the last post was about augmenting the tui with an extension. this one looks at modifying the agent behavior.
(1 of N): scope here is the playbook-injection half. reflection and curation are the hard parts and earn their own posts.
What I want to learn
- explain the ACE memory system:
- the value it delivers and the algorithm that gets you there
- the architectural components
- the lifecycle, including which hooks an integration would need
Approach
- read the ACE python implementation. pull out:
- architectural components
- lifecycle(s)
- side-effects, data, and functions
What I found
ACE in one paragraph
ACE stands for Agent Curator Environment system. it's a framework for evolving and improving agentic behavior. rough sketch: your agent gets the right domain-specific instructions and tips for the task at hand. that context is continually groomed (allowed to grow) and then distilled into a clearer, more focused version that uses less context budget. claimed gains: +10.6% on agent tasks and +8.6% on domain-specific benchmarks.
the artifact at the center is the playbook. format is easy to grok: bullets organized into categories, each with an identifier and helpfulness/harmfulness counters.
# strategies & insights
[str-0001] helpful=5 harmful=0 :: Always verify data types before processing
the architecture has three roles:
- GENERATOR: produces reasoning trajectories. roughly: tightly-scoped context specific to the task at hand.
- REFLECTOR: evaluation and insight generation. reviews what took place and extracts lessons.
- CURATOR: converts the lessons into normalized form and applies delta updates to the playbook.
to make GENERATOR concrete, here's its prompt structure (truncated):
You are an analysis expert tasked with answering questions using your knowledge, a curated playbook of strategies and insights and a reflection that goes over the diagnosis of all previous mistakes made while answering the question.
...
Your output should be a json object, which contains the following fields:
- reasoning: your chain of thought / reasoning / thinking process, detailed analysis and calculations
- bullet_ids: each line in the playbook has a bullet_id. all bulletpoints in the playbook that's relevant, helpful for you to answer this question, you should include their bullet_id in this list
- final_answer: your concise final answer
...
**Answer in this exact JSON format:**
{{
"reasoning": "...",
"bullet_ids": ["calc-00001", "fin-00002"],
"final_answer": "..."
}}
inputs: question, playbook, context (optional), reflection (optional). outputs: response, plus the set of bullet ids the generator deemed useful.
Mapping ACE onto Pi sessions
a pi session has a natural shape that lines up with ACE's GENERATOR phase. each agent turn has a beginning, inputs, and a result. roughly:
- session start (or user input, or maybe a tool-call return for tool-refining cases): annotate
generation phase started, inject the playbook. - agent response: annotate
generation phase ended.
the produced artifact (the session, including the annotations) feeds reflection later. and a bunch of useful context comes for free: the user's prior turns, the model and provider, other session config. all already in the session.
so: first thing to build is the playbook-injection half. defer everything else.
First extension: playbook injection
the simplest viable thing: read a playbook.md from the cwd, append it to the system prompt for each agent turn.
const createStartCtx = (params: {
playbook?: string;
systemPrompt: string;
}): { systemPrompt: string } | undefined => {
if (!params.playbook) {
return undefined;
}
return {
systemPrompt: `${params.systemPrompt}
${params.playbook}`,
};
};
export default function (pi: ExtensionAPI) {
let ace: Ace | undefined;
pi.on('session_start', (_event, ctx) => {
// find/read or create playbook
ace = createAce(pi);
logAce(pi, ace);
});
pi.on('before_agent_start', (event, ctx) => {
return createStartCtx({
playbook: ace?.playbook,
systemPrompt: ctx.getSystemPrompt(),
});
});
}
initialize global state on session_start, read the playbook if it exists in the cwd, append it to the per-turn system prompt via before_agent_start.
the playbook.md in the working dir for the test was empty:
# ACE (Agent Curator Environment) Playbook
// TODO: fill this out
yes, empty. however:

What's next
i'm now an expert on the ACE system. (not really.) what is true: deterministic playbook injection works. what's been punted on is the actually-hard stuff.
- reflection on the session. distilling what happened into insights worth keeping.
- training over sessions. treating a session as input to an evaluation function with the playbook varied. this one's tricky and will take some thinking.
one of the two is the next post.