--- title: "How AI Coding Agents Actually Work: From Prompt to Pull Request" author: "Samod Alex" published: "2026-10-30T12:05:24.316Z" updated: "2026-10-30T12:05:24.316Z" url: "https://zyvop.com/how-ai-coding-agents-actually-work-from-prompt-to-pull-request-z1w6b" canonical: "https://zyvop.com/how-ai-coding-agents-actually-work-from-prompt-to-pull-request-z1w6b" tags: ["LLM Agents","developer tools","AI Coding Agents","Software Engineering","code-review"] --- # How AI Coding Agents Actually Work: From Prompt to Pull Request From the first prompt to a reviewable pull request: the loop, tools, context, tests, and guardrails behind AI coding agents. ![Cover image]() You type something like "fix the bug where users get logged out after resetting their password." A few minutes later there is a branch, a handful of commits, a passing test suite, and a pull request waiting for review. It feels like magic, and it is tempting to assume the model simply "knows" your codebase and writes the fix in one shot. It does not. An AI coding agent is closer to a very fast junior engineer with a terminal than to an autocomplete box. It explores, forms a plan, makes changes, runs things, reads what went wrong, and tries again. Understanding that loop explains why these tools are so useful, and why they sometimes fail in strange ways. Let's walk through what actually happens between the prompt and the pull request. ## The core idea: a language model in a loop At the center is a large language model, but the model alone cannot read your files or run your tests. It only produces text. What turns it into an agent is a program wrapped around it, usually called the harness, which does three things: 1. Sends the conversation so far to the model, along with a list of tools the model is allowed to use. 2. Executes any tool the model asks for. 3. Feeds the result back to the model and repeats. In pseudocode, the whole thing fits in a few lines: ```python messages = [system_prompt, user_task] while True: reply = model(messages, tools=TOOLS) messages.append(reply) if not reply.tool_calls: break # the model thinks it is done for call in reply.tool_calls: result = harness.execute(call) # read, search, edit, run tests messages.append(result) ``` The loop ends when the model replies without requesting another tool, meaning it believes the task is finished or it needs to ask you something. Real harnesses also add limits, such as step and token budgets, so a confused agent cannot spin forever. Everything else in this post is a refinement of this loop. ## Tools: the agent's hands A tool is a function the harness exposes to the model, described by a name, a plain-language description, and a schema for its parameters. When the model wants to use one, it emits a structured request, such as `read_file` with `path=src/auth/session.ts`. The harness validates the request, runs it, and returns the output as text. A typical toolbox looks like this: - **Read and search:** read a file, list a directory, glob for filenames, grep for text. - **Edit:** apply a patch, replace an exact string, create a new file. - **Shell:** run builds, tests, linters, and git commands. - **Web and docs:** fetch a page or search documentation for an unfamiliar library. - **Code intelligence:** ask a language server for definitions, references, and type errors. - **External services:** issue trackers, databases, and CI systems, often connected through a standard such as MCP. - **Meta tools:** maintain a to-do list, spawn a subagent, or ask the user a question. Two design choices matter a lot here. First, tools are deliberately narrow and well described. A dedicated edit tool that fails loudly when the target text is missing is generally more reliable than asking the model to rewrite a whole file through the shell. Second, tools are gated by permissions. Read-only actions usually run freely, while writes and shell commands either ask for your approval or run inside a sandbox. ## Context gathering: the hard part The model has a finite context window, and it knows nothing about your repository except what ends up in front of it. A large share of an agent's work is therefore deciding what to read. It builds up context in layers: - **Standing instructions.** Projects often include a file such as `AGENTS.md` or `CLAUDE.md` (the first is an open format many tools support, the second is the Claude Code equivalent) holding build commands, conventions, and architecture notes. The agent loads it at the start, so it already knows how to build and test. In a monorepo, the nearest file usually wins. - **The task itself.** The prompt, plus anything attached: an issue description, a stack trace, a screenshot. - **Exploration on demand.** The agent greps for the error message, finds the function that throws it, reads the surrounding file, follows imports, looks at neighboring tests, and checks git history to understand why the code looks the way it does. - **Retrieval.** Some tools build a semantic index of the codebase using embeddings. Many popular agents lean mainly on plain search (glob and grep) instead, because it is precise, reads the live files, and needs no index to maintain. Others combine both, since long grep loops can burn a lot of tokens in a big repository. - **Subagents.** A noisy investigation, like scanning dozens of files for usages of an API, can be delegated to a separate context that returns only a short summary. - **Compaction.** As the window fills, the harness summarizes older turns and drops bulky tool output so the agent can keep working on long tasks. Failures often originate here. An agent that never saw the helper function in another module will cheerfully write a second copy of it. An agent drowning in irrelevant files will lose track of the details that matter. Good context gathering is less about reading more and more about reading the right things. ## Planning: deciding before doing Planning ranges from implicit to explicit. For a small fix, the model's reasoning is the plan: find the bug, change it, run the test. For larger work, agents write an explicit plan listing the files to touch, the order of changes, and how each step will be verified. This is often a to-do list the agent ticks off, which also keeps it on course across a long session. Several tools offer a plan mode where the agent can only read and propose. You review the plan, adjust it, and approve it before any file is modified. This is one of the cheapest ways to catch a misunderstanding early. Strong plans tend to share a few traits. They finish the investigation before editing anything. They aim for the smallest change that solves the problem. And they decide on verification up front. Plans are also disposable. When a test fails in an unexpected way, the agent should revise its approach, and the loop makes replanning natural because every new observation lands in the conversation. Good agents also know when to stop and ask. If the requirements are ambiguous, a clarifying question costs you ten seconds, while a wrong guess costs a review cycle. ## Code execution: making changes and running them **Editing.** Agents usually avoid rewriting entire existing files. They apply targeted edits, typically an exact string replacement or a patch. In many tools, an edit is rejected if the text to replace is not found exactly once, which prevents silent corruption. Small diffs are also easier for you to review. **Running.** Shell access is what lets an agent verify its own work, and where that shell lives is an important decision. It might be your local machine, with permission prompts guarding risky commands. It might be a sandboxed container or virtual machine. Or it might be a cloud environment, where the agent works in the background on a fresh checkout of the repository while you do something else. Sandboxes limit the blast radius: they usually keep your secrets out of reach, restrict network access, and give the agent a disposable filesystem. Git branches and worktrees let several agents work on separate tasks in parallel without stepping on each other. Permission systems typically combine an allowlist of safe commands, a prompt for anything unfamiliar, and a hard block on destructive operations. ## Testing: the feedback loop that makes it work One of the biggest reasons modern coding agents work as well as they do is that they can check their work. A model's first attempt often has a flaw. What changes the outcome is running the code and reading what happens. A typical verification pass runs the test suite, the type checker, the linter, and the build. Failure output is excellent feedback. A compiler error or a failed assertion tells the model exactly what went wrong, usually with a file and line number, which is far more precise than a vague human instruction. The agent reads the output, fixes the issue, and reruns. Agents often work in a test-first style for bug fixes: write a test that reproduces the bug, watch it fail, make the fix, watch it pass. For new features, they add tests that describe the intended behavior. There are caveats worth knowing: - **The agent optimizes for the signal it can see.** If the goal is "make the tests pass," it may special-case an input, loosen an assertion, or delete an inconvenient test. A weak test suite means weak guardrails. - **Flaky tests are poison.** An agent chasing a failure that is really random noise can burn a lot of time and make unrelated changes. - **Some things tests cannot cover.** For UI changes, agents increasingly drive a browser and inspect screenshots, but visual and performance checks remain much less reliable than unit tests. ## Review: the last gates before merge Review happens in layers. **Self-review.** Before finishing, a good agent looks at its own diff. It checks for leftover debug statements, unrelated edits, missing edge cases, and files it forgot to update. This is cheap, and it catches a surprising number of small mistakes. **Automation.** In cloud and background setups, the agent commits to a branch, pushes, and opens a pull request on its own, describing what changed, why, and how it was verified. It often attaches logs or screenshots as evidence. In a local session it typically asks before pushing. Continuous integration then runs the full test suite, linters, and security scans. Some teams add a second AI reviewer that starts from a fresh context, so it has no attachment to the original agent's reasoning. **Human review.** This remains the real gate. Read an agent's pull request the way you would read a colleague's: understand the change, check that the tests actually test the right thing, and question design decisions. The agent is trusted to propose changes, not to approve them. ## Putting it together: a worked example Here is how the earlier request plays out end to end. 1. **Prompt.** "Users get logged out after resetting their password. Fix it." 2. **Context.** The agent reads the project instructions file, greps for `resetPassword`, opens the handler, and notices it calls `invalidateAllSessions()`. It reads the session store and the existing auth tests, then checks git history to see when that line was added and why. 3. **Plan.** Write a failing test that logs in, resets the password, and expects the current session to remain valid. Then change the handler to revoke other sessions but keep the current one. Then run the auth tests. 4. **Execution.** It adds the test, runs it, and watches it fail for the expected reason. It then edits the handler with a small, targeted patch. 5. **Testing.** The new test passes. The wider auth suite reveals an older test that expects every session to be revoked. The agent decides that test encodes the old behavior, updates it, and flags the change prominently in its summary. 6. **Review.** The agent inspects its diff, removes a stray log line, commits on a new branch, and opens a pull request describing the behavior change and the updated test. 7. **Human.** You read the pull request and see that changing the older test is really a product decision. You confirm it with your team and merge. Notice that the model never needed to know your codebase in advance. It needed good tools, a way to find the relevant code, and a way to check its work. ## Where agents still struggle - **Ambiguity.** When a request is underspecified, agents sometimes guess instead of asking. - **Long-horizon drift.** Over many steps, especially after context has been compacted, an agent can forget an earlier constraint. - **Hidden knowledge.** Unwritten conventions, production quirks, and decisions made in meetings are invisible unless someone writes them down. - **Overreach.** Asked to fix one thing, an agent may refactor three others. - **Confident summaries.** A line like "all tests pass" may mean the full suite or only the subset it ran. ## Getting better results from your agent - Document your build, test, and style commands in a project instructions file. - Give the agent a verifiable goal, such as "make this test pass" or "this endpoint should return 404 for unknown IDs." - Keep tasks small and well scoped. - Invest in fast, reliable tests. They are the agent's eyes. - Ask for a plan on anything non-trivial and review it before code is written. - Review the diff, not the summary. ## The takeaway AI coding agents work because of a simple pattern: gather context, plan, act, check, and repeat, with a human at the end. The model supplies reasoning, the harness supplies hands and guardrails, and your tests and review process supply the ground truth. That is why your results depend on the repository as much as on the model. Treat the agent like a capable new teammate, give it what it needs to succeed, and keep your hands on the final merge button.