API Reference¶
Quick reference for the most-used classes and functions in ace.
Runners¶
ACELiteLLM¶
Simple self-improving conversational agent.
| 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 for full details.
ACE¶
Full adaptive pipeline (Agent + Reflector + SkillManager + Environment).
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.
BrowserUse¶
Browser automation with learning.
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")
LangChain¶
Wrap LangChain Runnables with learning.
from ace import LangChain
runner = LangChain.from_model(my_chain, ace_model="gpt-4o-mini")
results = runner.run([{"input": "Summarize this document"}])
ClaudeCode¶
Claude Code CLI with learning.
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")
ClaudeSDKExecuteStep / ClaudeSDKToTrace¶
Direct Anthropic Messages API steps for custom pipelines.
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.
Roles¶
Agent¶
Produces answers using the current skillbook.
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.
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.
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 for full details.
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.
Data Types¶
Sample¶
from ace import Sample
sample = Sample(
question="What is 2+2?",
context="Show your work",
ground_truth="4",
)
EnvironmentResult¶
from ace import EnvironmentResult
result = EnvironmentResult(
feedback="Correct!",
ground_truth="4",
metrics={"accuracy": 1.0},
)
UpdateOperation¶
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.
DeduplicationConfig¶
Requires: uv add ace-framework[deduplication]
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:
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:
Supports any LiteLLM model or PydanticAI-native identifier.
ACEModelConfig¶
Configuration for model selection per role:
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:
register_opik_litellm_callback¶
Standalone LLM cost tracking without pipeline traces:
from ace import register_opik_litellm_callback
register_opik_litellm_callback(project_name="my-experiment")
See Opik Observability.
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.
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 for the full architecture reference.
Prompts¶
The default prompts are v2.1 (built into ace). Pass a custom template via prompt_template:
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.