How to understand an agentic AI codebase quickly
Find the loop first, then the tools, the memory, the prompts and the guardrails, in that order. One short example below shows all five in a dozen lines.
Building an agentic AI application often starts with reading someone else's. These codebases look unfamiliar because the most important control flow is partly decided by a model at run time, but the parts that matter sit in a handful of predictable places.
Start with the agent loop
Every agentic application has a loop. It gives a model a goal and some context, lets the model choose an action or a tool, runs it, and feeds the result back. Find where that loop lives and you have the spine of the system.
It can take three shapes. A plain while or for loop around a model call is the simplest. A graph or state machine, as in LangGraph, spreads the loop across named nodes and edges. A framework's agent class hides the loop inside a library call, and then you read the configuration passed to it instead. Whichever shape you find, look for two things: what stops the loop, and what happens when a step fails.
Then the tools
Tools are the functions the model may call: search, code execution, databases, other APIs. Read how they are declared, what inputs they accept and what checks run before they execute. Sort them into two piles, tools that only read and tools that change something. The second pile is where most of the security risk lives, and each tool in it deserves a sentence in your notes on who may trigger it and what limits it.
Tools are only one part of what surrounds the model, and we wrote separately about the harness of tools, permissions and state around a model.
Then memory and context
Look for how conversation history, documents and intermediate results are stored and retrieved: a list of messages, a vector store, a database or a checkpointer. Then find where that memory is trimmed or summarised before each model call. How context is trimmed decides both cost and quality, and it is often the least documented part of the code.
Then prompts and guardrails
Prompts are often spread across files, in templates, constants and inline strings. Collect them in one place in your notes. Then find the guardrails: input validation, checks on the model's output, step and spending limits, and the points where a person must approve. A guardrail you cannot find in code does not exist, whatever the README says.
Then evaluation
Mature agentic systems measure themselves with test sets, scoring and regression gates that stop a release when a number drops. If you find none, that is the first thing to add, and the eval gate article shows one way.
A worked example: reading a small agent
Here is a minimal support agent, written the way many first versions are:
TOOLS = {"search_orders": search_orders, "refund": refund}
def run(goal, max_steps=8):
messages = [system_prompt(), {"role": "user", "content": goal}]
for step in range(max_steps):
reply = call_model(messages, tools=list(TOOLS))
if reply.tool is None:
return reply.text
if reply.tool == "refund" and reply.args["amount"] > 100:
return ask_a_person(reply)
result = TOOLS[reply.tool](**reply.args)
messages.append(tool_result(reply.tool, result))
raise StepLimit(goal)
Read it with the five questions:
- Loop. The
forloop is the spine. It stops when the model answers without a tool, or aftermax_steps, which raises an error instead of running forever. - Tools.
search_ordersonly reads.refundchanges something and moves money, so it goes in the second pile. - Memory.
messagesgrows by one entry per step and is never trimmed. With eight steps that is fine. With fifty it would be a cost problem. - Prompts. Everything the model is told lives in
system_prompt(), which is the next function to open. - Guardrails. Refunds over 100 go to a person. Nothing checks the arguments of
search_orders, and nothing checks the final text before it reaches the customer. Those are the two gaps to write down.
There is no evaluation here at all. In a dozen lines you have the spine, the risky tool, a cost question and two missing checks, which is the shape of what you would report after a day in a much larger codebase.
The same questions on a larger system
In a production system each answer sits in its own module, but the questions do not change. Nehemvix, for example, is a fixed LangGraph graph rather than a model-driven loop: code decides the order of its stages, from ingest and estimate through map, reduce and write to evaluate and publish. Its tools, such as fetching a commit or removing secrets, run as code through one wrapper that records every call. Its memory is a checkpoint after every step plus a record of each finished unit of paid work, and its main guardrail is an interrupt() that stops the graph until a person approves the cost. Agentic AI examples takes it apart in more detail.
A checklist
- Find the loop, and what stops it.
- List the tools, split into reading and changing.
- Find where memory is stored and where it is trimmed.
- Collect every prompt in one place.
- List the guardrails you can point to in code, and the gaps.
- Find the evaluation, or note that there is none.
- Write it down with a file and line for each claim.
Let Nehemvix do the first pass
Nehemvix reads the whole repository and writes a guide with the architecture, data flow, modules and a glossary, citing the exact lines of code, so you can verify each claim and spend your reading time where it matters. It does not run the agent, so behaviour that depends on the model's choices at run time still needs your reading. See how it works and how every guide is checked.
Related reading: How to document a LangGraph project, How to understand a new codebase and MCP vs A2A.
Learning this to build your own agent? AELSHA™ can help you design it.