- docs/ai-context/agent-button-system.md: 新建,agent 按钮体系完整设计文档(四层体系 + 载体选择 + 自验失败降级) - docs/templates/agents-meta-rules.md: v1.1.0,新增 Agent 按钮体系章节 + Acceptance 写法规范(可分发) - .blueprint/CONVENTIONS.md: 新增 Acceptance 写法规范章节(引用 agent-button-system.md) - AGENTS.md: ONBOARDING_MANAGED 块补充炼境自己的 Agent 按钮清单 + 自验失败降级约定
7.4 KiB
| version | updated | usage |
|---|---|---|
| 1.0.0 | 2026-07-03 | 炼境 agent 按钮体系的完整设计文档,供 Claude 理解体系全貌和设计意图;也是分发给子项目的方针来源 |
Agent 按钮体系
炼境的核心设计理念:让 AI agent 具备无人值守执行能力的工程基础设施。
核心命题
功能只有一份实现,但有两种投影:UI 按钮是给人的,agent 按钮是同一个功能给 AI agent 的投影。 当 agent 按钮完备,验证环路就能在 agent 内部闭合,人不再是执行链的瓶颈。
双投影设计
功能本体(单一实现)
├── UI 按钮 → 人操作
└── agent 按钮 → agent 调用
├── 可发现(agent 知道它存在)
├── 可调用(结构化接口)
└── 边界清晰(调的是同一条路径,不是捷径)
"调同一条路径"是关键:agent 走的验证路径和人走的一致,终验才有意义。
分工重构
没有 agent 按钮时,人卡在验证环节,成为执行链瓶颈:
人定目标 → agent执行 → 人验证 → 人反馈 → ...(人是瓶颈)
有了 agent 按钮后,中间的验证环路在 agent 内部闭合:
人定目标 → agent执行 → agent自验(走agent按钮) → 人终验
人只保留两件事:
- 需求澄清(目标定义权)
- 目标验收(终验权)
人在目标层,agent 在执行层,层间边界清晰,各自自洽。
四层体系
意图层 — AGENTS.md
声明方针 + agent 按钮清单。agent 进来第一件事:知道这个项目有哪些 agent 按钮可以调用。
执行层 — agent 按钮本体
按项目类型就近选择载体:
| 项目类型 | agent 按钮载体 |
|---|---|
| Web 服务 | HTTP API(前端按钮与 curl 调同一 endpoint,天然双投影) |
| CLI/脚本 | 命令与 npm scripts |
| 桌面应用 | 测试直接调用 command 函数 |
| UI 呈现层 | Playwright(最后手段,仅关键路径) |
验证层 — acceptance + 可执行断言
acceptance 是 agent 自验的唯一判断依据,必须是可执行断言:
❌ "功能正常运行"(描述性,agent 无法执行)
❌ "代码正确"(主观,无可执行路径)
✅ "pnpm typecheck 无报错"
✅ "cargo test 通过(src-tauri/)"
✅ "MCP tool list_projects 返回新增项目名"
✅ "pnpm test import-project 全绿"
最小结构:<可执行命令> + <通过标准> = 一条合格的 acceptance。
验证层的触发机制,按优先级(模型无关性递减):
| 机制 | 触发时机 | 模型无关 |
|---|---|---|
| git hooks(lefthook) | commit 时 | ✅ 最强 |
| CI/CD(Gitea Actions) | push 后 | ✅ |
| .claude/settings.json hooks | Claude Code 专属 | ❌ |
| AGENTS.md 约定 | 靠 agent 主动调用 | 语言约束 |
.claude/settings.jsonhooks 是 Claude Code 专属的,Cursor / Qwen 等其他工具不会读这个文件。模型无关的验证层靠 git hooks + CI,不能靠 Claude 专属配置。
持久层 — 目标持久化
让 agent 跨会话续接,不靠对话记忆:
- 炼境项目:蓝图(
.blueprint/) - 子项目完整接入:随炼境分发的蓝图规范
- 子项目最小接入:
.agent/task.md
蓝图在体系里的三个角色:
- 目标的结构化载体 — 把自然语言目标翻译成带 acceptance 的可执行任务卡
- 跨会话共享状态 — agent 跨对话续接的记忆
- 自验的判断依据 — acceptance 字段告诉 agent "走到什么状态算通过"
消费者驱动验证
普通应用的验证在自身边界内,一个角色(实现者)够用。
当产品的产出要被"圈外"消费时(工具、平台、SDK、炼境这类跨 APP 产品),验证必须出圈,天然产生两个角色:
实现者角色 → "我跑通了"(项目内部视角)
消费者角色 → "你的产出我真的能用"(圈外消费视角)
两个角色博弈,才能覆盖完整目标。
判断是否需要双角色:你的产出,有没有圈外消费者?
| 产品类型 | 消费者在哪 | 需要几个角色 |
|---|---|---|
| 普通业务应用 | 圈内(用户即使用者) | 1 个 |
| SDK / 工具 / 平台 | 圈外(其他项目) | 2 个 |
| 炼境 | 圈外(被管理的子项目) | 2 个 |
验证边界要跟着目标边界走,不是跟着实现边界走。
炼境的双角色示例:
- 实现者角色:炼境开发角度(导入新项目、跑通接入包分发流程)
- 消费者角色:被管理项目角度(接入包能否真的在子项目里用起来)
三条设计原则
辩证结论,缺一会让体系在现实中碎裂。
原则一:无人值守 ≠ 消灭人工介入
人工介入是设计内的降级路径,不是体系失败。体系的目标是把人从"执行路径"移到"降级路径"。
自验失败降级约定:
- 失败 2 次内:自行修正,继续自验
- 失败 3 次:停止执行,输出以下内容后等待人工介入:
- 失败原因(具体报错或不通过的断言)
- 已尝试的修正路径
- 需要人决策的具体问题
原则二:框架由炼境保证,内容由子项目填
炼境能分发的是结构(AGENTS.md 模板、蓝图规范、lefthook、CI 配置),不能替子项目实现 agent 按钮。
分发的最高价值物是 acceptance 写法规范——让子项目知道怎么写才算可执行断言,而不是描述性语句。
原则三:acceptance 是体系的核心关节
体系其他部分都能降级,acceptance 不能将就。acceptance 写得可执行,自验才是真自验;写得模糊,整个环路是假闭合,无人值守名存实亡。
炼境自己的 Agent 按钮清单
| 能力 | 调用方式 | 通过标准 |
|---|---|---|
| TypeScript 类型检查 | pnpm typecheck |
无输出,exit 0 |
| 前端单元测试 | pnpm test |
exit 0,无 FAILED |
| Rust 单元测试 | cargo test(src-tauri/ 目录) |
无 FAILED |
| MCP 工具调用 | 见 src-tauri/src/mcp_tools.rs 工具列表(21 个工具) |
返回 JSON,无 error 字段 |
| 蓝图状态读取 | 读 .blueprint/manifest.yaml |
文件可解析,字段完整 |
| 蓝图状态更新 | 编辑 .blueprint/modules/<id>.md |
文件写入成功,格式合法 |
分发给子项目的方案
完整接入(长期项目推荐)
接入包
├── AGENTS.md 模板 ← 含方针 + 按钮清单占位 + 降级约定
├── .blueprint/CONVENTIONS.md ← 含 acceptance 写法规范
├── lefthook.yml ← git hooks(模型无关验证层)
└── .gitea/workflows/ci.yml ← CI/CD(模型无关验证层)
最小接入(轻量项目)
接入包
├── AGENTS.md 模板 ← 含方针 + 降级约定
├── .agent/task.md 模板 ← 最小目标持久化(跨会话续接)
└── lefthook.yml ← 最小验证层
.agent/task.md 格式:
## 当前目标
<人填写>
## Acceptance
- <可执行断言 1>
- <可执行断言 2>
## 状态
in_progress / blocked / done
## 阻塞原因(blocked 时填)
自验失败 N 次,具体问题:<描述>
需要人决策:<具体问题>
子项目只需填入:
- AGENTS.md 里 agent 按钮清单的具体命令
- 任务卡 acceptance 字段的可执行断言