Project 4: AI Coding Agent
AI coding agents are, as the meme above puts it, suddenly everywhere. In Project 3 (docchat) you built the start of one: a program that loads your files into a conversation and answers questions about them. Every tool it has so far only reads your computer: cat dumps a file, grep searches for text, ls lists a directory. The model can read your code and tell you what is broken, but it cannot change a single character.
This project adds the tools that write: creating files, editing them, deleting them, and committing each change to git. Once docchat can do that, it stops being a program you chat with and becomes an autonomous agent that edits your project for you. It is the same jump that separates a chatbot from a coding agent like Claude Code or Cursor, and you are building a small version of exactly that.
Due: Wednesday, December 2, see the schedule.
Learning objectives
- extend smaller projects into larger projects
- understand how AI agents work
Instructions
Your project must meet every specification from Project 3 (docchat). If you missed any points there, fix the issue now, or you will lose those points again on this project.
Create a new branch in your repository and do all of your work in it. You may not touch the
main/masterbranch you submitted for docchat.Coding tasks.
When your program starts, it should run two checks:
Look for a
.gitfolder in the current directory. If it is not present, print an error and stop.Look for an
AGENTS.mdfile in the current directory. If it is present, load it into the conversation using yourcattool.Note:
AGENTS.mdis a standard file that AI agents load when they start working in a repo. Think of it as a README written for the agent instead of for a person: it lists project-specific instructions the agent should follow. You can find details and examples at https://agents.md/.
Then add the following four tools.
doctestsIt takes a single argument,
path.It runs the doctests in
pathwith the--verboseflag and returns the output.Note: Explicit confirmation that the test cases are passing is helpful for the LLM, which is why we ask for
--verboseoutput here rather than a silent success.Note: We have not covered how to run doctests from inside a Python program. There are several ways to do it, and any one you choose is fine.
write_fileIt takes three arguments:
path,contents, andcommit_message.It opens
pathand writescontentsto it. The output file must be UTF-8 encoded.Then it uses the
gitlibrary in Python to run the equivalent of:$ git add <path> $ git commit -m "[docchat] <commit_message>"Note: It is standard practice to have an agent commit every change it makes to disk with git. That way, when your agent “goes Skynet” on you, it is easy to travel back in time and undo its work. (AI researchers really do reach for Terminator memes when they talk about this.)
If the file is a Python file, run your
docteststool on it and return the output.
write_filesIt takes two arguments:
filesandcommit_message.filesis a list of dictionaries, each with apathkey and acontentskey. Write each one the same waywrite_filedoes.After writing all of the files, add and commit them together.
Note: We recommend writing the “real” code once, in
write_files, and makingwrite_filea thin wrapper that calls it with a one-element list. Less code is better than more code: it is easier to write, easier to test, and easier to change later. This is the DRY principle, short for Don’t Repeat Yourself.
Note: So why keep
write_fileat all if it is just a wrapper? Because LLMs, like people, use a specific tool more reliably than a general one. Just having the specificwrite_filein the toolbox helps the model work out when and how to reach for the generalwrite_files.
rmIt takes a single argument,
path.It deletes the path using Python’s
os.removefunction.It supports multiple files at once using globs.
It creates a commit with the file removed, using the commit message
[docchat] rm <path>.Warning:
rmis dangerous when it is implemented incorrectly. Two cautionary tales:- Meta’s director of AI alignment research, Summer Yue, had Claude accidentally delete her inbox through a bad combination of the
rmandcompactcommands: https://www.pcmag.com/news/meta-security-researchers-openclaw-ai-agent-accidentally-deleted-her-emails. - Toy Story 2 was almost lost forever to a bad
rmcommand combined with a glob: https://thenextweb.com/news/how-pixars-toy-story-2-was-deleted-twice-once-by-technology-and-again-for-its-own-good.
- Meta’s director of AI alignment research, Summer Yue, had Claude accidentally delete her inbox through a bad combination of the
Warning: Every one of these tools must validate its
pathbefore running, exactly like your read tools did: it must not run on absolute paths or on paths containing... When your read tools had this bug, the worst case was leaking a file to the model. These tools have write permission, so the worst case is now a rogue agent deleting everything on your computer. Get the check right.Repository organization.
Add examples to your README that show the agent in action: creating, modifying, and deleting files, and making git commits along the way. Use shell commands like
ls,cat, andgitto show the before and after, and format the prompts clearly.One possible example is the session below, which shows that
docchatcan create a file when asked, and that the new file is added to the git repo automatically:$ git checkout -b agent-work Switched to a new branch 'agent-work' $ ls -a .git AGENTS.md README.md $ git log --oneline c21103f (HEAD -> agent-work, master) init commit $ docchat chat> Create python code that implements the project in README.md Created the file hello_world.py chat> ^C $ ls -a .git AGENTS.md README.md hello_world.py $ git log --oneline 3cfb0a6 (HEAD -> agent-work) [docchat] create basic hello world python project c21103f (master) init commit
Grading rubric
This project is worth 16 points.
You may still complete any of the extra credit from previous projects, though extra credit you have already earned will not be counted twice. There are also new extra credits below, specific to this project.
Extra credit
-
Warning: Recall that a PyPI package can contain arbitrary code. Any agent that can install packages can therefore choose, on purpose or by accident, to destroy your computer. For example, the popular
LiteLLMpackage suffered a recent supply-chain attack:- https://docs.litellm.ai/blog/security-hardening-april-2026
- https://www.trendmicro.com/en_us/research/26/c/inside-litellm-supply-chain-compromise.html
- https://console.groq.com/docs/litellm
Open question: how would you prove that a piece of code is “safe”?
-
Note: Anthropic recently renamed their Ralph Wiggum implementation to just “Ralph” for copyright reasons. You can follow along in their GitHub repo: https://github.com/anthropics/claude-plugins-official/commit/44328beed48874d8e00da6c4ca5daaa5f0f3183c.
-
Hint: The Llama models on the free Groq API are not great at this task: the Llama models are old, and the free Groq tier has severe token limits. It is much easier with a state-of-the-art (SOTA) model like OpenAI’s latest GPT or Anthropic’s latest Opus. An OpenRouter API key lets you experiment across models. Finishing this task with the newest, most expensive model should cost less than $0.10, but put about $10 of credit on the account so you have room to play around.
-
Even SOTA LLMs are bad at generating correct diffs, mostly because a diff needs line numbers and LLMs are bad at counting which line a piece of code is on. (We can more or less prove that counting will always be hard for them.) The practical consequence is that you cannot use the standard
diff/patchtools to apply the model’s output. There are many workarounds, and you are welcome to use whatever you can get to work. We recommend wiggle, a tool built for applying exactly these “broken” LLM-generated diffs.Why bother with updates instead of rewrites? For a large file, rewriting the whole thing on every edit wastes a lot of tokens, which makes the agent more expensive to run. Worse, LLMs often make small typos, like dropping a
)that should match a(, and those typos make the code look correct while behaving very wrongly.
Submission
Submit a link to the new branch of your GitHub repo on Gradescope.
Along with the link, submit a one-to-two-sentence explanation of what you believe your grade should be. In particular:
- If you completed any extra credit, say so.
- If any part of your project does not work, say so, I may grade more leniently when you are upfront about it.
- If you are requesting points back from a previous project, you must say so explicitly.