- Step 13 of 17 in the agent-building course
Choose an Agent Starter: Inspect Three Repositories and Test One

A starter repository only saves you time if it gives you the piece you're actually missing.
That sounds obvious, but it's easy to get wrong. A chat window isn't an agent backend. A loop that calls tools isn't an app with logins. And a full-stack demo can have you setting up a database, file storage and a model provider account before you've even decided what the agent should do.
This lesson compares three official repositories built for different jobs. Then you'll check one of them at a fixed version: run its unit tests, and run a small script that pokes at how it routes, when it stops, and how it reads settings.
That script swaps in a fake model. Nothing here was deployed, and there are no live model answers or search results.
Choose the layer you are missing
These repositories were checked on September 17, 2026. GitHub didn't mark any of them as archived. The dates in the table are when the checked version was committed. They don't tell you how fast anyone answers issues, or whether the code is ready for production.
| Repository | What you receive | Inspected revision date | Main setup obligations |
|---|---|---|---|
| LangGraph ReAct Agent | Python graph with a model/tool loop and a Tavily search example | August 28, 2026 | Python environment; model and search credentials for a live run |
| Agent Chat UI | Next.js interface for a LangGraph server with a messages state key | September 14, 2026 | Node/pnpm plus an existing compatible backend; production authentication design |
| Vercel Chatbot | Full-stack Next.js/AI SDK chat application with history, authentication and file storage integrations | July 8, 2026 | Provider or gateway access, database, storage and application environment variables |
The first two use the MIT license. Vercel's license file says Apache License 2.0. GitHub's metadata showed NOASSERTION for it, which is why the file itself was checked. Read the actual license and the terms of the packages it depends on. A badge isn't the whole answer.
Here's how they line up for this course's Python ticket task:
- ReAct Agent is the smallest backend of the three that fits. Start here.
- Agent Chat UI is a front end. It's useful once you have that backend.
- Vercel Chatbot is for when the product itself is a web chat app, and you need its extra services.
The repository directory has a wider list to choose from.
Pin the ReAct template before evaluating it
"Pinning" means checking out one exact commit, so what you test is what you read. The version checked here is 9bbd82d84905acc37f527b1f372dae841016f3b4.
Its pyproject.toml needs Python 3.11 or newer, but below 4.0. These checks used Python 3.12.14. Install uv if you don't have it, then clone into a folder you can throw away:
git clone https://github.com/langchain-ai/react-agent.git
cd react-agent
git checkout 9bbd82d84905acc37f527b1f372dae841016f3b4
uv sync --frozen --python 3.12
uv run --frozen pytest tests/unit_tests -q
The --frozen flag tells uv to install exactly what the repository's lockfile lists. You need internet access to install, but these unit tests don't need any API keys. The result was 3 passed.
Be clear about what those three tests prove. They check which model setting wins when several are set. They don't check how a live agent behaves.
Don't fill in .env just to do this inspection. A real run of the template calls a model provider and the Tavily search service. Paying for those APIs is separate from any chat or coding-assistant subscription you have. Nothing below needs a live call.
Trace the actual source paths
At the pinned version, open these files in this order:
| File | What to verify |
|---|---|
langgraph.json | Graph ID agent points to src/react_agent/graph.py:graph |
context.py | System prompt, provider/model string, search limit and environment overrides |
graph.py | Model call, route_model_output router, tools/completion edges and last-step behavior |
tools.py | The search tool constructs a Tavily client when invoked |
state.py | Message accumulation and the managed last-step flag |
Here's the loop once you've read them. Everything starts at call_model. If the model's answer asks for a tool, the graph goes to the tools step, then back to the model. If the answer doesn't ask for a tool, the run ends.
There's one safety catch. If the model asks for a tool on the very last step it's allowed, it gets a message saying it has to stop, and the tool request is dropped.
That's a good loop to build on. But notice what's not there: no record of who approved a ticket change, no rule about who owns what, no check that the ticket hasn't changed since the agent read it.
There's also no explicit checkpointer in this file, meaning nothing here saves the run's progress. A hosted service might add its own saving. Reading this code alone won't tell you what survives if a deployed worker restarts.
Run the credential-free probe
Download and unzip the starter inspection probe somewhere outside the cloned repository. Then, from inside the clone, run it with the clone's Python environment. Swap in the real path to the script:
uv run --frozen python /path/to/inspect_react_starter.py --checkout .
The script first checks that you're on the right commit, before it loads any of the starter's code. Then it swaps the model loader for a fake model and clears any provider or tracing settings your shell might pass along.
It doesn't run the full graph, load a real model, or call the Tavily tool.
It reports six things:
| Case | Observed result |
|---|---|
| Assistant answer without tool calls | Routes to __end__ |
| Assistant result with a tool call | Routes to tools |
| Human message passed to the output router | Rejected with ValueError |
| Ordinary node step with a requested tool | Returns one tool call |
| Last node step with a requested tool | Returns no tool calls |
MAX_SEARCH_RESULTS=7 environment override | Context stores the string "7", not the integer 7 |
The last row is worth a closer look. You set MAX_SEARCH_RESULTS=7 in the environment, and the settings object stores it as the text "7", not the number 7. The code says it should be a number, but nothing enforces that.
That doesn't mean Tavily will break. The search client might convert it. The point is that you can't count on the settings object to check types for you. If your app relies on a number staying within limits, convert and check it where it comes in, and write a test that feeds it a bad value.
The README also disagrees with itself about the default model. At this version, the code defaults to anthropic/claude-sonnet-4-5-20250929, while another section of the README still mentions Claude 3 Sonnet. That's just what the source says. It's not advice to use either one today. Pick a model that's currently supported before you do a live run.
Inspect the two web starters differently
The Agent Chat UI README at the inspected revision says to run pnpm install and pnpm dev, then enter your deployment URL and assistant or graph ID. Those commands start the interface. They don't give you an agent behind it.
The production advice in that README matters too. The UI can pass requests through to LangSmith using a key kept on the server. But hiding the key that way doesn't check who's sending the requests. Anyone who can reach the proxy can use it. Follow the repository's custom sign-in guidance before you put it online.
This lesson didn't deploy or test that production setup. And no one's API key was typed into the public demo.
The Vercel Chatbot README at its inspected revision covers environment setup, pnpm install, a database migration, and pnpm dev. It comes wired to Auth.js for logins, Neon Postgres for the database, and Vercel Blob for files, with AI Gateway for model access.
Each of those is a feature and also something you'll have to run. Weigh them together. For this comparison, only the README and license were read. No services were set up and no migrations were run.
Make the adoption decision concrete
For the ticket course, the backend template's value is that you can see its whole graph, and the model plugs in at one clear spot.
The work it leaves you is just as clear:
- Replace the web-search tool with a ticket tool that can only touch what it should.
- Check every input.
- Keep the approval lifecycle.
- Run the evaluation cases before you connect anything live.
Now try making it fail. In a throwaway copy of the probe, change the expected commit to a different string. It should refuse to run before it loads the graph.
Then go back to the "7" result and write down the exact check your app needs for that setting. Keep these notes in a short record of the decision, next to the commit, the setup command, and the test output.
An inspection like this should end with a decision you can back up and a list of the work left. "It installed" is only the first thing you learned.
Next, try the Copilot coding exercise, where you review a small change written by an AI assistant against behavior you already know. The course index has the full sequence.



