Files
Sakurasan d5dac5a6fc feat: AutoZero 通用 Agent 框架(从 AutoGo 五阶段拆分完成)
llm(三协议 Provider)/ session(JSONL 持久化)/ tools(Registry、围栏、
builtin、computer)/ cdp(browser)/ skills / mcp / agent(循环、两级压缩、
编排、审批门控)+ 底座 jsonl/textx/execx/diag/scratch/spill/imagecache。

产品装配代码(config 桥接、schedule 工具、memory/plan/retro/prompt)
留在 AutoGo,宿主接入方式见 MIGRATION.md。
2026-10-26 00:54:46 +08:00

144 lines
9.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AutoZero 搬迁清单:从 AutoGo 拆出通用 Agent 框架
> 来源仓库:`~/Code/github/AutoGo`(module `autogo`)。
> 目标:把 `llm / tools / agent` 三层通用能力拆成独立 Go module,
> AutoGo 改为依赖它的第一个宿主;channel / scheduler / webui 等产品功能留在 AutoGo。
> 原则:**不重写,纯搬家**。每搬一层 AutoGo 都能编译、测试全绿。
## 策略(2026-10-26 定)
**AutoGo 处于持续开发阶段,暂不接入 AutoZero**——不做 replace 依赖、不做 shim,
保持自包含。两侧关系是**单向同步**:
- AutoGo 仍是唯一事实源,照常开发;框架包在 AutoGo 侧的改动(bug 修复、新协议、
新工具)由人工择期同步到 AutoZero 对应包。
- AutoZero 以框架视角收口:接入门槛、API 表面、文档是它的验收标准;
产品装配代码(config 桥接、schedule 工具、memory/retro 钩子)不同步进来。
- 等 AutoGo 功能进入稳定期,再按"AutoGo 侧接线"一节做反向依赖,届时 shim 是现成方案。
已完成的阶段 1(llm)即按此模式存在:AutoZero/llm 是 AutoGo internal/llm 去产品化
的镜像(config 桥接函数不进框架)。**同步时以 AutoGo 为准,漂移靠人工对齐。**
## 模块与包布局
```
AutoZero(module git.gopher.ink/mirrors2/AutoZero)
├── llm/ 阶段1 ✅:Provider 抽象 + 三协议实现(零内部依赖)
├── jsonl/ 阶段2 ✅:JSONL 容忍读取(坏行跳过、无行长上限)
├── session/ 阶段2 ✅:JSONL 会话持久化(依赖 llm + jsonl;wsbind 留宿主)
├── textx/ 阶段2 ✅:字符截断工具(tools/agent 的公共依赖)
├── execx/ 阶段2 ✅:命令执行/截断工具
├── tools/ 阶段3 ✅:Registry、Fence、guard、builtin、computer(schedule 留宿主)
├── cdp/ 阶段3 ✅:Chrome DevTools 协议客户端 + browser 工具
├── diag/ 阶段3 ✅:诊断输出(Printf / Indirect)+ 禁直写终端静态检查
├── scratch/ 阶段3 ✅:临时文件目录(~/.autogo/scratch)
├── skills/ 阶段4 ✅:SKILL.md 扫描与解析
├── mcp/ 阶段4 ✅:MCP 客户端(stdio + HTTP)与工具适配
├── spill/ 阶段5 ✅:超长工具结果落盘(~/.autogo/results)
├── imagecache/ 阶段5 ✅:图片落盘缓存(内容 hash → 文件、TTL 清理)
└── agent/ 阶段5 ✅:循环、两级压缩、编排、子 agent、审批/提问(memory/plan/retro/prompt 留宿主)
```
阶段顺序 = 依赖自底向上;每阶段结束 AutoGo `go test ./...` 全绿才算完成。
## 各包迁移映射
### 阶段 1:`llm`(已完成 2026-10-26)
| 内容 | 去向 |
|---|---|
| types / anthropic / openai / responses / retry / image / completion / streamguard 及各自测试 | → `AutoZero/llm/` 原样搬 |
| `provider.go` 通用部分(APIFormat、NormalizeAPIFormat、ProviderSpec、NewProvider、guessFormat、DedupeModels、FilterAllowed、matchesAllowed、MissingRegisteredModels) | → `AutoZero/llm/provider.go` |
| `provider.go` config 部分(SpecFromConfig、NewConfigProvider、currentProvider、specFromProvider、AllowedForCurrent、SwitchableModels) | 留在 AutoGo(见 shim) |
| `provider_test.go` 通用测试(TestFilterAllowed / NormalizeAPIFormat / NewProviderFormats / MissingRegisteredModels / FilterAllowedWildcard) | → `AutoZero/llm/` |
| `provider_test.go` config 测试(TestSpecFromConfigCurrentProvider / SwitchableModels×2 / AllowedForCurrent) | 留在 AutoGo |
AutoGo 侧改造:`internal/llm` 变成 **shim 包**——类型别名 + 函数转发 + 保留 config 桥接函数。
全部调用方零改动;后续包迁移完成后逐包把 `autogo/internal/llm` import 换成新 module,最后删 shim。
### 阶段 2:`session` + `textx` + `execx`(已完成 2026-10-26)
- `textx` / `execx` / `jsonl`:零内部依赖,原样搬(`jsonl` 是 session 的容忍读取
底座,一并进框架)。测试全部随包通过。
- `session`:除 `wsbind.go` / `wsbind_test.go`(工作区绑定,产品功能)外全部搬入;
import 路径改为本 module。**框架侧新增 `session.SetDir`**:覆盖默认的
`~/.autogo/sessions` 布局(宿主自定义存储位置用;AutoGo 侧无此函数,属框架增量)。
- AutoGo 侧零改动。
### 阶段 3:`tools`(已完成 2026-10-26)
- 核心全量搬入:`tools.go / guard.go / builtin.go / edit_match.go / instructions.go /
bashbg.go / fetch.go / websearch.go / vision.go` + 测试;`computer*.go` 三平台
GUI(build tag)一并进框架;`cdp`(browser 工具)整体搬入。
- 随迁底座:`diag`(诊断输出,含"禁直写终端"静态检查测试)、`scratch`(临时目录,
`~/.autogo/scratch` 硬编码与 AutoGo 保持镜像,宿主自定义需求出现时再加覆盖入口)。
- **接口增量**:`snapshot.Change` 内联为 `tools.Change`,`Snapshotter` 签名改为
`Record(Change)`——留档/回退(Store/Plan/Restore)是产品功能留在 AutoGo,宿主
接入时写一个几行的适配器把 `tools.Change` 转成自己的留档记录。
- **留在 AutoGo**:`schedule.go` / `schedule_test.go`(依赖 scheduler 引擎)。
- 第三方依赖与 AutoGo 对齐:`coder/websocket v1.8.15`、`imroc/req/v3 v3.61.0`、
`golang.org/x/net v0.57.0`。
- AutoGo 侧零改动。
### 阶段 4:`skills` + `mcp`(已完成 2026-10-26)
- `skills`(SKILL.md 扫描与 frontmatter 解析)零产品依赖,仅引用 textx,原样搬。
- `mcp`(手写 JSON-RPC 2.0 客户端,stdio + HTTP 两种传输,server 工具 →
Registry 适配)依赖 diag/execx/tools,全部已迁入,原样搬。
- AutoGo 侧零改动,测试全部随包通过。
### 阶段 5:`agent`(已完成 2026-10-26,框架五阶段收敛完成)
**随迁**:循环与门控全量(agent / context / subagent / skill / ask / askuser /
dangerous / anomaly / toolfail / continue / model_routing / checkpoint / secrets
及 34 个测试文件)+ 底座 `spill`(超长结果落盘,`~/.autogo/results` 与 AutoGo
保持镜像)、`imagecache`(图片落盘缓存,零依赖)。
**留在 AutoGo 的产品文件**(宿主接入时经钩子挂回):
| 文件 | 接回方式 |
|---|---|
| `memory.go`(memory 工具 + MemorySection) | 工具进 Registry 由宿主注册;注入段经 `Agent.ExtraSections` |
| `plan.go`(plan 工具 + PlanSection,含 Agent 上的 plan 状态) | 状态挪宿主侧(工具闭包自持),注入段同走 `ExtraSections` |
| `retro.go`(复盘记录 + SelfAssess) | 经 `OnTurnEnd(TurnReport)` 取数(byTurnCap/Steps/GoalIndex 已给全) |
| `prompt.go`(SystemPrompt:品牌名/项目探测/git 快照) | 宿主组装 `Agent.System`;通用注入(AGENTS.md/子树指令/放弃分支)已在框架 |
| `checkpoint.go`(git checkpoint)/ `occupy`(工作区占用) | 经 `Options.Occupy`/`Release` 钩子(占用行为测试已随框架迁移) |
| `failfields_test.go` / `turnend_test.go` / `memory_test.go` / `plan_test.go` / `retro_test.go` / `prompt_test.go` | 随对应产品文件留宿主 |
**框架相对 AutoGo 的接口增量**(均为超集,AutoGo 接入时按此适配):
1. `OnTurnEnd` 签名 `func(err error)` → `func(TurnReport)`:复盘需要的
byTurnCap / Steps / GoalIndex / Started 一次给全。
2. `Agent.ExtraSections func() string`:DynamicSections 的宿主扩展点(原
PlanSection+MemorySection 的位置);框架自有段(放弃分支说明、子树指令)不变。
3. 回合结果常量 `Outcome*`(completed/failed/stopped/max_turns)入框架 agent 包,
**取值与 AutoGo retro 包一致**(session 文件格式跨两端兼容);Agent 结构体
移除 `Memory` / `plan` / `PlanPath` 产品字段(`ImgCache` 保留,imagecache 随迁)。
4. 测试脚手架 `stubProvider` 入框架 `helpers_test.go`(AutoGo 侧同名定义随
retro_test.go 留宿主);`turn_end_test` / `occupy_test` 按 TurnReport 适配。
5. `MaxTurns` 默认值 40 保持镜像;`~/.autogo` 系路径(spill/scratch/sessions)
与 AutoGo 保持镜像,宿主自定义入口按需再加(session.SetDir 先行)。
## AutoGo 侧接线(接入期才执行,当前暂缓)
AutoGo 进入稳定期、决定接入框架时,每阶段按相同模式操作:
1. `go.mod`:`require git.gopher.ink/mirrors2/AutoZero v0.0.0` + `replace ... => ../AutoZero`(开发期本地路径)。
2. 原 `internal/<pkg>` 改为 shim:`type X = az.X`、`func X(...) = 转发`,产品桥接代码留下。
3. 调用方零改动;稳定后再逐包替换 import 路径,shim 退役。
## 关键设计约束(随包走,写进各包 doc.go)
1. **配对不变量**:transcript 中每个 tool_use 必须有配对 tool_result(含合成 is_error),`synthMissingToolResults` 兜底不得拆。
2. **transcript 不可变**:压缩/截断/图片驱逐只在视图层(contextView),Session 是唯一事实源。
3. **fail-closed 默认**:Tool 零值 = 有副作用 + 不可并发;忘标注时行为必须保守。
4. **截断只有一个口径**:正文一律 `textx.ClipBytes`(字节预算)/ `ClipRunes`(个数),禁止裸切 `s[:n]`。
5. **零重依赖**:框架层(llm/session/skills)不新增任何第三方依赖;协议层手写。
## 决策点(已定 / 待定)
1. computer / browser 进框架(阶段 3 已落实:computer 入 tools,cdp 独立包)。
2. 框架 config → 框架只定义 `ProviderSpec` 等纯值类型,配置装载归宿主(阶段 1 已落实)。
3. 开发期用 `replace` 指向本地路径,稳定后切 git tag(随 AutoGo 接入期一起执行)。
4. 框架名 AutoZero,module 路径 `git.gopher.ink/mirrors2/AutoZero`(与 AutoGo 同源托管)。