Lessons
1 · Understanding Modern AI
2 · Talking to AI Effectively
3 · AI for Learning
4 · AI for Work and Productivity
5 · AI for Developers
- 17AI Coding Assistants: Modes, Strengths and Your Responsibility
- 18Use AI to Understand Code, Codebases, APIs and Documentation
- 19How to Use AI to Debug Code Safely
- 20Testing, Reviewing and Refactoring AI-Generated Code
- 21Security and Licensing Risks of AI-Generated Code
- 22Vibe Coding vs Responsible AI-Assisted Building
6 · AI for Career Growth
7 · Research, Verification and Responsible AI
8 · Automation and AI Agents
Lesson 18 · AI for Developers
Use AI to Understand Code, Codebases, APIs and Documentation
Reading code is the safest and often most valuable use of an AI assistant: nothing changes until you decide it should. This article covers explaining unfamiliar code, mapping a codebase, learning an API or framework, writing documentation and brainstorming architecture, with the checks that catch confident mistakes.
For
Developers and students joining new projects or learning unfamiliar frameworks who want to use AI for comprehension, not only for generation.
Level
Before you start
Read AI Coding Assistants: Modes, Strengths and Your Responsibility (article 17). Basic Python reading ability for the examples.
On this page
Key takeaways
- Asking AI to explain code is lower risk than asking it to write code, because nothing changes. But explanations can be confidently wrong, so verify by running, tracing and reading the real source.
- To map a codebase, give the assistant real structure (file tree, README, key files) and ask for a reading order, then confirm by opening the files it names.
- When learning an API or framework, state the exact version, give it the official documentation as source material, and check that every method it mentions really exists.
- AI-drafted documentation must match what the code does. Review it like code, and keep it short and accurate.
- For architecture, use AI to list options, trade-offs and failure modes, and keep the decision, which depends on your constraints, with you and your team.
On your first day on a project, you are handed a repository with 400 files and a one-line README. In the old days you would spend a week opening files at random. Now you can ask an assistant to explain things. Used well, this compresses days into hours. Used carelessly, you build a mental model of the code from confident guesses and then change things on that basis.
The difference lies in how you ask and how you check.
What you will learn
#- How to get useful explanations of unfamiliar code, and verify them.
- How to map a codebase and trace a request through it.
- How to learn an API or framework without being misled by invented methods.
- How to draft documentation that stays accurate.
- How to use AI to explore architecture options without handing over the decision.
Why reading is a good first use
#A coding assistant that writes code changes your program. One that explains code changes your understanding. If its explanation is wrong, you can often find out cheaply, by running the code or reading the source. So comprehension tasks have a favourable balance: high value, easy checks, low blast radius.
They are not risk-free. A wrong mental model leads to wrong changes later. So the rule is: treat every explanation as a hypothesis, and test the important parts.
Explaining unfamiliar code
#Ask in layers
#Here is a function from a project I am joining. Explain it in three layers:1. What it does, in one sentence.2. How it works, step by step, using this example input: [example].3. What assumptions it makes, and where it could fail (empty input, large input, wrong types).Then list any parts you are unsure about, because they depend on code I have notshown you.[paste the code]The last line matters. Models do not naturally flag the edges of what they know, so ask for it.
A worked example
#Here is a small function. Suppose an assistant explains it, and you want to be sure the explanation is right.
# File: chunker.pydef chunk(items, size): result = [] for i in range(0, len(items), size): result.append(items[i:i + size]) return resultfor piece in chunk([1, 2, 3, 4, 5], 2): print(piece)print(chunk([], 3))try: chunk([1, 2, 3], 0)except ValueError as err: print("ValueError:", err)An assistant might say (illustrative): "This splits a list into chunks of the given size. The last chunk may be shorter. If size is 0, it returns an empty list." The first two sentences are right. The third is a plausible guess, and the program shows otherwise:
[1, 2][3, 4][5][]ValueError: range() arg 3 must not be zeroA size of 0 does not return an empty list. It raises an error. If you had relied on the explanation, you might have written calling code that expects an empty list and crashes in production when a configuration sets the size to zero.
The pattern: whenever an explanation makes a claim about behaviour, find a way to test it. Run the function with the edge case. Step through in a debugger. Add a print statement. Write a tiny test. Five minutes of checking beats an hour of working from a false belief.
Other useful questions
#- "What would break if I changed X?" Then check by searching the code for usages, since the assistant may not see all callers.
- "Why might the original author have written it this way?" Treat the answer as a theory, and check commit history and comments.
- "Which parts of this code are risky to modify?"
- "Rewrite the same logic in the simplest possible form so I can compare." This is a good way to test your own understanding. Do the two versions behave identically on the same inputs?
Mapping a codebase
#An assistant can only help with a repository as far as it sees it. Some tools index your whole repository and some see only open files, and the products differ and keep changing. GitHub's advice for Copilot is to supply relevant context, for example by keeping pertinent files open, selecting the code in question and being specific. In general:
- Give it real structure. Paste the directory tree (for example the output of a tree or list command), the README and the main configuration file.
- Ask for a reading order. "Given this structure, which five files should I read first to understand how a request is handled? Explain why for each."
- Open those files yourself. The assistant may name files that do not exist, or misjudge what they do.
- Ask for an overview, then correct it. "Here is my understanding after reading: [your summary]. What have I got wrong or missed?"
- Keep a one-page map in your own words as you learn: entry points, main modules, data flow, external services.
Trace a request path
#Here are routes.py, auth.py and models.py. Trace what happens when a clientsends POST /login with valid credentials. List each function that runs, in order,with the file name, and say what data is passed between them. If something happensin code I have not shown (a middleware, a decorator), say so rather than guessing.The final sentence is the key. Without it, a model fills missing parts with typical behaviour for the framework. Check the trace by adding a log line or using a debugger on a real request.
Learning an API or framework
#This is where invented details cause the most pain. A model may suggest a method that does not exist, that existed in an older version, or that belongs to a different library. The usual cause is a version mismatch or pattern from similar libraries.
A tiny demonstration of the failure and how fast a check catches it:
# File: no_such_method.pytitle = "Prompt Fundamentals"# A method name borrowed from other languages and libraries. It looks plausible.try: print(title.contains("Prompt"))except AttributeError as err: print("AttributeError:", err)# The check that actually exists in Python.print("Prompt" in title)AttributeError: 'str' object has no attribute 'contains'TrueMany languages have a contains method on strings, and Python does not. Running the code exposes the mistake instantly. With larger libraries, it will not always be that obvious, so build these habits:
- State the exact version. "Using pandas 2.x" or "React 18 with hooks", not just "pandas" or "React".
- Give it the official documentation as source material where practical. Paste the relevant page or section and say "use only the functions described here".
- Ask for a minimal example, not a full application. Small examples are easy to run.
- Verify every function and parameter in the official reference. If you cannot find it there, it probably does not exist in your version.
- Run it. A working example you ran beats a convincing one you read.
- Ask about alternatives and trade-offs, not only "how do I do X". "What are two ways to do X in this framework and when would I prefer each?"
- Beware of deprecated advice. Ask: "Is this approach current for version N? What does the documentation recommend now?" Then check the documentation, not the assistant's answer.
Documentation
#AI is useful for drafting documentation, because writing it is tedious and the code is right there. The risks are accuracy and noise.
- Docstrings and comments: ask for explanations of why, not restatements of what. "Increment i by one" is noise. "Skips the header row" is useful.
- READMEs: supply the actual commands, versions and folder structure, and ask for a draft. Then follow your own README on a clean machine to see whether it works.
- API documentation: generate from the code's signatures, then check that the described behaviour matches what the code does, including error cases.
- Changelogs and pull request descriptions: summarise your diff, then correct it. Check that it states why the change was made, because that is usually missing.
- Keep docs short and dated where they describe volatile things such as setup steps.
A documentation draft that does not match the code is worse than none, because readers trust it. Review it as carefully as code.
Architecture brainstorming
#Assistants can be a useful sounding board for design questions: they know many patterns and can enumerate trade-offs quickly. They do not know your team size, traffic, budget, skills or legacy constraints unless you tell them, and they do not carry the consequences.
Context: a small team of four building an internal expense app for about 300users. We know Python and PostgreSQL. We have no dedicated operations person.Question: should we build this as a monolith or split it into services?Please give: the main options, the trade-offs of each for our situation,the three risks you think matter most, and what would make you change yourrecommendation. Do not give a single answer; I will decide with my team.Then:
- Check the claims against reputable engineering sources, for anything specific such as performance numbers.
- Prototype the risky part before committing.
- Record the decision. A short architecture decision record (context, options, decision, consequences) helps your future self.
- Remember sycophancy. If you state your preference, it may argue for it. Ask for the strongest case against.
Common mistakes
#- Accepting an explanation without testing the edge case.
- Not giving the assistant the code it needs, so it guesses about the rest.
- Forgetting to name versions, and receiving advice for a different release.
- Trusting method names without checking the reference.
- Publishing AI-written documentation that nobody has run.
- Letting the assistant make architecture decisions it cannot own.
Exercises
#Exercise 1
Test the explanation
#An assistant says: "This function removes duplicates from a list while preserving order": def uniq(items): return list(set(items)). What is wrong, and how would you prove it?
Exercise 2: Ask better
#Write a prompt asking an assistant to explain a 30-line function you do not understand, using the three-layer approach and a request to list uncertainties.
Exercise 3: Check an API claim
#An assistant suggests df.group_by("city").mean() for a pandas DataFrame. You are not sure the method exists. What do you do before using it?
Exercise 4: Fix the documentation
#A README generated by an assistant says "Run npm start to launch the server" but your project uses npm run dev. Explain why this matters and how you would prevent the problem in future.
Show solutionHide solution
A set does not preserve order, so converting to a set and back can reorder the items. The claim "preserving order" is false. Prove it by running a quick test, for example with a short list of strings, and see whether the order matches the input. Because set ordering is not something you should rely on, the test might even pass by chance on one input and fail on another, so reason about it from the documentation as well: Python's documentation says sets are unordered collections. A correct order-preserving approach uses a dictionary (for instance list(dict.fromkeys(items)) in modern Python, where dictionaries keep insertion order). Check that in the documentation too.
Exercise 2
Show solutionHide solution
Here is a 30-line function from the project I am joining: [paste]. Explain it inthree layers: (1) what it does in one sentence, (2) how it works step by step usingthe example input [example], (3) the assumptions it makes and how it could failfor empty, very large or wrongly typed input. Then list anything you are unsureabout because it depends on code I have not shown. Do not guess about the restof the project.Afterwards, run the function on your example and on one edge case, and compare with what the assistant said.
Exercise 3
Show solutionHide solution
Check the official pandas documentation for the exact version you use. In pandas the method is spelled groupby (one word), not group_by, which resembles R's tidyverse and some other tools. Search the reference for the method name, and look at an example in the official docs. Then run the corrected code on a tiny DataFrame whose answer you can compute by hand.
The general rule: when a call looks plausible but unfamiliar, verify its existence and spelling in the official reference before running or relying on it.
Exercise 4
Show solutionHide solution
A wrong command in a README sends every new developer to a failed first step, wastes time and erodes trust in the rest of the document. It also shows the assistant guessed at a detail it could not know.
To prevent it: supply the actual commands (for example by pasting your package.json scripts) when asking for a draft, and follow the README yourself on a clean machine or a fresh clone. Keep setup steps short, and update them whenever the scripts change. Consider checking commands in CI where possible.
Where to go next
#- Next: How to Use AI to Debug Code Safely applies these habits to finding and fixing bugs.
- For a non-AI debugging foundation, read How to Debug Any Bug: A Calm, Repeatable Process.
- For testing what you learn, see Testing, Reviewing and Refactoring AI-Generated Code.
Sources & further reading
- Technology
- AI
- #AI
- #AI coding
- #context
- #developers
- #generative AI
- #learn to code
- #productivity
- #prompt engineering
- #responsible AI
Connected lessons
Linked from 3 guides
Other pages in the library that point here.
Keep reading
More in Technology →Guide · Technology
Writing Better AI Prompts: A Practical Guide
Guide · Technology
Using AI Tools at Work Without Getting Into Trouble
Course · Career
Off-Campus Placements With AI: From Zero to Offer

