File size: 12,296 Bytes
116524e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
# API Reference

Quick reference for the most-used classes and functions in `ace`.

## Runners

### ACELiteLLM

Simple self-improving conversational agent.

```python

from ace import ACELiteLLM



agent = ACELiteLLM.from_model("gpt-4o-mini")

```

| Method | Description |
|--------|-------------|
| `ask(question, context="")` | Generate an answer using the current skillbook |
| `learn(samples, environment, epochs=1, *, wait=True)` | Run the full ACE learning pipeline |
| `learn_from_feedback(feedback, ground_truth=None)` | Learn from the last `ask()` interaction |
| `learn_from_traces(traces, epochs=1, *, wait=True)` | Learn from pre-recorded execution traces |
| `save(path)` | Save skillbook to JSON |
| `load(path)` | Load skillbook from JSON |
| `enable_learning()` / `disable_learning()` | Toggle learning on/off |
| `wait_for_background(timeout=None)` | Wait for async learning to finish |
| `learning_stats` | Dict with background learning progress |
| `get_strategies()` | Formatted string of current strategies |

See [LiteLLM Integration](../integrations/litellm.md) for full details.

### ACE

Full adaptive pipeline (Agent + Reflector + SkillManager + Environment).

```python

from ace import ACE, Agent, Reflector, SkillManager, Skillbook, SimpleEnvironment



runner = ACE.from_roles(

    agent=Agent("gpt-4o-mini"),

    reflector=Reflector("gpt-4o-mini"),

    skill_manager=SkillManager("gpt-4o-mini"),

    environment=SimpleEnvironment(),

    skillbook=Skillbook(),

)



results = runner.run(samples, epochs=3)

```

| Method | Description |
|--------|-------------|
| `run(samples, epochs=1, wait=True)` | Run adaptation loop, return `list[SampleResult]` |
| `save(path)` | Save skillbook |
| `wait_for_background(timeout=None)` | Wait for async learning |
| `learning_stats` | Background learning progress |

See [Full Pipeline Guide](../guides/full-pipeline.md).

### BrowserUse

Browser automation with learning.

```python

from ace import BrowserUse



runner = BrowserUse.from_model(browser_llm=my_llm, ace_model="gpt-4o-mini")

results = runner.run("Find the top post on Hacker News")

```

See [Browser-Use Integration](../integrations/browser-use.md).

### LangChain

Wrap LangChain Runnables with learning.

```python

from ace import LangChain



runner = LangChain.from_model(my_chain, ace_model="gpt-4o-mini")

results = runner.run([{"input": "Summarize this document"}])

```

See [LangChain Integration](../integrations/langchain.md).

### ClaudeCode

Claude Code CLI with learning.

```python

from ace import ClaudeCode



runner = ClaudeCode.from_model(working_dir="./project", ace_model="gpt-4o-mini")

results = runner.run("Add unit tests for utils.py")

```

See [Claude Code Integration](../integrations/claude-code.md).

### ClaudeSDKExecuteStep / ClaudeSDKToTrace

Direct Anthropic Messages API steps for custom pipelines.

```python

from ace import Pipeline, Reflector, SkillManager, Skillbook, learning_tail

from ace.integrations import ClaudeSDKExecuteStep, ClaudeSDKToTrace



skillbook = Skillbook()

pipe = Pipeline([

    ClaudeSDKExecuteStep(model="claude-sonnet-4-20250514"),

    ClaudeSDKToTrace(),

    *learning_tail(Reflector("gpt-4o-mini"), SkillManager("gpt-4o-mini"), skillbook),

])

```

`ClaudeSDKResult` and `ToolCall` are Pydantic models, so token counts, latency,
tool calls, and serialization are validated before the learning tail consumes
the trace.

See [Claude SDK Integration](../integrations/claude-sdk.md).

---

## Roles

### Agent

Produces answers using the current skillbook.

```python

from ace import Agent



agent = Agent("gpt-4o-mini")

output = agent.generate(

    question="What is 2+2?",

    context="",

    skillbook=skillbook,

    reflection=None,  # optional

)

```

**AgentOutput fields:**

| Field | Type | Description |
|-------|------|-------------|
| `final_answer` | `str` | The generated answer |
| `reasoning` | `str` | Step-by-step reasoning |
| `skill_ids` | `list[str]` | Skillbook strategies cited |
| `raw` | `dict` | Raw LLM response |

### Reflector

Analyzes what worked and what failed.

```python

from ace import Reflector



reflector = Reflector("gpt-4o-mini")

reflection = reflector.reflect(

    question="What is 2+2?",

    agent_output=output,

    skillbook=skillbook,

    ground_truth="4",

    feedback="Correct!",

)

```

**ReflectorOutput fields:**

| Field | Type | Description |
|-------|------|-------------|
| `reasoning` | `str` | Analysis of the outcome |
| `error_identification` | `str` | What went wrong |
| `root_cause_analysis` | `str` | Why it went wrong |
| `correct_approach` | `str` | What should have been done |
| `key_insight` | `str` | Main lesson learned |
| `skill_tags` | `list[SkillTag]` | `(skill_id, tag)` pairs — populated in online mode when agent cited skills |
| `raw` | `dict` | Raw LLM response |

### SkillManager

Transforms reflections into skillbook updates.

```python

from ace import SkillManager



skill_manager = SkillManager("gpt-4o-mini")

sm_output = skill_manager.update_skills(

    reflections=(reflection,),

    skillbook=skillbook,

    question_context="Math problems",

    progress="3/5 correct",

    source=source,

)

# skillbook has already been mutated in place

```

Returns a `SkillManagerOutput` with an `.update` field (`UpdateBatch`) and `.raw` field.

See [Roles](../concepts/roles.md) for full details.

---

## Skillbook

```python

from ace import Skillbook



skillbook = Skillbook()

```

| Method / Property | Description |
|-------------------|-------------|
| `add_skill(section, issue=None, keywords=None, insight=None, content=None)` | Add a skill |
| `apply_update(update_batch)` | Apply update operations |
| `as_prompt()` | Markdown format for LLM consumption |
| `save_to_file(path)` | Save JSON plus embeddings sidecar |
| `Skillbook.load_from_file(path)` | Load JSON plus embeddings sidecar if present |
| `stats()` | Section count, skill count, active skill totals |
| `skills()` | List of all skills |

See [The Skillbook](../concepts/skillbook.md).

---

## Data Types

### Sample

```python

from ace import Sample



sample = Sample(

    question="What is 2+2?",

    context="Show your work",

    ground_truth="4",

)

```

### EnvironmentResult

```python

from ace import EnvironmentResult



result = EnvironmentResult(

    feedback="Correct!",

    ground_truth="4",

    metrics={"accuracy": 1.0},

)

```

### UpdateOperation

```python

from ace import UpdateOperation



op = UpdateOperation(

    type="ADD",

    section="context",

    keywords=["math", "decomposition"],

    issue="Complex arithmetic questions are easier to solve when the work is decomposed into smaller verified steps.",

    insight="Break problems into smaller steps before computing.",

    reflection_index=0,

    reflection_indices=[0, 1],

    skill_id="math-00001",

)

```

Operations: `ADD`, `UPDATE`, `TAG`, `REMOVE`. See [Update Operations](../concepts/updates.md).

### DeduplicationConfig

**Requires:** `uv add ace-framework[deduplication]`

```python

from ace import DeduplicationConfig



config = DeduplicationConfig(

    enabled=True,

    embedding_model="text-embedding-3-small",

    similarity_threshold=0.85,

)

```

---

## Environments

Extend `TaskEnvironment` to provide evaluation feedback:

```python

from ace import TaskEnvironment, EnvironmentResult



class MyEnvironment(TaskEnvironment):

    def evaluate(self, sample, agent_output):

        correct = sample.ground_truth.lower() in agent_output.final_answer.lower()

        return EnvironmentResult(

            feedback="Correct!" if correct else "Incorrect",

            ground_truth=sample.ground_truth,

        )

```

A built-in `SimpleEnvironment` uses substring matching and is included for quick testing.

---

## Providers

### resolve_model



Resolve a model string to a PydanticAI model instance:



```python

from ace.providers import resolve_model

model = resolve_model("gpt-4o-mini")

```



Supports any [LiteLLM model](https://docs.litellm.ai/) or PydanticAI-native identifier.



### ACEModelConfig



Configuration for model selection per role:



```python

from ace.providers import ACEModelConfig



config = ACEModelConfig.from_toml("ace.toml")
agent_model = config.for_role("agent")
```



---



## Observability



### OpikStep



Append to any pipeline for automatic tracing and cost tracking:



```python

from ace import OpikStep



OpikStep(project_name="my-experiment", tags=["training"])

```

### register_opik_litellm_callback



Standalone LLM cost tracking without pipeline traces:



```python

from ace import register_opik_litellm_callback

register_opik_litellm_callback(project_name="my-experiment")
```



See [Opik Observability](../integrations/opik.md).



---



## Recursive Reflector (RR)



PydanticAI agent-based trace analyser with tools for code execution and sub-agent analysis.



### RRStep



Drop-in replacement for `Reflector` — satisfies both `StepProtocol` and `ReflectorLike`.



```python

from ace.rr import RRStep, RRConfig



rr = RRStep(

    "gpt-4o-mini",                          # Model string

    config=RRConfig(max_requests=20),       # Configuration

)



# As drop-in reflector

ace = ACELiteLLM.from_model("gpt-4o-mini", reflector=rr)



# As pipeline step

pipe = Pipeline([..., rr, ...])

```

### RRConfig

| Parameter | Default | Description |
|-----------|---------|-------------|
| `timeout` | `30.0` | Per-execution timeout in seconds (Unix only) |
| `max_tokens` | `500_000` | Total token budget (input + output) per agent run |
| `max_requests` | `50` | Safety cap on LLM requests per agent run |
| `context_window` | `128_000` | Model context window; compaction triggers at 85% |
| `max_output_chars` | `20_000` | Per-execution output truncation limit |
| `max_depth` | `2` | Maximum recursion depth (0=root, max_depth=leaf) |

| `child_budget_fraction` | `0.5` | Fraction of remaining token budget for child sessions |

| `max_compactions` | `3` | Safety cap on full summarization rounds |
| `microcompact_keep_recent` | `3` | Recent tool results to preserve during microcompaction |

### Sandbox Functions

Available inside `execute_code` tool calls:

| Function | Description |
|----------|-------------|
| `FINAL(value)` | Submit final result dict (terminates the loop) |
| `FINAL_VAR(name)` | Submit a named variable as the result |
| `SHOW_VARS()` | Print available variables (debugging) |
| `register_helper(name, source, desc)` | Register a reusable helper function |
| `list_helpers()` | List registered helper names/descriptions |
| `run_helper(name, *args, **kwargs)` | Invoke a registered helper |
| `get_item_messages(item)` | Return message list for a batch item |
| `get_item_question(item)` | Return question string for a batch item |
| `get_message_text(msg)` | Safely render message content as text |

### TraceContext

Structured trace wrapper with factory methods:

| Factory | Input |
|---------|-------|
| `TraceContext.from_agent_output(output)` | `AgentOutput` |
| `TraceContext.from_conversation_history(msgs)` | `list[dict]` |
| `TraceContext.from_tau_simulation(msgs, system_prompt)` | TAU-bench messages |
| `TraceContext.from_browser_use(history)` | browser-use `AgentHistory` |
| `TraceContext.from_langchain(steps)` | LangChain intermediate steps |
| `TraceContext.from_reasoning_string(text)` | Raw reasoning string |
| `TraceContext.combine(traces)` | Merge multiple traces |

See [RR_DESIGN.md](../RR_DESIGN.md) for the full architecture reference.

---

## Prompts

The default prompts are v2.1 (built into `ace`). Pass a custom template via `prompt_template`:

```python

agent = Agent("gpt-4o-mini", prompt_template="Custom prompt with {skillbook}, {question}, {context}")

reflector = Reflector("gpt-4o-mini", prompt_template="Custom reflector prompt ...")

skill_manager = SkillManager("gpt-4o-mini", prompt_template="Custom skill manager prompt ...")

```

See [Prompt Engineering](../guides/prompts.md).