Welcome to Chapter 4!
In Chapter 3: Agent Execution Runtime, we built the "Game Console" that runs our agents. We learned how the system creates a sandbox and manages the lifecycle of an AI task.
However, booting up the system isn't enough. We need to tell the AI exactly what to do. In this chapter, we will explore Dynamic Prompt Engineering.
Imagine you are a spy agency handling a "Secret Agent."
If you give the agent the instructions for Mission A while they are holding wire cutters for Mission B, disaster strikes!
In AgentTool, we have different agents (General Purpose, Plan, Verification) running in different environments (Coordinator, Sub-agent, Teammate). A single static text file like "You are a helpful assistant" is not enough.
We want to generate a System Prompt (the hidden instructions sent to the LLM) that changes automatically based on the situation.
If we enable a feature called "Context Forking," the prompt should say: "You can fork yourself to run parallel tasks." If we disable that feature, that sentence must vanish so the AI doesn't try to use a tool that doesn't exist.
Dynamic Prompt Engineering in AgentTool relies on three building blocks:
isForkSubagentEnabled) to inject specific rules.
Instead of reading a static .txt file, AgentTool runs a function called getPrompt(). This function acts like a sandwich artist, assembling the final text layer by layer.
prompt.ts
Let's look at how the code constructs this "Mission Briefing" in prompt.ts.
First, the system needs to tell the AI what tools it holds. It doesn't hardcode this; it calculates it based on the agent's definition.
// simplified from prompt.ts
function getToolsDescription(agent: AgentDefinition): string {
const { tools, disallowedTools } = agent
// If we have a "Denylist" (e.g., Plan Agent cannot write files)
if (disallowedTools && disallowedTools.length > 0) {
return `All tools except ${disallowedTools.join(', ')}`
}
// Otherwise, list specific allowed tools
return tools ? tools.join(', ') : 'All tools'
}
Explanation: This function checks the agent's definition. If the agent is restricted (like the Read-Only Plan Agent from Chapter 2), the prompt explicitly says: "All tools except write_file." This prevents the AI from hallucinating that it can write code.
The AI needs to know about other agents it can call for help.
// simplified from prompt.ts
export function formatAgentLine(agent: AgentDefinition): string {
// Get the tool description we calculated above
const toolsDesc = getToolsDescription(agent)
// Format: "- Name: Description (Tools: ...)"
return `- ${agent.agentType}: ${agent.whenToUse} (Tools: ${toolsDesc})`
}
Explanation: This creates a neat list like:
- Plan: software architect (Tools: All tools except edit_file)- BugHunter: finds bugs (Tools: readFile, grep)This is the heart of the dynamic system. It stitches everything together.
// simplified from prompt.ts
export async function getPrompt(
agentDefinitions,
isCoordinator
) {
// Check if "Forking" feature is turned on
const forkEnabled = isForkSubagentEnabled()
// Conditionally create the "When to Fork" text block
const whenToForkSection = forkEnabled
? `## When to fork\nFork yourself when...`
: '' // Empty string if disabled!
// ... (continues below)
Explanation: We check isForkSubagentEnabled. If false, whenToForkSection becomes an empty string. This ensures we never confuse the AI with instructions for disabled features.
The prompt also changes its examples based on the mode.
// simplified from prompt.ts
const forkExamples = `
<example>
user: "Research this."
assistant: Forking for research...
</example>
`
const standardExamples = `
<example>
user: "Write code."
assistant: Writing code...
</example>
`
// Choose which examples to show
const activeExamples = forkEnabled ? forkExamples : standardExamples
Explanation: If Forking is on, we show examples of how to fork. If off, we show standard coding examples. This is crucial for In-Context Learningβthe AI mimics the examples it sees.
Finally, we return the massive string.
// simplified from prompt.ts
return `
Launch a new agent to handle complex tasks.
${agentListSection}
${whenToForkSection}
${activeExamples}
`
}
Explanation: The final prompt is a concatenation of all the conditional sections. The Runtime receives this string and sends it to the LLM as the "System Message."
In this chapter, we learned that Dynamic Prompt Engineering is the art of assembling instructions on the fly.
getPrompt function that concatenates strings based on feature flags and agent definitions.Now that the agent knows who it is (Chapter 1), what role it plays (Chapter 2), how to run (Chapter 3), and what its mission is (Chapter 4), it needs to be able to remember what it has done.
Next Chapter: Persistent Agent Memory
Generated by Code IQ