Skip to content

Commit 1e6d99b

Browse files
Hert4claude
andcommitted
docs: Phase 7 slice 1 — project polish
README was stuck at "Phase 0 scaffolding only" while the framework is actually at Phase 5/6 with 319 tests, 3 working harness adapters, 5 provider families, and 2 evidence sources. Anyone landing on the repo would conclude it was abandoned. - README rewrite: honest status (pre-alpha, actively developed), a quickstart that actually runs, architecture diagram, Python API example, adapter matrix, citation. Drops "not yet functional" warnings because the functional surface is large now. - CONTRIBUTING.md (closes Phase 0 deferred item): dev setup, the three-check gate (pytest + ruff + pyright strict), conventions (no regex in signal/, adapters extract not classify), a concrete "add a new adapter" walkthrough that points at the LangChain harness + evidence adapters as reference implementations. - .github/ISSUE_TEMPLATE/bug_report.md + feature_request.md — the feature template is structured around the four plugin axes so requests land in the right category. - .github/pull_request_template.md — plan.md phase pointer + the three-check gate as an explicit checklist. No code change; 319 tests still pass. plan.md §0.5 snapshot updated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 41a4e69 commit 1e6d99b

6 files changed

Lines changed: 274 additions & 26 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
name: Bug report
3+
about: Something doesn't work as documented
4+
labels: bug
5+
---
6+
7+
**What happened**
8+
<!-- A clear one-line summary -->
9+
10+
**Reproduction**
11+
<!-- Smallest steps / command / code that trigger it -->
12+
13+
```bash
14+
15+
```
16+
17+
**Expected vs actual**
18+
<!-- What you thought would happen, what actually happened (paste error output) -->
19+
20+
**Environment**
21+
- OS:
22+
- Python version:
23+
- `trace2skill` version/commit:
24+
- Relevant extras installed (e.g. `[anthropic]`, `[langchain]`):
25+
- LLM provider + model in use:
26+
27+
**Anything else**
28+
<!-- Logs, screenshots, related commits — optional -->
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
name: Feature / adapter request
3+
about: New adapter, new config knob, new behavior
4+
labels: enhancement
5+
---
6+
7+
**What do you want the framework to do that it can't do now?**
8+
<!-- One paragraph. Include the concrete use case, not just the abstract capability. -->
9+
10+
**Which axis does this live on?**
11+
<!-- Pick one or describe a new seam: -->
12+
- [ ] HarnessAdapter (new agent harness: LangChain, Cline, OpenCode, custom ReAct, ...)
13+
- [ ] LLMProvider (new LLM vendor or SDK wrapping)
14+
- [ ] SkillFormat (new on-disk skill layout)
15+
- [ ] EvidenceAdapter (new source of session signals)
16+
- [ ] Core pipeline (Stage 1/2/3 behavior, signal layer, CLI)
17+
- [ ] Other / cross-cutting
18+
19+
**Any existing adapter / provider this is like?**
20+
<!-- Pointing at `trace2skill/harnesses/langchain.py` or similar is fine. -->
21+
22+
**Willing to send a PR?**
23+
- [ ] Yes
24+
- [ ] Yes but I need pointers — see `CONTRIBUTING.md`
25+
- [ ] No, just requesting

.github/pull_request_template.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!--
2+
Thanks for the PR. Keep the description short — focus on *why*, not *what*.
3+
The diff shows *what*.
4+
-->
5+
6+
## Summary
7+
<!-- 1-3 sentences on the motivation. If this closes or fixes an issue, link it. -->
8+
9+
## Design notes
10+
<!--
11+
Optional. Use this for non-obvious decisions: why this approach over the
12+
alternatives, tradeoffs, what a future maintainer would need to know.
13+
-->
14+
15+
## Scope / plan.md phase
16+
<!-- e.g. "Phase 5 — Cline harness adapter" — helps the plan.md stay in sync -->
17+
18+
## Checklist
19+
20+
- [ ] `python -m pytest tests/unit -q` passes
21+
- [ ] `ruff check .` clean
22+
- [ ] `pyright --strict trace2skill` 0 errors on touched files
23+
- [ ] New behavior has tests; tests are offline-only (mocks, no live APIs) unless explicitly placed under `tests/integration/`
24+
- [ ] For new adapters: registered in the axis `__init__.py`, optional dependency declared in `pyproject.toml`
25+
- [ ] For behavior changes: `plan.md` §0.5 snapshot + relevant phase row updated

CONTRIBUTING.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Contributing to Trace2Skill
2+
3+
Thanks for considering a contribution. This is a pre-alpha research project, so expect rough edges, but we merge PRs that come with tests and match the existing design.
4+
5+
## Quick start
6+
7+
```bash
8+
git clone https://github.com/Hert4/trace2skill.git
9+
cd trace2skill
10+
pip install -e ".[dev]"
11+
12+
python -m pytest tests/unit -q # should print "319 passed" (or current count)
13+
ruff check . # should print "All checks passed!"
14+
pyright --strict trace2skill # should print "0 errors"
15+
```
16+
17+
If any of those three fail on `main`, that's a bug — open an issue.
18+
19+
## Development loop
20+
21+
1. Branch from `main`.
22+
2. Write failing tests first when the change is behavioral. Mocks live in `trace2skill/mocks/`; use them to avoid hitting real APIs in unit tests.
23+
3. Make the code change. Keep source files compact — the reference adapters are ~200-280 LOC each including comments.
24+
4. Run the three checks above before pushing.
25+
5. Open a PR with a clear `why` in the description. Link the plan.md phase the work belongs to if applicable.
26+
27+
## Conventions
28+
29+
- **Type hints everywhere.** `pyright --strict` gates CI.
30+
- **`ruff check .` clean.** Line length 100, plus `E F W I UP B SIM RUF` rule families. Run `ruff check --fix` for auto-fixable lints.
31+
- **No regex in `trace2skill/signal/`.** Rubric + LLM judge. (Paper §2.5 and plan §13.7.)
32+
- **Adapters do not classify.** `EvidenceAdapter` extracts raw signals. The judge decides what they mean. (Plan §13.8.)
33+
- **Tests run offline by default.** Live/integration tests live under `tests/integration/` and require explicit API keys — don't add them to the default suite.
34+
- **Commit style.** Follow the repo's existing commits: imperative subject line, blank, body explaining *why*. Feature commits prefixed `feat:`, fixes `fix:`, docs `docs:`, etc.
35+
36+
## Adding a new adapter
37+
38+
The framework's design goal is "new adapter in <300 LOC." Reference implementations:
39+
40+
| Axis | Reference |
41+
|---|---|
42+
| `HarnessAdapter` | `trace2skill/harnesses/langchain.py` (~200 LOC, lazy import pattern, unit-test-friendly `_response_to_trajectory` split) |
43+
| `EvidenceAdapter` | `trace2skill/evidence_adapters/langchain.py` (~280 LOC, LangSmith-backed, feedback API error-swallowing) |
44+
| `LLMProvider` | `trace2skill/llm/openai_compatible.py` (generic — 1 class covers 7+ providers via base_url) |
45+
| `SkillFormat` | `trace2skill/skill_formats/anthropic.py` (SKILL.md + resources/ with junk-dir filtering) |
46+
47+
Typical new-adapter PR:
48+
49+
1. Source file: `trace2skill/<axis>/<name>.py`. Use `TYPE_CHECKING` for heavy optional dependencies; lazy-import inside method bodies so the module stays importable when the extra isn't installed.
50+
2. Register in the axis's `__init__.py`.
51+
3. Add `[<name>]` to `pyproject.toml`'s `[project.optional-dependencies]` if the adapter needs a new SDK.
52+
4. Tests: `tests/unit/test_<name>_<axis>.py`. Mock the external SDK (`unittest.mock.MagicMock` / `AsyncMock` + `patch`). Target 10+ tests covering happy path, error paths, protocol conformance via `isinstance(obj, HarnessAdapter)` etc.
53+
5. Example (optional): `examples/<N>_<name>_<flavor>/` with a `README.md`, `trace2skill.yaml`, seed skill, a few tasks, and an evaluator.
54+
55+
## Deferred items / good first issues
56+
57+
See `plan.md` "Deferred checklist" and "Phase 5 remaining." Good starter tickets:
58+
59+
- `ClineHarnessAdapter` + `ClineSkillFormat` (`.clinerules`)
60+
- `OpenCodeHarnessAdapter`
61+
- Rubric YAMLs: `code_editing_agent`, `qa_agent`, `search_agent`, `spreadsheet_agent`
62+
- ast-grep lint rule banning regex inside `trace2skill/signal/`
63+
- `examples/04_langchain_rag_agent/` demo
64+
65+
## Questions
66+
67+
Open a GitHub issue. For design discussions, label with `design` and the relevant phase.
68+
69+
## License
70+
71+
By contributing, you agree your contributions are licensed under the MIT license (same as the repo).

README.md

Lines changed: 119 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,144 @@
11
# Trace2Skill
22

3-
Harness-agnostic framework for evolving agent skills from real trajectories.
4-
Implementation of **Trace2Skill: Distill Trajectory-Local Lessons into Transferable Agent Skills** ([arXiv:2603.25158](https://arxiv.org/abs/2603.25158)).
3+
Harness-agnostic framework for evolving agent skills from real trajectories. Reference implementation of **Trace2Skill: Distill Trajectory-Local Lessons into Transferable Agent Skills** ([arXiv:2603.25158](https://arxiv.org/abs/2603.25158)).
54

6-
> **Status:** pre-alpha (Phase 0 — scaffolding only).
7-
> Types and protocols are in place; pipeline stages land in Phase 1.
5+
[![Python](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/)
6+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
7+
[![Paper](https://img.shields.io/badge/arXiv-2603.25158-b31b1b.svg)](https://arxiv.org/abs/2603.25158)
8+
[![Tests](https://img.shields.io/badge/tests-319%20passing-brightgreen)](./tests)
9+
10+
> **Status:** pre-alpha, actively developed. Core pipeline and two real harnesses (Claude Code, LangChain) are working end-to-end. Not on PyPI yet — install from source.
811
912
## What it does
1013

1114
Given an agent with a `SKILL.md` file and a set of tasks with ground truth, Trace2Skill runs a 3-stage pipeline to improve the skill **without touching model weights**:
1215

13-
1. **Rollout** — run the agent on N tasks, collect trajectories
14-
2. **Analyze** — N parallel analysts propose patches (Error Analyst is an agentic ReAct loop with access to ground truth)
15-
3. **Consolidate** — hierarchical merge that keeps only edits appearing ≥2 times, with 3 deterministic guardrails
16+
1. **Rollout** — run the agent on N tasks in parallel, collect trajectories
17+
2. **Analyze** — N parallel analysts propose patches. Error Analyst is an **agentic ReAct loop** with 6 tools (inspect skill, read ground truth, try patches, diff vs ground truth, finish, drop). Quality-gate drops trajectories where the cause can't be verified.
18+
3. **Consolidate** — hierarchical merge that keeps only edits appearing ≥2 times across the patch pool, with 3 deterministic guardrails (file-exists, line-range conflict, trial-apply validation)
1619

17-
The output is a better `SKILL.md` + resources, portable across harnesses.
20+
Output: a better `SKILL.md` + resources, portable across harnesses. Every patch is traceable back to its source trajectory — full audit trail.
1821

1922
## Why this repo exists
2023

21-
The paper proves the method; this repo makes it **plug-and-play** across any agent harness. Four plugin axes:
24+
The paper proves the method. This repo makes it **plug-and-play** across any agent stack. Four plugin axes:
2225

23-
| Axis | Role | Examples |
26+
| Axis | Role | Shipped adapters |
2427
|---|---|---|
25-
| `HarnessAdapter` | Run one query on an agent harness → Trajectory | Claude Code, LangChain, custom ReAct |
26-
| `LLMProvider` | Wrap an LLM API for analyst/merger/judge | Anthropic, OpenAI, Gemini, OpenAI-compatible |
27-
| `SkillFormat` | Read/write skills on disk | Anthropic SKILL.md, Claude Code CLAUDE.md, Cline rules |
28-
| `EvidenceAdapter` | Collect raw session signals (semi-online mode) | Claude Code transcripts, LangSmith |
28+
| `HarnessAdapter` | Run one query on an agent harness → `Trajectory` | `ClaudeCodeHarnessAdapter`, `LangChainHarnessAdapter`, `SimpleReActHarness` |
29+
| `LLMProvider` | Wrap one LLM API for analyst/merger/judge | `AnthropicLLMProvider`, `OpenAICompatibleProvider` (covers OpenAI / Gemini / OpenRouter / DeepSeek / Groq / Together / xAI) |
30+
| `SkillFormat` | Read/write skills on disk | `AnthropicSkillFormat` (SKILL.md + resources/) |
31+
| `EvidenceAdapter` | Collect raw session signals for semi-online mode | `ClaudeCodeEvidenceAdapter` (JSONL sessions), `LangChainEvidenceAdapter` (LangSmith runs) |
2932

30-
**API-only.** No GPU required. vLLM and Ollama are optional/community-tier.
33+
**API-only.** No GPU required. All LLMs go through HTTPS endpoints. vLLM and Ollama are optional community-tier.
3134

32-
## Quickstart (not yet functional)
35+
## Quickstart
3336

3437
```bash
35-
pip install -e ".[dev]"
36-
# Phase 1 will add:
37-
# trace2skill evolve --config trace2skill.yaml
38+
git clone https://github.com/Hert4/trace2skill.git
39+
cd trace2skill
40+
pip install -e ".[dev,anthropic,langchain]"
41+
42+
# Set at least one provider key
43+
export ANTHROPIC_API_KEY=sk-ant-...
44+
# or GEMINI_API_KEY / OPENAI_API_KEY / OPENROUTER_API_KEY
45+
46+
# Run the Claude Code example (20 tasks, real claude CLI)
47+
cd examples/02_claude_code_basic
48+
trace2skill evolve --config trace2skill.yaml
49+
```
50+
51+
You'll need the [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) installed + authenticated for example 02. Alternative: wire `LangChainHarnessAdapter` with any `BaseChatModel` — see `trace2skill/harnesses/langchain.py`.
52+
53+
## Minimal Python API
54+
55+
```python
56+
import asyncio
57+
from pathlib import Path
58+
from trace2skill.pipeline import Trace2SkillPipeline
59+
from trace2skill.harnesses import LangChainHarnessAdapter
60+
from trace2skill.llm.openai_compatible import OpenAICompatibleProvider
61+
from trace2skill.skill_formats import AnthropicSkillFormat
62+
from trace2skill.core.models import Task, FileGroundTruth
63+
from langchain_anthropic import ChatAnthropic
64+
65+
llm = OpenAICompatibleProvider(
66+
model="gemini-2.5-pro",
67+
base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
68+
api_key="...", # your Gemini key
69+
)
70+
harness = LangChainHarnessAdapter(llm=ChatAnthropic(model="claude-sonnet-4-6"), tools=[...])
71+
pipeline = Trace2SkillPipeline(
72+
harness=harness,
73+
llm=llm,
74+
skill_format=AnthropicSkillFormat(),
75+
evaluator=MyEvaluator(),
76+
)
77+
78+
tasks = [Task(task_id="t1", query="...", inputs={}, ground_truth=FileGroundTruth(...))]
79+
result = asyncio.run(pipeline.evolve(
80+
tasks=tasks,
81+
skill_dir=Path("./skill-v0"),
82+
workspace_dir=Path("./workspace"),
83+
analyst_modes={"error"}, # paper's +Error condition
84+
))
85+
86+
AnthropicSkillFormat().save(result.skill, Path("./skill-evolved"))
87+
print(f"{len(result.patches)} patches proposed, {result.patches_dropped} dropped")
88+
```
89+
90+
## Pipeline modes
91+
92+
- **Offline batch** (`trace2skill evolve`) — paper-faithful 3 stages, need tasks + ground-truth + evaluator.
93+
- **Semi-online** (`trace2skill evolve-online`) — consume real user sessions via an `EvidenceAdapter`, run from filtered trajectories (skip Stage 1). SessionEnd hook example in `examples/03_claude_code_semi_online/`.
94+
- **Rollback** (`trace2skill rollback`) — atomic swap previous skill version back from timestamped backups.
95+
96+
## Architecture in one diagram
97+
98+
```
99+
┌──────────────────────────────────────────────────────────────┐
100+
│ trace2skill CORE │
101+
│ (harness-agnostic, zero domain logic) │
102+
│ │
103+
│ Stage 1 Rollout → Stage 2 Analyze → Stage 3 Merge │
104+
│ + Signal Layer │
105+
└───┬──────────────┬──────────────┬──────────────┬─────────────┘
106+
│ │ │ │
107+
┌───▼────┐ ┌────▼────┐ ┌────▼────┐ ┌────▼──────┐
108+
│Harness │ │ LLM │ │ Skill │ │ Evidence │
109+
│Adapter │ │Provider │ │ Format │ │ Adapter │
110+
└────────┘ └─────────┘ └─────────┘ └───────────┘
38111
```
39112

113+
Each axis is a `Protocol`. Core never imports any adapter or provider SDK. Users pick-and-mix: `ClaudeCodeHarnessAdapter` + `AnthropicLLMProvider` + `AnthropicSkillFormat`, or `LangChainHarnessAdapter` + `OpenAICompatibleProvider` (Gemini) + `AnthropicSkillFormat`, or any combo.
114+
40115
## Roadmap
41116

42-
See [`plan.md`](./plan.md) for the full 16-week plan. Current progress: Phase 0.
117+
See [`plan.md`](./plan.md) for the 16-week plan. Current progress: Phases 0/1/1.5/2/3/6 done, Phase 4 infra complete (paper-level delta deferred), Phase 5 partial (LangChain shipped, Cline/OpenCode pending), Phase 7 in progress (this README is part of it).
118+
119+
## Development
120+
121+
```bash
122+
pip install -e ".[dev]"
123+
python -m pytest tests/unit -q # 319 tests
124+
ruff check .
125+
pyright --strict trace2skill
126+
```
127+
128+
Adapter contributions are welcome — see `trace2skill/harnesses/langchain.py` and `trace2skill/evidence_adapters/langchain.py` for reference implementations (~200-280 LOC each). Aim for <300 LOC per new adapter.
129+
130+
## Citation
131+
132+
If you use Trace2Skill in research, cite the paper it implements:
133+
134+
```bibtex
135+
@article{trace2skill2026,
136+
title={Trace2Skill: Distill Trajectory-Local Lessons into Transferable Agent Skills},
137+
journal={arXiv preprint arXiv:2603.25158},
138+
year={2026}
139+
}
140+
```
43141

44142
## License
45143

46-
MIT. See [`LICENSE`](./LICENSE).
144+
MIT — see [`LICENSE`](./LICENSE). Built as open source from day one.

0 commit comments

Comments
 (0)