Skip to content

Commit 383deec

Browse files
committed
feat: Integrate tool orchestrator into hypothesize and reflect nodes
Wire Claude tool-use orchestration into the agent graph with graceful fallbacks. Score falsifiable claims during reflect to track proposal accuracy. ## Changes - Update hypothesize_node to try tool orchestration first: - Calls ToolOrchestrator with Claude tool-use - Falls back to ProposalGenerator if tools unavailable - No breaking changes; tools activate automatically - Add _hypothesize_with_tools() helper: - Gathers market context via tools (regime, web search) - Calls Claude with available tools - Records tool calls in trace - Enhance reflect_node with claim scoring: - Add _score_falsifiable_claims() to track proposal accuracy - Compares predicted vs. realized improvements - Enables harness to learn which proposal strategies work - Update .env.example: - Add TAVILY_API_KEY and ANTHROPIC_API_KEY placeholders - Keep .env in .gitignore; never commit secrets - Add TOOL_INTEGRATION_GUIDE.md: - Setup instructions (dependencies, API keys) - Architecture overview and how tools work - Available tools and their purposes - Extending tools with custom implementations - Evaluation metrics and walk-forward validation - Debugging and troubleshooting ## Behavior 1. Agent runs hypothesize_node 2. Tool orchestrator tries Claude tool-use (if ANTHROPIC_API_KEY set) 3. Claude can call tools: get_regime_context, search_market_sentiment, etc. 4. Tool results fed back to Claude for reasoning 5. Claude generates proposals (parsing TODO) 6. Falls back to ProposalGenerator if tools fail 7. In reflect_node, falsifiable claims are scored 8. Scores tracked for harness evaluation ## API Key Security - .env must contain TAVILY_API_KEY and ANTHROPIC_API_KEY (if using tools) - .env is in .gitignore; safe to add locally - Tools degrade gracefully if keys missing This establishes the foundation for harness evolution where tool definitions can be evolved as editable surfaces and proposal accuracy is tracked. Claude-Session: https://claude.ai/code/session_01E54K1CmU1o6MwuLmVGqhSZ
1 parent 62344e8 commit 383deec

3 files changed

Lines changed: 390 additions & 9 deletions

File tree

.env.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ GOOGLE_API_KEY=your_gemini_api_key_here
99
# Get your key at: https://fred.stlouisfed.org/docs/api/api_key.html
1010
FRED_API_KEY=your_fred_api_key_here
1111

12+
# Optional: Tavily API Key for web search in tools
13+
# Get your key at: https://tavily.com
14+
TAVILY_API_KEY=your_tavily_api_key_here
15+
16+
# Optional: Anthropic API Key for Claude tool-use (if using)
17+
# Get your key at: https://console.anthropic.com
18+
ANTHROPIC_API_KEY=your_anthropic_api_key_here
19+
1220
# Optional: Logging configuration
1321
LOG_LEVEL=INFO
1422

docs/TOOL_INTEGRATION_GUIDE.md

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
# Tool Integration & Harness Evolution Guide
2+
3+
This guide covers the tool-calling architecture integrated into the agent graph and how to enable harness evolution features.
4+
5+
## Architecture Overview
6+
7+
The agent graph now includes **tool orchestration** for:
8+
1. **Market context gathering** — regime signals, web search
9+
2. **Quality assessment** — eval benchmark scoring
10+
3. **Falsifiable claim tracking** — proposal prediction accuracy
11+
12+
```
13+
analyze ──► hypothesize (with tools) ──► backtest ──► reflect (with claim scoring) ──► store
14+
▲ │
15+
└──────────────── (retry if needed) ◄──────────┘
16+
```
17+
18+
## Setup
19+
20+
### 1. Install Dependencies
21+
22+
The tool system requires Claude SDK and Tavily for web search (optional):
23+
24+
```bash
25+
pip install "anthropic>=0.30" "tavily-python>=0.3"
26+
```
27+
28+
Or install the project with LLM extras:
29+
```bash
30+
pip install -e ".[llm]"
31+
```
32+
33+
### 2. Configure API Keys (`.env`)
34+
35+
Copy `.env.example` to `.env` and set your API keys:
36+
37+
```bash
38+
# Required for tool orchestrator (Claude tool-use)
39+
ANTHROPIC_API_KEY=your_key_here
40+
41+
# Optional for web search in tools
42+
TAVILY_API_KEY=your_key_here
43+
44+
# Existing keys (Gemini, FRED, etc.)
45+
GOOGLE_API_KEY=your_key_here
46+
FRED_API_KEY=your_key_here
47+
```
48+
49+
**⚠️ Important:** `.env` is in `.gitignore`. Never commit API keys.
50+
51+
### 3. Enable Tools in Agent
52+
53+
The `hypothesize_node` in `src/agent/agent_graph.py` now:
54+
1. **Tries tool orchestration first** — if Claude/Tavily available
55+
2. **Falls back to ProposalGenerator** — if tools fail or APIs missing
56+
3. **Scores claims in reflect** — tracks proposal accuracy
57+
58+
No code changes needed to activate — tools are tried automatically.
59+
60+
## How It Works
61+
62+
### Tool Orchestrator Loop
63+
64+
When `hypothesize_node` is called:
65+
66+
```python
67+
# 1. Build tool registry
68+
registry = get_default_registry()
69+
70+
# 2. Create orchestrator
71+
orchestrator = ToolOrchestrator(registry)
72+
73+
# 3. Run Claude with tools
74+
result = orchestrator.run_tool_loop(
75+
user_prompt="Generate 5 momentum proposals...",
76+
regime_context=context,
77+
strategy_type="momentum",
78+
max_turns=2,
79+
)
80+
81+
# 4. Claude can call tools like:
82+
# - get_regime_context() → retrieve stored regime signals
83+
# - search_market_sentiment() → web search via Tavily
84+
# - extract_parameter_recommendations() → access parameter grid
85+
# - run_benchmark_to_assess_quality() → eval harness quality
86+
87+
# 5. Tool results fed back to Claude
88+
# 6. Claude reasons and generates proposals (as JSON)
89+
# 7. Proposals parsed into Proposal objects (TODO)
90+
```
91+
92+
### Available Tools
93+
94+
| Tool | Purpose | Requires |
95+
|------|---------|----------|
96+
| `get_regime_context` | Retrieve stored market context | StrategyMemory |
97+
| `search_market_sentiment` | Web search market news, VIX | Tavily API |
98+
| `search_strategy_research` | Web search strategy ideas | Tavily API |
99+
| `extract_parameter_recommendations` | Access parameter grid | Config grid |
100+
| `run_benchmark_to_assess_quality` | Quality assessment eval | Recent backtest results |
101+
102+
### Falsifiable Claims
103+
104+
When a proposal is generated with a claim (e.g., "This window length will improve Sharpe by 15%"):
105+
106+
1. **Proposal generation** — claim is recorded in `Proposal.reasoning`
107+
2. **Reflect node**`_score_falsifiable_claims()` compares predicted vs. actual
108+
3. **Memory storage** — claim accuracy tracked in `StrategyMemory`
109+
4. **Harness eval** — eval suite scores "% of claims materialized"
110+
111+
This creates a feedback loop where the harness learns which proposal strategies work.
112+
113+
## Extending the Tool System
114+
115+
### Add a New Tool
116+
117+
1. Implement the callable function:
118+
119+
```python
120+
# src/agent/tools/registry.py
121+
122+
def _my_new_tool(param1: str) -> Dict[str, Any]:
123+
"""Your tool implementation."""
124+
return {"result": "..."}
125+
```
126+
127+
2. Register it in `get_default_registry()`:
128+
129+
```python
130+
registry.register(
131+
Tool(
132+
name="my_new_tool",
133+
description="What it does",
134+
input_schema={
135+
"properties": {
136+
"param1": {"type": "string"},
137+
},
138+
"required": ["param1"],
139+
},
140+
callable_fn=_my_new_tool,
141+
category="custom", # For organization
142+
)
143+
)
144+
```
145+
146+
3. The tool is now available in Claude tool-use loops and can be called by agents.
147+
148+
### Modify Tool Behavior
149+
150+
Tools and their schemas live in `src/agent/tools/`:
151+
152+
- **Tool definitions**`registry.py` (callable + schema)
153+
- **Web search**`_search_market_sentiment`, `_search_strategy_research`
154+
- **Evaluation**`evals.py` (quality assessment)
155+
- **Orchestration**`orchestrator.py` (Claude loop)
156+
157+
Change any of these and the agent's next run uses the new version.
158+
159+
## Evaluation & Harness Quality
160+
161+
### Run Quality Assessment
162+
163+
Agents can call `run_benchmark_to_assess_quality` to self-evaluate:
164+
165+
```python
166+
result = registry.execute_tool(
167+
"run_benchmark_to_assess_quality",
168+
{"strategy_type": "momentum", "regime": "Bull"},
169+
)
170+
171+
# Returns:
172+
{
173+
"overall_score": 0.75,
174+
"passed": True,
175+
"metrics": {
176+
"oos_sharpe": 0.52,
177+
"stability": 0.68,
178+
"generalization_gap": 0.12,
179+
"tool_accuracy": 0.80,
180+
},
181+
"thresholds": {...},
182+
"recommendation": "Harness performing well. Consider scaling."
183+
}
184+
```
185+
186+
### Metrics Explained
187+
188+
- **OOS Sharpe** — Out-of-sample Sharpe ratio (primary metric)
189+
- **Stability** — Consistency across regimes (1 - normalized std dev)
190+
- **Generalization Gap** — Train Sharpe − held-out Sharpe (lower is better)
191+
- **Tool Accuracy** — % of falsifiable claims that materialized
192+
193+
## Walk-Forward Validation
194+
195+
To prevent overfitting, partition price history into three windows:
196+
197+
```python
198+
# Train window: [t0, t1)
199+
# - Agent evolves harness
200+
# - Tests proposals on held-in backtest data
201+
202+
# Validation window: [t1, t2)
203+
# - Accept/reject decisions based on OOS Sharpe
204+
# - Check falsifiable claims
205+
206+
# Held-out test window: [t2, t3)
207+
# - Touched once, at epoch end
208+
# - True generalization measurement
209+
# - Computes generalization gap (train improvement − test improvement)
210+
```
211+
212+
Implementation in `experiments/walk_forward_context.py` and `walk_forward_context_with_costs.py`.
213+
214+
## Logging & Debugging
215+
216+
Enable DEBUG logging to see tool calls and claims scoring:
217+
218+
```python
219+
import logging
220+
logging.basicConfig(level=logging.DEBUG)
221+
```
222+
223+
Output includes:
224+
- Tool invocations and results
225+
- Proposal generation methods
226+
- Falsifiable claim scoring
227+
- Harness evolution decisions
228+
229+
## Troubleshooting
230+
231+
### Tools Not Found
232+
233+
If you see `Tool <name> not found`, check:
234+
- Tool is registered in `get_default_registry()`
235+
- No typos in tool name
236+
237+
### Missing API Keys
238+
239+
- **Tavily** — Web search tools return empty results if `TAVILY_API_KEY` not set
240+
- **Anthropic** — Tool orchestrator falls back to ProposalGenerator if `ANTHROPIC_API_KEY` not set
241+
242+
Both degrade gracefully; harness works without them.
243+
244+
### Falsifiable Claims Not Scoring
245+
246+
Check:
247+
- `Proposal.reasoning` is populated (has the claim text)
248+
- `reflect_node` is called after backtest
249+
- `_score_falsifiable_claims()` is logging debug output
250+
251+
## Next Steps
252+
253+
1. **Parse Claude proposals** — Complete `_hypothesize_with_tools()` to extract proposals from Claude JSON
254+
2. **Evaluate on held-out data** — Run walk-forward harness with three-way split
255+
3. **Track generalization gap** — Measure train vs. held-out improvement
256+
4. **Evolve the grid** — Learn parameter space from results
257+
5. **Multi-agent swarm** — Add specialist agents (critic, regime analyst, etc.)
258+
259+
## References
260+
261+
- `src/agent/tools/README.md` — Tool system architecture
262+
- `src/agent/tools/example_integration.py` — Integration examples
263+
- `DESIGN.md` — Agent graph and harness architecture
264+
- `docs/PAPER_DRAFT.md` — Research methodology
265+
- Research: [Harness Engineering for Self-Improvement](https://lilianweng.github.io/posts/2026-07-04-harness/)

0 commit comments

Comments
 (0)