Dynamic System Prompt Assembly for Coding Agents: A Runtime Contract Approach
Coding agents often load a fixed system prompt at startup, even after tools, extensions, and working directories change. This article explains how to assemble system prompts at runtime as a session behavior contract, covering the inputs to collect, the principles to keep stable, post-start injection, context compression, subagents, neutral scaffold evaluation, and an implementation checklist.
1. The Problem Is Not Prompt Length but Runtime Consistency
Many intelligent coding tools treat the system prompt as fixed text inserted verbatim into context at startup. After the session begins, the text remains unchanged regardless of which tools the user has disabled, whether the working directory has changed, or whether external capabilities have been connected. As a result, the model may reference tools that are no longer available, ignore current directory constraints, or lose usage rules that were only preserved in the prompt after context compression.
A more reliable approach is to treat the system prompt as a behavior contract for the session: the base guidelines remain relatively stable, but the final text must be generated at startup from the live environment. The test is simple: every capability mentioned in the prompt should actually be available in the current session, and capabilities that are currently unavailable should not continue to occupy prompt space and mislead the model.
2. Inputs to Collect During Runtime Assembly
Assembly happens before the first inference round. The inputs should include at least five categories.
- Base behavior guidelines: tool-use priority, output style, memory file discovery and write rules, authorization requirements for dangerous operations, and how callable skills are described.
- Currently enabled tool set: each tool carries a short description, and only enabled items are concatenated. When a tool is disabled, its description disappears at the same time, preventing the model from calling a name that the runtime will reject.
- External extension connection status: if the session is connected to an external service that exposes capabilities over a protocol, inject that service’s usage boundaries, applicable scenarios, and return forms. If it is not connected, do not inject them.
- Skill or shortcut index: include only names, purposes, and trigger conditions. Do not stuff the full text of every skill into the system prompt.
- Environment awareness: operating system, date, working directory, and whether the session is in read-only or restricted mode. This information reduces unnecessary probing by the model.
User-level and project-level configurations should act as overlays, not as a separate set of conflicting prompts. The recommended order is platform default guidelines, organization policy, user preferences, and current repository conventions. Later layers should override only items that are explicitly allowed to be overridden, and the safety floor should not be quietly relaxed by project files.
The following is an illustrative flow:
effective_prompt = base_policyeffective_prompt += render(enabled_tools)effective_prompt += render(connected_extensions)effective_prompt += render(skill_index)effective_prompt += render(env)effective_prompt += apply(user_overrides, deny_list=safety_floor)
3. Principles That Should Be Hard-Coded in the Behavior Contract
Dynamic assembly does not mean there is no stable core. The core should use short statements to specify “how to work,” rather than piling up product introductions.
Tool priority. Reading files, pattern-based search, and path lookup should prefer dedicated tools rather than terminal commands that reconstruct equivalent operations. Dedicated tools make permission checks, result truncation, and structured returns easier. The terminal is suitable for builds, tests, and operations that genuinely have no dedicated tool coverage. The prompt should explain the reason for this preference; otherwise, the model may bypass controls because “the terminal is more universal.”
Output restraint. Require direct conclusions and necessary steps, and avoid emojis, polite confirmations, and restating the user’s words. Context for coding agents is expensive, and redundant output crowds out subsequent code and error messages. Style constraints should be locally relaxable by project conventions; for example, documentation tasks may allow fuller explanations, but the default should remain short.
Memory layering. Convention files should be discovered in the order of user home directory, repository root, and subdirectories. Nearer files override distant project details, while distant files retain personal habits. Write rules should state that only stable preferences, directory structure, build methods, and prohibitions are recorded, not one-off errors or secrets. Subdirectory conventions should take effect only when the agent works in that directory, preventing irrelevant constraints from polluting the global scope.
Explicit authorization for dangerous operations. For actions such as force-overwriting remote history, irreversible rollback, deleting large numbers of files, or rewriting credentials, the prompt must require explaining the impact to the user and obtaining explicit consent first. Default denial does not mean the action can never be performed; it means the model cannot infer on its own that “the user probably agrees.”
How to invoke skills. The index only tells the model which capabilities exist and when to use them. The skill body should be loaded at execution time, avoiding a startup prompt filled with long procedures.
4. Information That Still Needs Dynamic Injection After Startup
Base guidelines alone are not enough. The following types of content are suitable for concatenation at the start of each session and for updates after key state changes.
Tool descriptions change with the enabled set. In implementation, each tool should provide its own description fragment, and the assembler should iterate and concatenate them. This way, adding a new tool does not require editing one giant central string, and it reduces the chance of drift between descriptions and real parameters. Descriptions should include purpose, when not to use the tool, parameter constraints, and return shape, not a marketing-style capability list.
Extension service instructions are bound to connection status. Inject usage instructions after a connection is established; remove them after disconnection or authentication failure. If context undergoes compression, extension instructions are loss-prone “operating procedures” and should be reinjected after compression based on connections that are still valid, rather than expecting a summary to preserve them faithfully.
Keep the skill index lightweight. Limit fields to name, one-sentence description, and applicable conditions. Load details by name when the model needs them. Index expiration caused by installation or uninstallation should be reflected in the next assembly round, rather than waiting for a model call to fail.
Inject environment information in a fixed small block. Update this block when the working directory changes, when entering a submodule, or when switching to a read-only view. Do not make the model confirm where it is by repeatedly running probe commands.
Lazy-loaded tools need a discovery entry. When there are many tools, it is not necessary to include all descriptions in the first round. The prompt should state that “unknown tools can be discovered through retrieval,” and retrieval results should append the corresponding descriptions to subsequent context. The precondition for lazy loading is that retrieval itself is reliable and that the permission system still uses the actual enabled set; a name should not be allowed merely because it appeared in the prompt.
5. Context Management: Compression Must Not Remove the Contract
Long sessions inevitably compress history. A common mistake is to keep only a dialogue summary and discard system-side tool descriptions, extension procedures, and safety clauses together. The compressed agent may suddenly switch to using the terminal to read files indiscriminately or forget that dangerous operations require confirmation.
It is advisable to split context into a non-compressible layer and a compressible layer. The non-compressible layer includes the safety floor, current tool descriptions, valid extension instructions, the environment block, and still-applicable project conventions; after compression, replay this block as a whole. The compressible layer consists of chat history, read file snippets, and intermediate reasoning, which can be replaced by a structured summary: which paths were changed, which assumptions remain unverified, which commands failed and why. The summary should state facts, not vague notes such as “continue optimizing.”
Intermediate output from subtasks should also not be fed back into the main session indefinitely. The main session should receive only conclusions, change lists, and open issues, while raw logs remain in the subtask context.
6. Subagents: Isolate Context, Do Not Clone an All-Powerful Assistant
Subagents are suitable for clearly bounded subproblems, such as conducting a read-only review of a directory, running tests within a limited command set, or summarizing a set of retrieval results. A subagent should have a narrower tool set and an independent context, with a system prompt trimmed from the main contract rather than a separate, conflicting persona.
The main agent is responsible for splitting goals, accepting results, and actions that require user authorization; subagents should not directly perform irreversible operations. Return values should be as structured as possible: conclusion, evidence paths, confidence, and blockers. If a subagent times out or a tool fails, return the failure reason to the main session so that the main model does not fill in the gaps from imagination.
In terms of permissions, a subagent inherits a subset, not the full set. Operations forbidden to the parent session must not be allowed in the child session just because the prompt did not mention them.
7. How to Compare Scaffolds Rather Than Brands
Differences among agent scaffolds in the industry are mainly a matter of whether their mechanisms form a closed loop, not their slogans. The following points can be used for neutral evaluation without binding to any one implementation.
- Whether the prompt is reassembled when tools are toggled, extensions are connected, or directories change. If not, the model will still try to call a disabled tool.
- Whether safety clauses still exist after compression, subagents, and multi-turn tool calls. Safety prompts that appear only in the first round have very weak practical binding force.
- Whether the boundary between dedicated tools and the terminal is enforced at runtime, not merely written in the prompt. If the prompt recommends dedicated tools but the permission layer does not reject unnecessary full terminal reads, the model can still bypass them.
- Whether skills and extensions use index-based lazy loading or are all stuffed into the system prompt. The latter quickly crowds out code context as the number of tools grows.
- Whether failures are observable: tool denials, extension disconnections, and compression reinjection should have logs that can be checked, making it possible to distinguish model noncompliance from a missing fragment in the assembler.
Sophistication is usually reflected in these closed loops, not in longer prompt text. A short contract that is consistent with the runtime, still present after compression, and backed by the permission layer is better than an unmaintainable static long prompt.
8. Implementation Checklist
When designing or refactoring a coding agent, check each item:
- Assemble on site at startup, rather than only reading a constant string.
- Tool descriptions come from the tools themselves, and the prompt changes when the enabled set changes.
- Descriptions of external extensions do not appear when they are not connected; reinject them after reconnection or compression.
- Skills are indexed only and loaded on demand.
- The environment block includes minimal awareness information such as working directory and date.
- Project conventions may override style and path habits, but they must not override dangerous-operation authorization and credential red lines.
- Compression preserves the non-compressible layer and replays the currently valid tool and extension descriptions.
- Subagents use a trimmed contract and a tool subset; irreversible actions return to the main session and require user consent.
- Do not fabricate nonexistent interfaces, parameters, or performance promises in the prompt; descriptions must match the real tool definitions.
These practices do not depend on any vendor-specific interface and are suitable as an engineering baseline for self-built coding agents or enterprise code assistants. If running in a cloud development environment, object storage can hold convention files and skill packages, while logs and monitoring can verify assembly results and tool-denial reasons. The prompt content should still be determined by the real state at session startup, not hard-coded in advance.
