Skip to content
CodeLifter
Search/ Browse prompts
CodeLifter Forum

How do you build a simple AI agent that can edit code?

Staff answerWritten by CodeLifter editors · MCP and tools1 replyupdated

Short answer

To build a simple AI agent that can edit code, give a model an editing tool through its provider's API, run every tool call it asks for in your own code, send the result back, and repeat until it stops asking. That loop plus one guarded file tool is the whole agent; most of the work is in the guards.

Written by CodeLifter editors · Staff, CodeLifter ·
CiteCodeLifter Forum, "How do you build a simple AI agent that can edit code?", https://codelifter.com/forum/posts/how-do-you-build-a-simple-ai-agent-that-can-edit-code/, accessed 2026-11-12.
  1. Staff, CodeLifter ·

    What is the smallest thing that counts as an agent?

    Anthropic's engineering post Building effective agents puts it in one line: agents "are typically just LLMs using tools based on environmental feedback in a loop." A tool here is a function your program offers the model, described by a name, a description and an input schema. The model never touches your disk. It returns a structured request; your code decides whether to run it. The AI agent thread explains how that differs from a chatbot.

    OpenAI's function calling guide describes the same loop in five steps: send the request with tools, receive a tool call, execute it in your application, send the output back, and receive a final answer "(or more tool calls)". Anthropic's API works the same way: a response with stop_reason: "tool_use" contains tool_use blocks, and you reply with tool_result blocks.

    Part Your job or the model's? In the example below
    Tool definition Yours Anthropic's built-in text editor schema
    Choosing a tool call The model's It asks to view, create or str_replace
    Running the call Yours run_tool()
    Guarding the call Yours safe(), the single-match check and the backup
    Stopping Both The model stops asking, or the 10-turn cap ends it

    Step by step: a file-editing agent in Python

    This follows Anthropic's text editor tool documentation, read on 16 October 2026, which defines a tool type text_editor_20250728 named str_replace_based_edit_tool with the commands view, create, str_replace and insert. CodeLifter has not run this code; treat it as a sketch to check against the current docs.

    1. Use Python 3.9 or later (the path check relies on Path.is_relative_to). Install the SDK with pip install anthropic and set ANTHROPIC_API_KEY in your shell, never in the file.
    2. Make a throwaway folder called demo with one broken file in it, and put it under git.
    3. Save this as agent.py next to it:
    import pathlib, shutil, anthropic
    
    ROOT = pathlib.Path("demo").resolve()
    TOOLS = [{"type": "text_editor_20250728", "name": "str_replace_based_edit_tool"}]
    client = anthropic.Anthropic()
    
    def safe(path):
        p = (ROOT / path).resolve()
        if not p.is_relative_to(ROOT):
            raise ValueError("path is outside the project folder")
        return p
    
    def run_tool(inp):
        p, cmd = safe(inp["path"]), inp["command"]
        if cmd == "view":
            return p.read_text() if p.is_file() else "\n".join(x.name for x in p.iterdir())
        if cmd == "create":
            p.write_text(inp["file_text"])
            return "Created"
        if cmd == "str_replace":
            text = p.read_text()
            n = text.count(inp["old_str"])
            if n != 1:
                raise ValueError(f"Found {n} matches; give more context for exactly one")
            shutil.copy(p, f"{p}.backup")
            p.write_text(text.replace(inp["old_str"], inp["new_str"]))
            return "Edited"
        raise ValueError(f"Command {cmd} is not supported here")
    
    messages = [{"role": "user", "content": "Fix the syntax error in primes.py"}]
    for turn in range(10):
        reply = client.messages.create(model="claude-opus-5-5", max_tokens=2048,
                                       tools=TOOLS, messages=messages)
        messages.append({"role": "assistant", "content": reply.content})
        if reply.stop_reason != "tool_use":
            break
        results = []
        for block in reply.content:
            if block.type == "tool_use":
                try:
                    out, err = run_tool(block.input), False
                except Exception as e:
                    out, err = f"Error: {e}", True
                results.append({"type": "tool_result", "tool_use_id": block.id,
                                "content": out, "is_error": err})
        messages.append({"role": "user", "content": results})
    
    1. Run python agent.py, then git diff to see exactly what changed.

    The model name is the one in the docs' own examples; swap in whichever current model you have access to.

    Why are the guards the important part?

    Every guard above comes from a vendor recommendation, not from taste:

    • Paths. The text editor page tells you to "Validate file paths to prevent directory traversal". safe() resolves the path and refuses anything outside demo. Anthropic's agents post adds that the model made mistakes with relative paths after moving out of the root, so its team "changed the tool to always require absolute filepaths".
    • Exactly one match. The docs show an error for a str_replace that matches several places: "Please provide more context to make a unique match." Returning that as an error lets the model try again instead of editing the wrong line.
    • Backups. The page says to "Create backups before making changes". Git does this better, which is why step 2 matters.
    • Errors go back to the model. Each failure is returned with "is_error": true, so the model reads it and adjusts.
    • A turn cap. The agents post mentions "stopping conditions (such as a maximum number of iterations) to maintain control". Without one, a confused loop keeps spending tokens.

    The same post warns that agents bring "higher costs, and the potential for compounding errors" and recommends "extensive testing in sandboxed environments". So run this in a container or a throwaway folder, never in your home directory.

    What would you add next?

    Human approval. Before run_tool writes anything, print the file name, old_str and new_str, and ask Apply? [y/N]. If the answer is no, return an error result saying the edit was refused, so the model knows to stop or try something else. That one prompt turns the loop from autonomous to supervised.

    A test tool. A run_tests tool is the usual next step: it gives the model what the agents post calls "ground truth" from the environment. Run it with a fixed command only, not arbitrary shell input. If you want the same tools in several apps, wrap them in an MCP server instead, as in the simple MCP server thread. The CodeLifter API providers page lists fourteen model APIs and which ones accept the OpenAI request format, useful if you port the loop, and the agents directory shows how finished coding agents handle the same problems.

    Short version

    • An agent is a model, some tools and a loop that runs the tool calls the model asks for.
    • You execute every call yourself, so you decide what is allowed.
    • Validate paths, require a single match for edits, keep backups and cap the turns.
    • Test in a throwaway folder under git and read git diff after each run.
    0
    ReplyLink

Plain text or simple Markdown. Links are nofollow. Your email is never shown.

  1. CodeLifter editorsStaffStaff, CodeLifter ·

    Do you need a framework like an agent SDK to build an AI agent? No, and for a first one it can hide what is happening. Anthropic's Building effective agents post recommends "finding the simplest solution possible, and only increasing complexity when needed", which "might mean not building agentic systems at all." The loop in this thread is about forty lines of plain Python. What a helper library saves you is the bookkeeping. Anthropic's tool runner page says the SDK helper "handles the agentic loop, error wrapping, and type safety", and lists it as beta in the Python, TypeScript, C# and Go SDKs. The same page names the trade-off: when you need "human-in-the-loop approval, custom logging, or conditional execution", it points you back to the manual loop. A file-editing agent is exactly the case where you may want to approve each write, so writing the loop yourself first is a reasonable choice. Once you understand it, a helper or a full agent SDK saves code without changing the shape.

CodeLifter

Reviewed vibe coding prompts, the JavaScript each one should produce, and sourced answers on AI-generated code: who wrote it, who owns it, and whether you can ship it. Free since 1999.

Browse the Prompt Shelf

Popular topics

© 1999 to 2026 CodeLifter

Independent. No ties to any software vendor.
Code MIT Text CC-BY-4.0 Back to top