Introduction to AI-assisted coding

Learn how to efficiently and safely use AI-assisted coding tools

Both beginners and experienced developers increasingly make use of generative AI to help in generating data analysis scripts and developing applications.

In this session, you will learn about:

Some knowledge about programming can be useful but is not essential.

Definitions

Although they vary slightly in how they are used, we use expressions “AI-assisted coding” and “vibe coding” to describe the practice of using generative AI (genAI) tools to help in writing code with a programming language. “Vibe coding” often has a more negative connotation, as it implies that large amounts of code are automatically generated, with less scrutiny over the code’s validity.

The tools themselves are often called “AI assistans” or “coding companions”.

Beyond initial code generation, these tools can help with debugging, designing tests, refactoring, documenting and other common tasks in software project management. Increasingly, such AI features are woven into existing Integrated Development Environments (IDEs).

When talking about AI-assisted coding, some terms are important to understand:

  • Large Language Model (LLM): a language model trained on very large amounts of data by using machine learning methods. What generates text and code in genAI tools.
  • AI agent (or “agentic AI”): autonomous entities that can operate independently to achieve complex tasks
  • Integrated Development Environment (IDE): an application to write code, with various features helpful for software development (debugging, version control, project management, command line tools…)
  • Application Programming Interface (API): what allows one program to access another program’s features. In the topic of AI-assisted coding, it could be the interface that allows code or an app to make use of a LLM, and might involve some kind on authentication (for example, to make use of a subscription-based product).

Common tools

While many generalist genAI tools can produce and analyse code, other tools are designed specifically for programming. Some popular ones are:

Some Open Source options:

  • Tabby: assistant integrates in IDEs, can be self-hosted
  • OpenCode (Anomaly): CLI, desktop app and IDE extension, with access to various models

Some tools are mainly a model and an API that can be integrated into an IDE (sometimes via extensions), others are fully integrated IDEs in which many tools useful to developers are bundled. Some can be installed on your computer, while others are cloud-based web applications. And they differ vastly in the features they provide (for example, access to a variety of models, project management tools, or agentic AI for autonomous tasks).

NoteWebsite generation with Claude

One powerful use of such tools is website generation. See for example this website showcasing some open research tools generated by Claude from one prompt. The tool can directly publish the website using the “Publish artefact” button.

  • Prompt: “Create a HTML page that showcases popular open source research software. Show tools in a grid, each one with the project’s logo, a short description and a link to the project’s website. Only showcase research software that does not rely on generative AI, as we want to promote reproducibility in science with deterministic tools. For example: QGIS, R, OpenRefine.”
  • Settings: claude.ai using Sonnet 4.6 (March 2026)
  • Published website: Open Source Research Software
  • Issues:
    • Wrong date
    • Wrong count of tools
    • Mismatched title
    • …more?

Potential issues with AI-assisted coding

Not all these issues are specific to AI-assisted coding. Many can also arise when writing your own code, or copying code from other sources like Q&A websites. But they can be compounded by the fact that generative AI tools present outputs in a very convincing way, and that they can produce very large amounts of code at once - making it less likely that the users will review the code.

Code is not valid

Sometimes, AI tools plainly generate code that does not run. Here are two real-world examples.

NoteGemini’s vanished variable

In this example, Gemini uses a variable that does not yet exist, meaning the code fails to run.

  • Prompt: “Give me an example block of code that generates a network visualisation using the R programming language.”
  • Settings: Gemini “legacy” model, prompted in 2025
Show the code
# Install and load necessary packages
# install.packages("igraph")
# install.packages("ggraph")
# install.packages("ggplot2")
library(igraph)
library(ggraph)
library(ggplot2)

# --- 1. Create a sample network object ---
# This is a random graph with 20 vertices and 30 edges.
# The 'barabasi.game' function generates a scale-free graph.
set.seed(42) # For reproducibility
g <- barabasi.game(20, m = 2, directed = FALSE)

# Add some vertex attributes (e.g., group)
V(g)$group <- sample(c("A", "B", "C"), vcount(g), replace = TRUE)
V(g)$size <- degree(g) + 5 # Vertex size based on degree

# Add some edge attributes (e.g., weight)
E(g)$weight <- runif(ecount(g), 1, 10)

# --- 2. Generate the network visualization ---
# Use ggraph for a ggplot2-based plotting
ggraph(g, layout = 'kk') + # 'kk' is a popular force-directed layout
    geom_edge_link(aes(alpha = weight), # Edge transparency based on weight
                    arrow = arrow(length = unit(4, 'mm')),
                    end_cap = circle(3, 'mm')) +
    geom_node_point(aes(color = group, size = size)) + # Node color by group, size by degree
1    geom_node_text(aes(label = name), repel = TRUE) + # Add node labels
    theme_graph() + # A clean theme for network plots
    labs(title = "Example Network Visualization",
        subtitle = "Generated using igraph and ggraph")
1
In this line, the variable name is given to the label argument. However, name was not defined earlier, so the code fails to run.
NoteJan’s function fudge-up

In another example using the same prompt, Jan gets a function name wrong, then “lies” about why it did:

  • Prompt: “Give me an example block of code that generates a network visualisation using the R programming language.”
  • Settings: Jan-v1-4B-Q4_K_M model in Jan desktop app, default settings, September 2025.
Show the code
# Install required package first (if needed)
# install.packages("igraph")

library(igraph)

# Create a simple undirected graph (triangle)
1g <- graph.from.data.frame(
    data.frame(
    from = c("A", "B", "C"),
    to = c("B", "C", "A")
    ),
    directed = FALSE
)

# Plot the network
plot(g, vertex.label.cex = 0.8, edge.width = 1.5, main = "Simple Triangle Graph")
1
This line uses the function graph.from.data.frame() (in line 7), which does not exist. The code fails to run.

When asked about it, the model repeatedly gives erroneous information (e.g. “it used to have this name in previous versions”) that can be disproven every time.

WarningTrained to be convincing

Remember that generative AI tools are designed to be convincing in how they present information. Always try to cross-reference the facts it gives you. Even when it links to a “source”, you might find that the source was not interpreted or summarised correctly, or that the link is dead.

Output is correct, but process is wrong

To reduce this issue to a very small example, imagine a user prompting to generate code that will give the answer “2” when given the input “1 + 1”. Code that ignores the input entirely while always giving the answer “2” would fit the bill. But the user was likely hoping for a calculator that would correctly give an answer to any addition.

This simple scenario would be easy to notice, but with more complex prompts, there is a significant chance that the real objective is misinterpreted, and that the AI-generated code focuses on the result rather than the process that leads to such a result. And if large amounts of code are generated at once, the user is less likely to notice the issue.

Unnecessary or inefficient code

Here’s a lived example: a student prompted for some Python code to generate a visualisation of a categorical variable. The resulting code included a custom colour scale for a plot, using random colours, even though the visualisation module already has default colour scales that are better designed. In this case, shorter code would have generated a less confusing, more accessible result.

It is also possible that code gets duplicated in different places of the project, instead of reffering to the same bit of code. For example, we might prompt the AI tool several times to generate code that needs a summary of a dataset. If the tool is not sophisticated enough to “remember” that such a summary was already generated elsewhere, it will not only make the project more complex by re-writing an equivalent bit of code, but also make the program slower by executing a task that might have already run before.

Inserting a vulnerability

A 2021 paper found that 40% of programs generated by GitHub Copilot included vulnerabilities.(Pearce et al. 2021) Models do improve over the years, but they are likely to have been trained on large amounts of buggy and vulnerable code. Without proper review and testing, AI-generated code can perpetuate the same issues.

Slopsquatting

Generative AI produces outputs in a probabilistic manner, which means generated code can include erroneous package names:

  • names that are often spelt wrong in the training data
  • names that are plausible, or entirely made up
  • names coming from other languages, or names used in the wrong context

“Slopsquatting” is the development of malicious libraries by exploiting such AI-generated typos. This is the AI version of “typosquatting”: exploiting the common errors humans make when typing the name of a library by uploading a malicious library to common repositories, using the erroneous name.

Researchers found in 2025 that, from code generated by 12 models, 19.7% of library names generated were “hallucinated”: more than 200,000 unique, fake package names that could be used for slopsquatting.(Spracklen et al. 2025)

Making maintenance more difficult

It is often reported that using AI assistants in software development speeds up code generation but complicates maintenance further down the line. Understanding a codebase will make it easier to document, navigate and build upon. It will also make it easier to detect, understand and fix issues.

Reduced accessibility of the user interface

WebAccessBench (2026) reports that more than 89% of AI-generated user interfaces (UIs) “include detectable barriers” to accessibility. Many generative AI tools do not have default instructions to make generated UIs accessible by default, by for example assigning labels to buttons, asking the user to add alternative text to images, and testing if the interface is navigable with a keyboard.

Becoming over-reliant

Like any generative AI tool, it’s possible to become over-reliant on coding assistants. This can errode critical thinking and make the user miss out on learning opportunities.

Writing better code

Many of these issues can be mitigated to some extent with some recommendations and best practices. What strategies can we use to improve the code we write with the help of AI tools?

Prompting strategies

Prompting a generative AI tool effectively commonly involves:

  • Being clear and to the point
  • Assigning a role to the tool
  • Describing the task
  • Giving relevant context
  • Clarify what is expected regarding the output’s formatting, style, verbosity…
  • Iterating by modifying the prompt and learning about what works with the model

If you want to learn more about prompting strategies that are not specific to programming, the UQ Library offers a “Mastering Prompting Engineering” course. Search for AI-related courses on the website.

For AI-assisted coding, here are some more strategies that can help:

  • Specify a list of specifications relevant for the whole project, so you don’t have to repeat yourself with every prompt. This can be seen as context to and requirements for your project that should always be relevant and taken in consideration, as opposed to a prompt’s isolated instructions that generate a specific block of code. You can regularly go back to this “project context” and tweak it as you notice recurring issues in the code generated. Such context and requirements could include:
    • the overall objective of the project;
    • programming language used;
    • formatting rules to use;
    • amount of comments to use; which kind of user or audience the project targets;
    • which hardware (processor architecture) and operating system the software needs to run on;
    • security requirements; what balance between dependencies and own code we want to strike;
    • prioritisation of accessibility in UI by always checking generated UI elements (or more precise set of rules).
  • Break down tasks into smaller chunks, similarly to the “decomposed prompting” strategy.(Khot et al. 2023) This allows for more precise instructions, more control over the output, more learning opportunities, easier review. (However, there needs to make sure the tool is not missing useful context.)
  • Ask for several options to resolve one issue or implement one feature, with reasons why one could be preferred over the other.
  • Use different models to compare outputs or compete against each other
    • For example, ask one tool to generate code, and ask another tool to check its validity, look for potential bugs, and recommend changes.
  • When prompting to fix a bug or add a feature, ask for an accompanying unit test that verifies that the bug does not re-occur, or that the feature still works as expected.
NoteAI against AI

The earlier Claude-generated website’s source code can be fed to a different model to check for issues to fix.

  • Prompt: “Can you spot any issues with this webpage? Any issue in the code? Is there some plagiarism (i.e. copy-paste that wasn’t acknowledged)? What about accessibility?” (with HTML file attached)
  • Settings: Gemini 3 model using “Fast” setting (March 2026)

Some of the issues Gemini spotted:

  • Mismatch in number of tools
  • Missing alt text
  • “Significant hurdles for users with screen readers or motor impairments”
  • Poor CSS card animation design

The CSS issue is an example of repeated code that is not robust against future changes: using hard-coded delays for a limited number of items.

Show the code
    @keyframes fadeUp {
      from { opacity: 0; transform: translateY(18px); }
      to   { opacity: 1; transform: translateY(0); }
    }

    .card:nth-child(1)  { animation-delay: 0.04s; }
    .card:nth-child(2)  { animation-delay: 0.08s; }
    .card:nth-child(3)  { animation-delay: 0.12s; }
    .card:nth-child(4)  { animation-delay: 0.16s; }
    .card:nth-child(5)  { animation-delay: 0.20s; }
    .card:nth-child(6)  { animation-delay: 0.24s; }
    .card:nth-child(7)  { animation-delay: 0.28s; }
    .card:nth-child(8)  { animation-delay: 0.32s; }
    .card:nth-child(9)  { animation-delay: 0.36s; }
    .card:nth-child(10) { animation-delay: 0.40s; }

However, letting Gemini apply its recommended changes can create new issues (e.g. removing an aestheticaly pleasing logo fallback by “cleaning the HTML”).

Use reputable, purpose-built tools

Tools that were specifically designed for AI-assisted coding are usually more likely to perform better at generating code that works, is more efficient, and is safer. They might also have wider context to take into account a larger part of your project, and therefore reduce code duplication by reusing what already exists.

However, the ecosystem of generative AI tools moves very rapidly. Start-ups and products come and go, and there is a strong incentive to get products out very fast, sometimes with limited testing but convincing marketing. Pay attention to how long a tool has been around for, what reviews say, its reputation, if it is currently maintained, and who has created it.

You can search for software on AlternativeTo.net to get an idea of what is available, and how popular the alternatives are.

Use version control

Using version control (Git being the most popular tool currently) helps keeping track of what has changed in a project. You decide when to take a “snapshot” and give a short description of what the changes were, so you can record a clean history, roll back to previous working versions, and precisely identify what change introduced a bug.

Integrate accessibility checks

Web accessibility standard can be overwhelming, and it is difficult to remember all the ways UIs can become a barrier to users. There are options to automate the accessibility check of what you create, for example by integrating axe-core, an open source accessibility testing engine with very helpful documentation on how to fix each issue it detects.

Review the code

Don’t trust that the tool will always do the right thing. Generate code in smaller bits that you can review yourself, and when it is difficult to review, use the opportunity to learn more about the language by asking questions about the programming language, the choice of syntax, and the logic behind the code. Don’t hesitate to cross-reference the information given with reputable sources, like the official documentation of the programming language.

Making it maintainable

When generating code from prompts, make sure you consider the maintenance aspect of the project:

  • Understanding the code will make it easier to fix issues when they arise.
  • Try to keep track of what logic has already been implemented so the AI tool does not duplicate it.
  • Will the codebase need to be maintained in the future? Over which period of time? If such maintenance and development entirely relies on one proprietary tool, what happens if that tool is not available anymore, or too expensive?
  • Keep an eye on the dependencies of your code. If the AI-generated code makes use of many external libraries, it will likely increase the maintenance burden (which could be because of new versions, availability or lack of maintenance).
  • Are there tests in place to verify that the code still works as expected?

Testing your code

Tools can generate large amounts of code, but how do we know it does the right thing? Generative AI can create programs that generate the output you expect, but it might have done so in the way you were hoping for.

Some AI tools can use agents to test code, as part of Continuous Integration, like Continue.

Throughout the development process, it is importing to regularly test your code to check that it does the right thing, but also design automated tests that are run at least before a new version is released (and ideally, every time a change is made, with Continuous Integration).

Acknowledging and referencing

It is important to be transparent and acknowledge your use of AI-assisted coding. This might be a requirement coming from your course, the specific assessment your are completing, or your employer - if AI use is not outright disallowed. Not following such requirements may be considered academic misconduct. But even if it isn’t a requirement, acknowledging and referencing such practices helps by:

  • increasing traceability when issues arise (for example, identifying which model generated buggy code)
  • letting others learn from the methods you used
  • documenting successful processes that you might appreciate reusing in the future
  • comparing results when working on a different project with a different set of tools
TipResponsibility

Note that, as the person who used the tools, you are likely entirely responsible for the issues in your code. Most AI-assisted coding tools warn you about potentially erroneous outputs (and tell you that the user is responsible for checking the output’s validity), and often make you sign a user agreement that specifies that developers and/or the company that created the AI assistant will not be found legally responsible for negative impacts from code generated by their tools.

For help with referencing AI tools, refer to the UQ Library’s Guide to acknowledging and referencing AI.

Resources

At UQ, we have hubs, guides and books to help you make use of generative AI tools in a safe, responsible and ethical way:

Here are more resources about AI-assisted coding:

References

Khot, Tushar, Harsh Trivedi, Matthew Finlayson, Yao Fu, Kyle Richardson, Peter Clark, and Ashish Sabharwal. 2023. “Decomposed Prompting: A Modular Approach for Solving Complex Tasks.” https://arxiv.org/abs/2210.02406.
Pearce, Hammond, Baleegh Ahmad, Benjamin Tan, Brendan Dolan-Gavitt, and Ramesh Karri. 2021. “Asleep at the Keyboard? Assessing the Security of GitHub Copilot’s Code Contributions.” https://arxiv.org/abs/2108.09293.
Spracklen, Joseph, Raveen Wijewickrama, A H M Nazmus Sakib, Anindya Maiti, Bimal Viswanath, and Murtuza Jadliwala. 2025. “We Have a Package for You! A Comprehensive Analysis of Package Hallucinations by Code Generating LLMs.” https://doi.org/10.48550/arXiv.2406.10279.