Spaces:
Sleeping
Sleeping
File size: 6,464 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 | # Full Pipeline Guide
This guide walks through building a complete ACE pipeline from scratch β choosing components, defining an environment, running training, and saving results.
## Components
A full pipeline needs four things:
1. **LLM Client** β the language model powering all three roles
2. **Three Roles** β Agent, Reflector, SkillManager
3. **Environment** β evaluates agent outputs
4. **Samples** β training data with questions and ground truth
## Step 1: Create the Roles
Each role takes a model string directly. Supports any [LiteLLM model](https://docs.litellm.ai/) or PydanticAI-native identifier:
```python
from ace import Agent, Reflector, SkillManager
agent = Agent("gpt-4o-mini")
reflector = Reflector("gpt-4o-mini")
skill_manager = SkillManager("gpt-4o-mini")
```
Optionally use a cheaper model for learning:
```python
agent = Agent("gpt-4o")
reflector = Reflector("gpt-4o-mini")
skill_manager = SkillManager("gpt-4o-mini")
```
## Step 3: Define an Environment
The environment evaluates agent outputs. Extend `TaskEnvironment` and implement `evaluate()`:
```python
from ace import TaskEnvironment, EnvironmentResult
class MathEnvironment(TaskEnvironment):
def evaluate(self, sample, agent_output):
correct = str(sample.ground_truth).lower() in str(agent_output.final_answer).lower()
return EnvironmentResult(
feedback="Correct!" if correct else f"Incorrect. Expected: {sample.ground_truth}",
ground_truth=sample.ground_truth,
metrics={"accuracy": 1.0 if correct else 0.0},
)
```
Or use the built-in `SimpleEnvironment` for basic ground-truth matching:
```python
from ace import SimpleEnvironment
environment = SimpleEnvironment()
```
## Step 4: Prepare Samples
```python
from ace import Sample
samples = [
Sample(question="What is 2+2?", context="", ground_truth="4"),
Sample(question="Capital of France?", context="", ground_truth="Paris"),
Sample(question="Who wrote Hamlet?", context="", ground_truth="Shakespeare"),
]
```
## Step 5: Build and Run the Pipeline
```python
from ace import ACE
runner = ACE.from_roles(
agent=agent,
reflector=reflector,
skill_manager=skill_manager,
environment=environment,
)
results = runner.run(samples, epochs=3)
```
## Step 6: Save the Skillbook
```python
runner.save("trained.json")
print(f"Learned {len(runner.skillbook.skills())} strategies")
```
## Complete Example
```python
from ace import (
ACE, Agent, Reflector, SkillManager,
Sample, SimpleEnvironment,
)
# Roles (each takes a model string directly)
agent = Agent("gpt-4o-mini")
reflector = Reflector("gpt-4o-mini")
skill_manager = SkillManager("gpt-4o-mini")
# Pipeline
runner = ACE.from_roles(
agent=agent,
reflector=reflector,
skill_manager=skill_manager,
environment=SimpleEnvironment(),
)
# Training data
samples = [
Sample(question="What is 2+2?", context="", ground_truth="4"),
Sample(question="Capital of France?", context="", ground_truth="Paris"),
]
# Train and save
results = runner.run(samples, epochs=3)
runner.save("trained.json")
```
## Checkpoints
Save the skillbook automatically during long training runs:
```python
runner = ACE.from_roles(
agent=agent,
reflector=reflector,
skill_manager=skill_manager,
environment=environment,
checkpoint_dir="./checkpoints",
checkpoint_interval=10, # Save every 10 samples
)
```
This creates:
- `ace_checkpoint_10.json`, `ace_checkpoint_20.json`, etc.
- `ace_latest.json` (always the most recent)
## Deduplication
Prevent duplicate skills from accumulating (requires `uv add ace-framework[deduplication]`):
```python
from ace import DeduplicationConfig, DeduplicationManager
dedup = DeduplicationManager(DeduplicationConfig(
enabled=True,
embedding_model="text-embedding-3-small",
similarity_threshold=0.85,
))
runner = ACE.from_roles(
...,
dedup_manager=dedup,
dedup_interval=10,
)
```
## Custom Prompts
The default prompts are v2.1 and work well out of the box. You can pass your own templates via the `prompt_template` parameter:
```python
agent = Agent(llm, prompt_template="Your custom agent prompt with {skillbook}, {question}, {context}")
reflector = Reflector(llm, prompt_template="Your custom reflector prompt ...")
skill_manager = SkillManager(llm, prompt_template="Your custom skill manager prompt ...")
```
See [Prompt Engineering](prompts.md) for template variables and more examples.
## Testing Without API Calls
Use `test` as the model to get PydanticAI's built-in test model, or use `unittest.mock` to patch the agent's `run_sync` method:
```python
agent = Agent("test")
reflector = Reflector("test")
skill_manager = SkillManager("test")
```
## Observability
Add Opik tracing to any pipeline via `extra_steps` (requires `uv add ace-framework[observability]`):
```python
from ace import ACE, OpikStep, register_opik_litellm_callback
runner = ACE.from_roles(
agent=agent,
reflector=reflector,
skill_manager=skill_manager,
environment=environment,
extra_steps=[OpikStep(project_name="my-experiment")],
)
# Optionally add per-LLM-call cost tracking
register_opik_litellm_callback(project_name="my-experiment")
```
See [Opik Observability](../integrations/opik.md) for full details.
## Going Deeper: Manual Pipeline Composition
The `ACE.from_roles()` runner composes a `Pipeline` internally. You can build the
same pipeline yourself for full control over step ordering, branching, and
custom steps:
```python
from ace import Pipeline, AgentStep, EvaluateStep, learning_tail
pipe = Pipeline([
AgentStep(agent, skillbook),
EvaluateStep(environment),
*learning_tail(reflector, skill_manager, skillbook),
])
```
See [Composing Pipelines](composing-pipelines.md) for the complete guide.
## What to Read Next
- [Composing Pipelines](composing-pipelines.md) β compose custom pipelines from steps
- [Async Learning](async-learning.md) β parallel Reflector execution
- [Prompt Engineering](prompts.md) β customize prompt templates
- [Integration Pattern](integration.md) β wrap existing agents instead
- [Opik Observability](../integrations/opik.md) β monitor costs and traces
|