Inside a Self-Built Coding Agent: Prompt Assembly, Context Compression, and Multi-Agent Orchestration
Most developers use coding agents as black boxes and hit a ceiling when the tool misbehaves — wrong tool selection, lost context, style drift. Understanding the prompt structure, compression pipeline, and role isolation lets an engineer diagnose failures at the architecture level instead of re-prompting blindly, and the open-source PaiCLI implementation makes these internals concrete and reproducible.
A developer who built an open-source terminal coding agent (PaiCLI) walks through its internal architecture in an interview-style format. The prompt sent to the model is assembled from nine layers: four static layers (identity, persona, mode, approval) placed first to maximize Prompt Caching hit rates, followed by five dynamic layers that change each round. Context compression uses three tiers — tool-result truncation, conversation-history summarization triggered at 80% of the context window, and emergency auxiliary-context discard — each operating on different content at different granularities.
Skills and Tools are treated as distinct primitives: Tools are executable capabilities called via tool_call, while Skills are decision-level knowledge loaded on demand through a progressive-disclosure system with an LRU buffer capped at three active Skills. For complex tasks, the agent switches from ReAct mode to a Plan-and-Execute mode with topological sorting of dependencies, and a Team mode introduces Planner, Worker, and Reviewer roles with isolated conversation histories and prompt-level constraints that prevent the Reviewer from executing tools — keeping the roles from becoming both player and referee.
Incremental modifications trigger a full re-plan rather than appending to the original plan, because new requirements can change the dependency graph of already-completed steps. The whole system is open-source and serves as a reference implementation for developers who want source-level understanding of how coding agents work under the hood.
Placing static prompt layers first for Prompt Caching is a cost-optimization detail that most agent tutorials skip, yet it can multiply token costs if done wrong.
The three-tier compression design is notable because each tier targets a different content type — tool output, dialogue history, auxiliary context — rather than applying one generic summarizer, which avoids both premature compression and context-window overflows.
Triggering history summarization at 80% of the context window (not 100%) leaves headroom so the LLM call for summarization itself doesn't push the context over the limit.
The decision to re-plan on incremental changes rather than append is a real architectural tradeoff: appending is cheaper but silently breaks when new requirements shift the dependency graph of already-finished steps.
Keeping Planner and Reviewer tool-free via prompt constraints (not technical locks) is a pragmatic design choice that makes responsibility boundaries debuggable — wrong code means Worker, bad plan means Planner, missed defect means Reviewer.
The 10:1 to 20:1 tool-to-skill call ratio justifies progressive Skill loading economically; loading all Skills into context would waste tokens on capabilities most conversations never use.
Building an agent from scratch to understand commercial tools is a learning strategy that mirrors how developers once built their own frameworks to understand React or Kubernetes — the source-level understanding transfers directly to better prompting and debugging of production agents.