9.0 KiB
Agent-Intent × Agent-Squad × Agent-Native 接入与集成测试报告
日期:2026-09-29;执行:weichen(会话内自动化 + 手工 E2E)。
设计依据:2026-09-29-decoupling-and-llm-layering.md(D1–D7 全部按推荐执行)。
提交组合:Error-Code-System dbeed2f ← Agent-Intent 55780ae ← Agent-Native c659dc1 ← Agent-Squad 6a36308(guidelines 26b562d2 / logging-system 2c5716f 全链一致,各仓一致性脚本全绿)。
一、外挂了什么意图(本报告全部用例共用的意图集)
E2E 与 intentctl 用同一份 JSON 配置(/tmp/squad-intents/intents.json);单测另用等效 Go/MapFS 定义。共 4 条:
| # | 意图 ID | 域 | 触发词(includes_any) | 置信度参数 | 元数据(宿主解释) |
|---|---|---|---|---|---|
| 1 | guard.config_change |
guard(守卫域,Stage 0) | 系统配置 / 网关 / 改密码 | 默认(base 0.7 / threshold 0.6) | risk=high;guidance="系统配置请在管理界面修改,任务入口不受理" |
| 2 | demo.report.competitor |
demo | 竞品 / 对标分析 | base 0.8 / threshold 0.7 | handler=report.competitor;blueprint=competitor_report(定向模板) |
| 3 | demo.greet.hello |
demo | 你好 | 默认 | priority=10(无 blueprint → 命中也不干预) |
| 4 | demo.greet.hi |
demo | 你好 | 默认 | priority=5(与 3 同词同分 → 制造歧义分支) |
配套蓝图(Squad 数据目录):competitor_report,关键词 竞品分析报告(注意:E2E 目标文本不含该关键词),1 步(researcher → output.md)。
二、意图识别层用例(intentctl,纯模块层)
命令:go run ./cmd/intentctl eval -root /tmp/squad-intents /tmp/squad-intents-corpus.json → 5/5 PASS。
| 用例 | 输入 | 识别结果(分支 / Top / 置信度) | 期望 | 判定 |
|---|---|---|---|---|
| guard_refuse | 帮我把系统网关地址改一下 |
guard_hit / guard.config_change / 0.7 |
guard_hit + 该 Top | ✅ |
| route_blueprint | 给我做一份竞品情况的分析报告 |
matched / demo.report.competitor / 0.8(terms=竞品) |
matched + 该 Top | ✅ |
| ambiguous_greet | 你好呀 |
ambiguous(hello 与 hi 同分 0.7,priority 10>5 排序) | ambiguous | ✅ |
| free_fallback | 帮我整理一下这周的会议纪要 |
fallback | fallback(交给原路径) | ✅ |
| hard_negative_excluded | 查询系统状态 |
fallback(无 spec 过阈;守卫词"系统配置"未整词命中) | fallback(不误触) | ✅ |
explain 摘录(route_blueprint 输入):守卫 排除 guard.config_change no_positive_match;规则 命中 demo.report.competitor 0.8000 竞品。
三、Agent-Squad 端到端(真实 CLI,--hitl-mode auto,stub 后端)
四组对照实验,同一数据目录与蓝图,唯一变量是是否 --intent-root /tmp/squad-intents:
| 用例 | 输入(goal) | 外挂意图 | 实际结果 | 期望 | 判定 |
|---|---|---|---|---|---|
| A 守卫拒绝 | 帮我把系统网关地址改一下 |
有 | failed,错误 squad.intent_refused: 命中守卫意图 guard.config_change,exit 1 |
拒绝且带稳定码 | ✅ |
| B 同输入对照 | 同上 | 无 | completed,4 步自主规划,质检 100,exit 0 |
正常执行(证明拒绝只来自外挂意图) | ✅ |
| C 意图定向 | 给我做一份竞品情况的分析报告(不含蓝图关键词) |
有 | completed,1 步(= 蓝图步骤 b1);state.json 记录 task_key=competitor_report、planning_mode=blueprint、intent_id=demo.report.competitor、intent_blueprint=competitor_report |
定向到模板并审计落盘 | ✅ |
| D 同输入对照 | 同上 | 无 | completed,4 步自主规划 |
不定向(证明路由变化来自意图) | ✅ |
| E 自由透传 | 帮我整理一下这周的会议纪要 |
有(不命中) | completed,4 步自主规划,质检 100 |
与无意图行为一致(意图只增不删) | ✅ |
真实输出摘录:
# A(有意图)
▶ 运行 run_20260929T160446.234228623 终态:failed
错误: squad.intent_refused: 命中守卫意图 guard.config_change exit=1
# B(无意图,同文本)
▶ 运行 run_20260929T160446.236881964 终态:completed
步骤 4 个(完成 4/跳过 0/失败 0)。质检得分 100。 exit=0
# C(有意图)
▶ 运行 run_20260929T160453.123945617 终态:completed
步骤 1 个(完成 1/跳过 0/失败 0)。质检得分 100。 exit=0
# D(无意图,同文本)
▶ 运行 run_20260929T160453.126982316 终态:completed
步骤 4 个(完成 4/跳过 0/失败 0)。质检得分 100。 exit=0
四、Agent-Native 装饰器(adapters/intentgate,单测层)
后端为计数 stub;外挂意图与第一节同源(守卫 spec 等效定义):
| 用例 | 外挂意图 | 输入(Prompt) | 识别结果 | 期望 | 判定 |
|---|---|---|---|---|---|
| 零 spec 透传逐字节等价 | 无(零 spec 快照) | 帮我改一下系统网关地址 |
fallback | Wrap 与裸后端 Result 深比较相等;Handler 零触发 | ✅ |
| 守卫拦截不经模型 | guard.config_change | 帮我改一下系统网关地址 |
guard_hit | Handler 收到 GuardHit;返回拒绝合成结果;后端零调用 | ✅ |
| fallback 透传 | 同上 | 写一份周报 |
fallback | 透传,后端恰好 1 次调用 | ✅ |
| Handler 放弃回退 | 同上 | 帮我改一下系统网关地址 |
guard_hit | 透传原后端 | ✅ |
| 组件为 nil 原样返回 | n/a | n/a | n/a | Wrap 返回原后端 | ✅ |
| 识别错误 fail-closed | MaxInputLen=8 | 超长输入 | sys.invalid_argument | 返回错误,后端零调用 | ✅ |
五、自动化测试与解耦证明汇总
| 验证项 | 位置 | 结果 |
|---|---|---|
| 既有全链路契约回归(等价证明) | Agent-Squad conformance |
通过(未改动即过) |
| 零配置等价(nil 闸门 / 零内容闸门 / 无闸门引擎三路对照) | Squad squad + squadintent |
通过 |
| 守卫拒绝稳定码 / 蓝图缺失 fail-closed / 闸门错误 fail-closed / TaskKey 旁路 | Squad squad 引擎级 |
通过 |
| 适配器→引擎→蓝图→执行→质检全链路(含 -race) | Squad squadintent.TestEngineEndToEndWithAdapterGate |
通过 |
结构断言:go list -deps ./squad ./server ./store 与 Native 核心 |
两仓 | agent-intent 0 命中 |
| submodule 一致性(Squad 8 项比对 / Native 4 项 / Agent-Intent 3 项) | 各仓脚本 | 全绿 |
全仓 go vet + go test -count=1(三仓)+ 关键包 -race |
三仓 | 全绿 |
六、结论与回退
- 结论:Squad(引擎级闸门)与 Native(Backend 装饰器)均以 T1 形态接入;未配置意图时行为与原实现一致(T0 已由测试与对照实验双重证明);守卫拒绝与配置失败均 fail-closed 且带稳定码。
- 回退:各仓删除对应适配器包 + 接线 + submodule(清单见各仓 docs/records 采纳记录),核心包零改动。
过程记录:Agent-Squad docs/records/2026-09-29-intent-gate-adoption.md;Agent-Native docs/records/2026-09-29-intentgate-adoption.md。
七、追加轮:目录驱动的编排(E2/E4 + G3–G5,组合 AI 3674dc4 ← N 292142a ← S 5454f74)
本轮外挂意图在第一节基础上新增 demo.run.status_query(必填槽 run_id:pattern run-\d+、label 运行编号、提问建议"要查询哪个运行?请提供 run 编号")。
| 用例 | 输入 / 场景 | 实际结果 | 期望 | 判定 |
|---|---|---|---|---|
| 槽位归一+校验链 | 查询任务 RUN-42 的进度 |
slot run_id 归一为 run-42,通过自定义 validator |
抽取→归一→校验链生效 | ✅ |
| 槽位非法区分 | 查询任务 42 的进度 |
InvalidSlots[run_id]="validator: 须以 run- 开头",不进 Missing |
"给错了"与"没给"分离 | ✅ |
| 枚举/格式校验 | 环境: dev 日期: 明天 |
env 枚举不合法、date 格式不合法,均进 InvalidSlots | 确定性校验 | ✅ |
| 目录渲染 | intentctl catalog | 目录含能力/必填槽位/提问建议;守卫 spec 不出现 | 规划者可消费 | ✅ |
| LLM 规划器/leader 提示词 | buildPrompt/leaderPrompt | 目录与提问建议注入;未配置时不出现 | G5 提问模板落地 | ✅ |
| 计划确定性校验 | 缺目录/未知意图/缺必填槽/枚举违规 | 四类全部 fail-closed 拒绝计划(错误含澄清建议) | 防领导幻觉闭环 | ✅ |
| E2E 混合步 F | 做一次混合演示(蓝图=系统功能步+agent 步,EchoRunner) |
completed 2 步:sys1 物化系统功能调用(intent_id/handler/slot 落盘),write1 走 agent 后端 | 系统功能不经智能体 | ✅ |
| E2E fail-closed G | 同输入但未注册 handler | failed:handler "taskrun.query_status" 未注册(fail-closed,不静默降级) |
不静默降级 | ✅ |
三仓 vet/test/-race 全绿;既有 conformance 套件两轮均未改动即通过(等价回归持续成立);核心包 agent-intent 依赖 0 命中;一致性脚本全绿(Squad 8 项比对)。