Appearance
11.7 — System Design: Agent Platform
Scenario: A developer-tools company wants to build a platform letting its customers (software teams) deploy custom AI coding agents that can read a codebase, propose changes, run tests, and open pull requests — genuinely open-ended, multi-step technical work where the exact sequence of actions can't be predetermined (unlike Part 11.6's constrained workflow platform).
1. Requirements
Let customer teams deploy an agent capable of genuinely open-ended software engineering tasks (fix this bug, implement this feature) that requires real autonomy — investigating a codebase, forming a plan, executing it, and adapting based on what it discovers — while remaining safe enough that customers trust it with real access to their code and CI systems.
2. Constraints
- Unlike Part 11.6's workflow platform, this genuinely requires agent-level autonomy (Part 3.7) — the task's steps cannot be predetermined, since what a bug fix actually requires depends entirely on what the agent discovers while investigating.
- Agents need real, consequential tool access: reading/writing code, running tests (which can execute arbitrary code, Part 9.6's sandboxing), and creating pull requests.
- Customers are technically sophisticated (software engineers) but still need strong default safety guarantees, since a single customer's team using the platform incorrectly could still cause real damage.
3. Functional Requirements
- Codebase exploration and understanding (retrieval over code, a specialized RAG variant, Part 3.5).
- Code modification proposals with test execution to validate them (Part 9.6's sandboxing for arbitrary test-code execution).
- Pull-request creation as the final output — never direct, unreviewed commits to a protected branch (Part 5.4's human-in-the-loop applied structurally).
4. Non-Functional Requirements
- Every code-execution step must be sandboxed with strong isolation (Part 9.6) given the genuinely untrusted nature of running arbitrary, agent-modified code.
- Agent runs must be fully bounded (Part 3.7's iteration cap) — an open-ended coding task without a hard step/time limit risks runaway cost and, worse, runaway unintended changes.
- Full traceability of every action the agent took, for the engineering team reviewing the resulting pull request to understand the agent's reasoning (Part 6.1's tracing, directly serving a functional need here, not just operational debugging).
5. Architecture
Task description"fix bug X"
Bounded agent loopinvestigate → plan → execute → validate, max N iterations (Part 3.7)
Code retrievalcode-specific chunking (Part 3.5)
Sandboxed code executionmicroVM/separate execution environment (Part 9.6)
PR creation toolNEVER direct commit, always a reviewable PR
6. Components
- Bounded agent loop (Part 3.7): given this task's genuine unpredictability, an agent (not a fixed workflow) is justified here — unlike Part 11.6's workflow platform or Part 11.3's support agent, where a workflow was the better default. This is the clearest instance in this Part of Part 3.7's "agent justified" case.
- Code-aware retrieval: a RAG variant specialized for code (different chunking strategy respecting function/class boundaries, Part 3.5's chunking-quality discussion applied to code structure specifically).
- Sandboxed execution environment (Part 9.6's strongest isolation tier — microVMs or fully separate, disposable execution environments) for running arbitrary, agent-generated or agent-modified test code, given this is exactly the "genuinely untrusted code execution" scenario Part 9.6 flagged as warranting the strongest available isolation.
- PR-only output tool: structurally prevents the agent from ever directly modifying a protected branch — every change surfaces as a reviewable pull request, a hard, code-enforced (Part 3.3/9.2) human-in-the-loop checkpoint on the final, consequential action.
7. Data Flow
- A developer submits a task description.
- The agent investigates the codebase via code-aware retrieval, forms a plan (Part 3.7's ReAct pattern).
- The agent executes changes and runs tests within the sandboxed environment (Part 9.6), iterating based on test results, bounded by a hard iteration cap.
- Once the agent concludes its changes are ready (or the iteration cap is reached), it opens a pull request — never committing directly.
- A human engineer reviews the PR, with the full agent trace (Part 6.1) available to understand the reasoning behind each change.
8. Failure Modes
- Agent gets stuck in an unproductive loop (e.g., repeatedly trying and failing the same fix): bounded by the hard iteration cap (Part 3.7), at which point it opens a PR with its best partial progress and an explicit note about where it got stuck, rather than looping indefinitely.
- Sandboxed test execution attempts something genuinely malicious or destructive: contained entirely within the sandbox's isolation boundary (Part 9.6) — the strongest possible mitigation given this is precisely the class of risk sandboxing exists for.
- Agent proposes a change that passes its own tests but is subtly wrong: mitigated by the mandatory human-review-via-PR step (section 6) — the agent's own test-passing isn't treated as sufficient for unreviewed merge, exactly Part 8.1's outcome-vs-trajectory distinction applied here (passing tests is "outcome," but a human reviewing the actual diff and reasoning trace checks something closer to "trajectory").
9. Security
This design sits at the highest-stakes end of Part 9.2's excessive-agency spectrum — genuine code-execution capability warrants the strongest available sandboxing (Part 9.6) and the hardest available human-in-the-loop checkpoint (never bypassable direct commits, only PRs). Tool access should be scoped per-repository, per-customer (Part 9.3/9.6), preventing any cross-customer code or credential exposure.
10. Scalability
Agent runs are naturally parallelizable across customers/tasks (Part 5.6's independent-execution model) — the sandboxed execution environments themselves (Part 9.6) should scale elastically per active agent run, since each run needs its own genuinely isolated environment.
11. Observability
Full trajectory tracing (Part 6.1/8.1) is a functional requirement here, not just an operational nicety — the human reviewer needs to understand why the agent made each change, making comprehensive tracing central to the product's actual usability, not an afterthought.
12. Cost
Agent runs are typically more expensive per-task than a single LLM call or even a fixed workflow (Part 3.7/3.11's cost discussion) given the potentially many iterations of investigation, execution, and validation — cost per completed task should be tracked explicitly and likely forms the basis of this platform's own pricing model (Part 15), directly connecting engineering cost structure to business pricing strategy.
Worked numeric example: assume 50 active customer teams each running an average of 20 agent tasks/day → 1,000 agent runs/day. Given the code-reasoning demands of this task category, assume a strong-tier model at roughly $15/$75 per million input/output tokens (materially pricier than the mid-tier models used elsewhere in this Part, reflecting the genuine reasoning-quality bar code changes require), with an average of 8 iterations per run (below the hard cap of, say, 15 — section 6/8) at roughly 3,000 input tokens (accumulated code/test context) and 400 output tokens per iteration: (3,000/1,000,000 × $15) + (400/1,000,000 × $75) ≈ $0.045 + $0.03 ≈ $0.075/iteration → $0.60/run (8 iterations) → $600/day across 1,000 runs → roughly $18,000/month platform-wide. This is the concrete number behind section 12's claim that agent runs are meaningfully pricier per-task than a workflow (Part 11.6's example above cost roughly $0.0054/step, two orders of magnitude less per step) — directly informing whether this platform's pricing model charges per-run, per-iteration, or a capped monthly quota.
A run that hits the full 15-iteration cap without concluding costs proportionally more (~$1.125 at 15 iterations) — worth alerting on specifically (Part 8.4), since a rising rate of cap-hitting runs signals either a task-difficulty mismatch or an emerging systematic problem worth investigating before it inflates cost broadly.
13. Trade-offs
Chose a genuinely open-ended agent architecture (accepting its cost/unpredictability trade-offs) specifically because this task category — unlike every other system design in this Part — has genuinely unpredictable, discoverable-only-during-execution structure that a fixed workflow cannot capture, directly following Part 3.7's "agent justified" criterion rather than defaulting to a workflow out of general preference.
14. Alternatives
A fixed, templated workflow for common bug-fix patterns was considered as a possible cheaper alternative for a subset of simpler, well-understood task types — a hybrid approach (workflow for known-pattern tasks, full agent for genuinely novel ones, Part 3.12's decision-tree logic) is a reasonable future evolution once enough real usage data reveals which task types are actually predictable enough to warrant it.
15. Code Example
The PR-only output tool (section 6/9's structural, non-bypassable human-in-the-loop checkpoint) — the mechanism that makes it structurally impossible for the agent to modify a protected branch directly:
python
class DirectCommitBlockedError(Exception):
"""Raised if any code path attempts a direct commit to a protected branch."""
class AgentGitTool:
"""Git access surface exposed to the coding agent — deliberately
missing any direct-commit-to-protected-branch capability."""
def __init__(self, repo, protected_branches: set[str]):
self._repo = repo
self._protected_branches = protected_branches
def open_pull_request(self, branch_name: str, title: str, diff: str) -> str:
"""
The agent's ONLY path to proposing a change — always a reviewable
pull request, never a direct commit.
Args:
branch_name (str): A new, non-protected branch for this change.
title (str): Pull request title summarizing the change.
diff (str): The proposed code diff.
Returns:
str: The created pull request's URL.
Raises:
DirectCommitBlockedError: If branch_name resolves to a
protected branch — this tool has no other method that
could commit directly, by design.
"""
if branch_name in self._protected_branches:
raise DirectCommitBlockedError(
f"Refusing to target protected branch '{branch_name}' — "
f"all agent changes must go through a pull request on a "
f"new branch for human review."
)
return self._repo.create_pull_request(branch_name, title, diff)16. Interview questions
- Walk through estimating the monthly cost of running this agent platform given task volume, average iterations per run, and per-iteration token cost — and explain why cost per completed task, not per token, is the right unit for this platform's pricing model.
- Why is PR-only output a structural safety control rather than a policy the agent is merely instructed to follow?
17. FDE/customer scenario
CUSTOMER: "For our most trusted repos, can the agent just commit directly instead of opening a PR? It would save review time."
The FDE-correct response declines, even for a "trusted" repo — section 9's design treats PR-only output as a structural, non-bypassable control specifically because "trusted" is a property of the repo's owners, not of the agent's actual behavior on a given run (section 8's "passes its own tests but subtly wrong" failure mode applies regardless of how trusted the target repo is), and offering an exception undermines the exact guarantee that makes customers comfortable granting this platform real code-execution access in the first place.
Key takeaways
- This is the clearest case in this Part where a genuinely open-ended agent (not a workflow) is justified, per Part 3.7's criterion — the task's actual structure is discoverable only during execution, not knowable in advance.
- Genuine code-execution capability demands the strongest available sandboxing (Part 9.6) and a structurally non-bypassable human-in-the-loop checkpoint (PR-only output, never direct commits).
- Full trajectory tracing is a functional product requirement here, not just operational debugging — the human reviewer's ability to understand the agent's reasoning is core to the product's usability.
Things you should be able to explain
- Why this specific task category justifies a genuine agent architecture where most other designs in this Part favor a workflow.
- Why PR-only output is a structural, non-bypassable safety control rather than a mere convention.
Things you should be able to build
- A bounded, sandboxed coding agent with code-aware retrieval and a PR-only output mechanism.
Common mistakes
- Allowing any direct-commit path that bypasses human review.
- Insufficient sandboxing isolation for genuinely untrusted, agent-generated code execution.
Recommended next chapter
08-design-enterprise-knowledge-assistant.md