diff --git a/.doc/ops/CURRENT.md b/.doc/ops/CURRENT.md index 90f922a9..ab7dde29 100644 --- a/.doc/ops/CURRENT.md +++ b/.doc/ops/CURRENT.md @@ -18,6 +18,7 @@ | owner | task | branch | worktree | mutex | status | |---|---|---|---|---|---| +| Cursor | agent-reply-llm-narrative-2026-09-28 | feature/agent-reply-llm-narrative-2026-09-28 | .worktrees/agent-reply-llm-narrative-2026-09-28 | chat+coordinator | in_progress | | Cursor | error-events-pg-roundtrip-2026-09-28 | feature/error-events-pg-roundtrip-2026-09-28 | .worktrees/error-events-pg-roundtrip-2026-09-28 | error-events-pg-evidence | done | | Cursor | error-code-observability-2026-09-28 | feature/error-code-observability-2026-09-28 | .worktrees/error-code-observability-2026-09-28 | error-code-observability | done | | Cursor | attachment-only-turn-2026-09-28 | fix/attachment-only-turn-2026-09-28 | .worktrees/attachment-only-turn-2026-09-28 | attachment-only-turn | done | diff --git a/.doc/ops/short-term/2026-09-28-agent-reply-llm-narrative.md b/.doc/ops/short-term/2026-09-28-agent-reply-llm-narrative.md new file mode 100644 index 00000000..afd22758 --- /dev/null +++ b/.doc/ops/short-term/2026-09-28-agent-reply-llm-narrative.md @@ -0,0 +1,71 @@ +--- +title: "助手回复智能体叙述优先" +task_id: "agent-reply-llm-narrative-2026-09-28" +status: in_progress +created: 2026-09-28 +updated: 2026-09-28 +owner: Cursor +task_type: implementation +task_tier: multi_stage +policy_revision: "agent-governance-2026-09-21-r1 @ 8f77053f5169502eaf3e4e4135a082e8914f3704" +branch: feature/agent-reply-llm-narrative-2026-09-28 +worktree: .worktrees/agent-reply-llm-narrative-2026-09-28 +base_dev_sha: "8f77053f5169502eaf3e4e4135a082e8914f3704" +write_scope: ["internal/coordinator", ".doc"] +allowed_environments: ["dev"] +head_sha: "" +mutex: "chat+coordinator" +review_state: pending +integration_state: pending +deployment: pending +cleanup: pending +cleanup_owner: "独立维护者" +cleanup_trigger: "dev 合入且验收证据落盘后复查 worktree" +remote_sync: not_requested +--- + +# 助手回复智能体叙述优先 + +## 用户目标与授权 + +- 用户目标:助手回复尽可能由智能体生成,减少模板直答。授权来自本会话「实施助手回复智能化改造方案」。 +- 交付终点:T1/T2 叙述与 T3 结果通报走 PI Agent,失败回退模板;T4 安全话术保持模板;单测与 dev 真实 Runner 证据落盘后合入 local dev。 +- 禁止项:不 push、不晋升 test/main、不改确认卡结构与权限拒绝话术。 +- 例外:注册本任务前,`integrate-attachment-only-turn-2026-09-28` 以 scope `.` 仍为 active,但其分支已是当时 dev 祖先且队列为空。已将其 task state 记为 done 以解除 same_scope 硬门禁。未删除其 worktree。 + +## 范围与非目标 + +- 允许写入:`internal/coordinator` 叙述管道与意图 handler;本任务记录与测试报告。 +- 非目标:不改交互卡、挂起期望、澄清追问、权限不足与安全拦截文案的生成路径;不替换 `templates/docs` 交付物模板。 + +## 相关问题与经验 + +- issue_ids:无对应未关闭问题。 +- 开工检索 ISSUES / lessons INDEX(模板回复、答非所问、reply_source):无命中可复用条目。 +- 不新增 lesson:本次是既有「LLM 优先、模板兜底」机制的扩展,尚未出现新的复发机制。 + +## 步骤与验收 + +1. [x] 统一 `narrateReply` / `applyNarrative`,事实块进入提示词,开关 `AGENT_REPLY_LLM_ENABLED`。 +2. [x] T1 查询、T2 帮助、T3 已受理/已完成通报接入;确认提问与权限拒绝不接入。 +3. [x] `go test -short ./...`、`go vet`、`arch-check --mode block`,以及 `RUN_PI_E2E=1` 的真实 Runner 叙述用例。验收见 [测试报告](../../test-reports/2026-09-28-agent-reply-llm-narrative-test-report.md)。 + +按 [验证契约](../2026-09-21-validation-contract.md):Go 单测 + 产品 PI 受影响链路。 + +## 验证与证据 + +| 范围 / 被测 SHA | 命令与环境 | 预期 | 实际 / 判定 | 证据 / 脱敏说明 | +|---|---|---|---|---| +| coordinator 单测与全量 short | `go test -short ./...`;`arch-check --mode block`;`go vet ./...` | PASS | PASS | 见测试报告 | +| 真实 Runner T1/T2/T3 | `RUN_PI_E2E=1 go test -run TestIntentReply_RealPI`,模型 MiniMax-M2.7-highspeed | reply_source=pi-agent | PASS(26.90s) | [测试报告](../../test-reports/2026-09-28-agent-reply-llm-narrative-test-report.md);未记录 token | + +## 收口与交接 + +- 剩余工作:真实 Runner 证据、合入 local dev。 +- 本地提交 / dev 集成 / 部署 / 远端:尚未提交。 +- cleanup:合入后由独立维护者复查。 +- 需求目录:`R-agent-reply-llm-narrative`。 + +## 相关链接 + +- 方案:助手回复智能化改造(LLM 叙述优先、模板兜底) diff --git a/.doc/test-reports/2026-09-28-agent-reply-llm-narrative-test-report.md b/.doc/test-reports/2026-09-28-agent-reply-llm-narrative-test-report.md new file mode 100644 index 00000000..7c5dc84e --- /dev/null +++ b/.doc/test-reports/2026-09-28-agent-reply-llm-narrative-test-report.md @@ -0,0 +1,83 @@ +# 助手回复智能体叙述 测试报告 + +## 一、 测试背景 (Background) + +项目助手大量查询、帮助和操作回执仍由 Go 硬编码模板直接返回。本轮把这些路径改为:系统先生成确定性事实底稿,再由产品 PI Agent Runner 组织自然语言;Runner 失败、开关关闭或无 backend 时回退原模板。安全拦截、权限不足和确认提问不进入叙述。 + +## 二、 测试目标 (Test Objectives) + +- T1 权责查询、T2 能力帮助、T3 暂缓回执由真实 Runner 生成,`reply_source=pi-agent`,且保留底稿中的人名、文档名或项目名。 +- Runner 失败时回退模板,并记录 `agent_reply_fallback`。 +- 开关关闭时不调用 backend。 +- 安全拦截话术不被叙述改写。 +- 存量 `go test -short ./...` 与 `arch-check --mode block` 通过。 + +## 三、 测试方案与环境 (Test Plan & Environment) + +- OS:Linux。Go 模块测试在任务 worktree `feature/agent-reply-llm-narrative-2026-09-28`,基线 dev `8f77053f5169502eaf3e4e4135a082e8914f3704`。 +- 真实 Runner:宿主机 `http://127.0.0.1:18865/health` 返回 200。模型按本机批准配置 `PI_AGENT_PROVIDER=minimax`、`PI_AGENT_MODEL=MiniMax-M2.7-highspeed`。凭证只从本机 `.env` 读取,不写入报告。 +- 层级:Go 单测(scripted backend)+ 受影响产品 PI 链路(`RUN_PI_E2E=1`)。未跑 nightly 五项全量,因为本变更不改工作流生成链。 + +## 四、 预期结果 (Expected Results) + +- 有 backend 且开关开启:`ReplySource=pi-agent`,提示词含「系统确定性底稿」。 +- backend 返回失败:`ReplySource=template`,正文仍含模板标题「我能帮您做什么」。 +- `AGENT_REPLY_LLM` 测试开关关闭:不调用 backend。 +- `SECURITY_FORBIDDEN`:正文不含脚本注入的智能体改写句。 +- 真实 Runner 三轮均 `source=pi-agent`,且分别保留「张工/用户需求表」「查询/补充」「肌骨超声项目」。 + +## 五、 实际测试结果与判定 (Actual Results & Evaluation) + +### 用例 1:真实 Runner T1/T2/T3 + +- **测试输入 (Input)**:`RUN_PI_E2E=1 go test -count=1 -timeout 8m -v ./internal/coordinator/ -run TestIntentReply_RealPI_NarratesQueryHelpAndDecline` +- **实际输出 (Actual Output)**: + +```text +intent=QUERY_USER_RIGHTS source=pi-agent duration=8.919s +intent=HELP_CAPABILITIES source=pi-agent duration=11.655s +intent=DECLINE_EXPECTATION source=pi-agent duration=6.329s +--- PASS: TestIntentReply_RealPI_NarratesQueryHelpAndDecline (26.90s) +``` + +权责回复含「张工」与「用户需求表」;帮助回复含「查询项目进展与风险」「补充项目事实」,并保留「请前往项目设置界面」;暂缓回复含「肌骨超声项目暂不推进」。路由日志里的 `channel=TEMPLATE` 是 R0 意图通道名,不是回复来源;回复来源字段为 `pi-agent`。 + +- **评价判定**:PASS +- **性能与耗时**:三轮合计 26.90s(8.919s / 11.655s / 6.329s) + +### 用例 2:backend 失败回退模板 + +- **测试输入**:`go test -short -v -run TestIntentReply_BackendFailureFallsBackToTemplate` +- **实际输出**: + +```text +INFO agent_reply_fallback handler=handleHelpCapabilities intent=HELP_CAPABILITIES reason="forced failure" +--- PASS: TestIntentReply_BackendFailureFallsBackToTemplate (0.00s) +``` + +- **评价判定**:PASS +- **性能与耗时**:<1s(scripted backend,非真实 Runner) + +### 用例 3:开关关闭与安全话术 + +- **测试输入**:`TestIntentReply_FlagOffKeepsTemplate`、`TestIntentReply_SecurityForbiddenStaysTemplate` +- **实际输出**:两者 PASS。安全用例未调用 dialogue backend。 +- **评价判定**:PASS +- **性能与耗时**:<1s + +## 六、 自动化测试套件汇总 (Test Suite Execution) + +| 检查 | 结果 | +|---|---| +| `./scripts/arch-check.sh --mode block` | PASS(production gate passed) | +| `go vet ./...` | PASS(exit 0) | +| `go test -short -count=1 -timeout 8m ./...` | PASS(含 `internal/coordinator` 0.042s、`internal/server` 20.498s) | +| `RUN_PI_E2E=1` 叙述三轮 | PASS(26.90s) | + +未运行 nightly 全量五项。不把未运行记为产品全链路 PASS。 + +## 七、 测试结论与后续优化建议 (Conclusion & Next Steps) + +授权范围内的叙述改造达到本轮验收:真实 Runner 能在保留确定性事实的前提下改写查询、帮助和暂缓回执;失败与安全边界仍走模板。 + +后续可观察线上 `agent_reply_fallback` 比例,再决定是否把仍保持模板的确认提问也改为叙述。确认卡选项与权限拒绝本轮故意不改。