diff --git a/PROGRESS.md b/PROGRESS.md index ee662a3..dc1ca73 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -2,7 +2,7 @@ > 配合 `DESIGN.md`。本文件只记 phase 状态、决策偏差、文件量、下一步。每条 1-2 句:做了啥 + 关键判断;细节查 `git log` / `git diff` / `DESIGN §7.9`。 -最后更新:2026-05-27(ppt skill description 收紧路由,避免 "生成方案" 被误命中) +最后更新:2026-05-27(ppt skill 歧义反问 + general_v1 加"产物形式歧义先问"通用原则) --- @@ -23,6 +23,7 @@ ### 2026-05-27 +- **ppt skill 歧义反问 + general_v1 加"产物形式歧义先问"通用原则**:上次 8109f20 把 ppt description 收紧成"白名单 + 反例"后,实测"MES**汇报方案**"这种请求还是被路由命中 —— 反例列表只覆盖"生成方案 / 写报告 / 出文档 / 做纪要"几个组合,但"汇报方案"未列入,而"汇报"在 LLM 语义里就有强烈的 PPT 联想重力(工作汇报 / 季度汇报多以幻灯片形式)足以压过"必须明确点名 PPT"的硬约束。**修法**:① `skills/ppt/SKILL.md:3` description 改三段(✅触发白名单 / ⛔不触发[只留明确指向文档的"报告 / 文档 / 纪要"] / ⚠️ 歧义先反问)—— 把"汇报 / 方案 / 材料"从反例摘出来,改成"先反问用户'PPT 还是 Word/Markdown 文档'再决定 load",把判断权还给用户而不是赌 LLM 路由词典;② `prompts/system/general_v1.md` Skill 机制段加一条系统级原则"产物形式歧义时先问",升格为跨 skill 通用约束(imagegen / videogen 各自 skill 内本来就有"问清楚再画"逻辑,现在抽到 system prompt 让新加 skill 也能继承)。**否决**:(a) 继续往反例里堆"汇报方案 / 汇报材料 / 汇报内容"—— 堆词典治标不治本,下次"做个 Q4 总结"又得加;(b) 路由层加 `required_keywords` 结构化字段,在 discovery_block 之前 grep 用户原话兜底 —— 跨多 skill 都得补字段,工程量大,短期 LLM 反问范式收益已够;(c) ppt skill load 后再反问 —— 路由命中后再反问就是已经误触发了,要在路由阶段拦。代价:用户已经心里清楚要 PPT 只是没说时,会觉得多一轮反问啰嗦;缓解靠反问句式短 + 暗示默认选项,一个字"PPT"就能过,比生成完整 deck 后推翻代价小一个数量级。`DESIGN.md` 不动(无架构变化);`RUN.md` 不动(纯 skill 元数据 + system prompt 文案)。 - **ppt skill description 收紧路由**:`skills/ppt/SKILL.md:3` 原文 "做汇报 PPT、把材料/会议纪要/方案转为幻灯片、生成演示稿" 含 "方案" / "生成" 字样,Claude 路由时把 "生成一个方案" 也命中到 PPT skill。改成显式白名单(PPT/幻灯片/演示文稿/.pptx/slide/deck)+ 显式反例("生成方案 / 写报告 / 出文档 / 做纪要" 不触发 —— 那是文档任务)。`DESIGN.md` 不动;`RUN.md` 不动(纯 skill 元数据)。 - **skill 热更新:`/v1/skills` 每次现扫**:此前 `web/app.py` lifespan 启动时 `app.state.skill_registry = SkillRegistry(...)` 扫一次,`GET /v1/skills` 从这份静态快照读 → 加新 skill 目录(放到 `skills//SKILL.md`)必须重启 web 才能在 dev SPA 新建任务弹窗下拉看见,为未来"允许用户安装自己 skill"埋了一刀。改法:删 lifespan 那行 + 注释,`/v1/skills` 路由内每次 `SkillRegistry(ROOT / cfg["skills_dir"])` 现扫。实测 SkillRegistry 构造 ~3ms / 次(9 个 skill,iterdir + 9 次 read_text + yaml frontmatter),整个 HTTP e2e ~20ms 完全淹没在 JWT + DB 噪声里,且 `/v1/skills` 只在"新建任务弹窗打开"触发,非热路径。**`core/agent_builder.py::build_agent` 早已是每次新建 SkillRegistry**(每发新消息重扫),所以 agent 内部 `load_skill` 工具与 system prompt discovery block 一直是热的;此次仅修补前端下拉这一处静态快照。Smoke 验证:`skills/_smoke_hot_reload/SKILL.md` 临时创建 → `/v1/skills` 9→10 看见、删除 → 10→9 消失,全程未重启进程。否决:(a) 加 `POST /v1/skills/reload` 显式触发 —— 多 API + 用户得记得调,3ms / 次的优化收益为 0;(b) watchdog 文件系统监听 —— 加依赖 + 容器 bind mount inotify 偶尔不稳 + 工程量过重,与方案 A 在用户体感上无差异;(c) `SkillRegistry` 加 mtime cache —— 智能化复杂度换 ms 级 IO 节省,§7.9 "不为不存在的瓶颈预付架构成本"同款判定。**未来"用户自带 skill"独立维度**(届时 `workspace/users//.skills/` 与全局 `skills/` 多 root 叠加),跟当前热更新不耦合,等真做时再加多 root 支持。`DESIGN.md` 不动(无架构变化);`RUN.md` 不动(无 CLI / env 变化)。 - **dev SPA 「导出对话记录」/「清空对话」按钮 disable 逻辑改成只要选中 task 就常亮**:`web/static/dev.html` `renderChatMeta` 里原本按 `t.n_messages === 0` 一并禁用两键(`:1812`/`:1815`)。bug:用户「清空对话」→ `clearMessages` 返回 `n_messages=0` → 两键 disable;之后发新消息走 SSE 流(`sendMessage` `:2210`),后端 task.n_messages 累加但前端 `state.taskMeta.n_messages` 没刷,renderChatMeta 也不会再跑,两键一直灰。改法:不按 n_messages 门禁,导出常亮、清空仅在 run running/cancelling 期间禁(后端 409,confirm 后再报错 UX 差);0 条时点导出生成空 docx、点清空 confirm 显 0 条 —— 都不会出错,语义一致更省心。`deleteTask` 路径里把"无 task 选中时两键显式 disable"逻辑保留(那时 chat-meta 退到"未选中任务"占位,常亮反而误导)。否决:(a) 修真正的 n_messages 同步问题(SSE 收 done 时回拉 taskMeta) —— 一次额外 GET,且 streaming 期间频繁拉一致性更易飘;(b) 把 export 也按 running 禁 —— export 是只读快照,run 中导出当前可见的部分对话完全合理。`DESIGN.md` 不动(无架构变化);`RUN.md` 不动(无 CLI/env 变化)。 diff --git a/prompts/system/general_v1.md b/prompts/system/general_v1.md index cb60bef..80acd3d 100644 --- a/prompts/system/general_v1.md +++ b/prompts/system/general_v1.md @@ -23,6 +23,8 @@ 简单问答、读代码、改 bug、文件操作这类通用任务,直接用通用工具就够,不必为每个 任务硬套 skill。一旦决定要用,**不要凭印象推测**怎么用 —— load 一下。 +**产物形式歧义时先问**:用户请求里产物**内容**清楚了、但**形式**(PPT / 文档 / 视频 / 图)还模糊时(只说"汇报 / 方案 / 材料 / 报告"等通用词、没明确说成品形式),先用一句话反问确认形式,再决定 load 哪个 skill。例:用户说"做一个 XX 汇报方案",反问"要做成 PPT 演示稿,还是 Word/Markdown 文档?"。歧义反问的代价 ≪ 误选 skill 后整份产物推翻的代价。 + ## 工作原则 - 动手前先看: 用 read/grep/glob 摸清现状,再 edit - 改动最小化: edit 工具的 old_str 必须唯一匹配,不够唯一就多带上下文 diff --git a/skills/ppt/SKILL.md b/skills/ppt/SKILL.md index ca60999..ea43a57 100644 --- a/skills/ppt/SKILL.md +++ b/skills/ppt/SKILL.md @@ -1,6 +1,6 @@ --- name: ppt -description: 生成 PowerPoint 演示文稿 (.pptx) 文件。**仅当**用户明确点名 PPT / 幻灯片 / 演示文稿 / .pptx / slide / deck 之一时才用。⛔ 不要触发:用户只说"生成方案 / 写报告 / 出文档 / 做纪要"而没明确要 PPT 形式 —— 那是文档任务,不是 PPT 任务。 +description: 生成 PowerPoint 演示文稿 (.pptx) 文件。✅ 触发:用户明确点名 PPT / 幻灯片 / 演示文稿 / .pptx / slide / deck 之一。⛔ 不触发:用户明确说要"报告 / 文档 / 纪要"等指向纯文档形式的产物。⚠️ 歧义先反问:用户说"汇报 / 方案 / 材料"等产物形态不明的词、且没说成品形式时,不要直接 load 本 skill 也不要假定走文档,先反问一句"这份要做成 PPT 演示稿,还是 Word/Markdown 文档?" 用户确认 PPT 后再 load。 --- # PPT