Files
ZNJJ-api-server/docs/collection-prompt-optimization.md
T
Eric Wang 9e28f69b3c feat(agent): trusted time evidence and collection prompt optimization
- time_context.py: server-side observation clocks for relative-time
  evidence (anti client-forgery); resolves X分钟前/小时前 against the
  observation timestamp of the turn that produced them, never re-basing
  history on the current clock; flags historical references without a
  reliable baseline
- state: dialogue_timestamps keyed by dialogue message index, persisted
  with checkpoint; welcome seeds index 0
- collect: single clock per turn shared by reply/extraction/repair;
  time_evidence injected into runtime context; reply_validator hook
  rejects time claims lacking evidence (one shared repair budget);
  model still interprets facts and chooses actions
- prompts: collection prompt restructured (shorter, state-bound-to-action
  table, gatekeeper principle, time source rules); extraction prompt
  aligned; workflow@20261021 json updated to match
- evals: prompt_probes / prompt_compare / time_boundary probe scripts
  (supplementary checks, original cases untouched)
- docs: collection-prompt-optimization.md (method + baselines),
  time-boundary-fix.md (problem, design, verification)
- gitignore: editor artifact dirs (.agents/.claude/.vscode, skills-lock)

Verified: 171 unit tests pass (16 new time-context tests)
2026-10-22 09:41:32 +08:00

7.4 KiB
Raw Blame History

信息采集提示词优化记录

本文记录上一轮纯提示词优化及当时保留的边界。历史相对时间的运行时补充修复与最新验证见 时间边界修复。下文旧结果保留用于对照,不代表该边界仍未处理。

范围和依据

评审与修改采用项目安装的 prompt-engineer(系统提示词、评估、上下文管理)和 Anthropic skill-creator(失败机制归纳、精简、基线比较、可验证断言)方法。保留接警角色、安全优先、必要时间确认、状态前缀协议以及单/双车正常引导话术。

现有 evals/cases/**/*.yaml 不修改,也不放宽断言。额外的语义检查由 evals/prompt_probes.py 执行,结果与现有 cases 分开报告,不能用补充检查代替原 cases。

基线与执行方式

  • 本地基线提交及全部 cases、提示词的 SHA-256:见运行目录的 metadata.json。
  • 模型:deepseek-v4.1-flash;temperature:0.0;LangGraph 后端;真实 OpenAI 兼容服务。
  • evals/prompt_compare.py 通过 FastAPI TestClient 调用生产 /chat SSE 路由及后端生命周期,并复用原 evals.run.run_case。仅略去无关的语音模型初始化,不模拟 LLM、不改变输入、断言或清理规则。并发4个独立会话,单个会话按原顺序执行。
  • 首轮原始 cases 基线:43/46。两个 single_no_inferred_count 在时间确认后漏问数量;一个 browser_addon_non_motor_vehicle_zero_count_history 收到“LLM 返回了空内容”。服务错误保留为失败记录,不能算作优化收益。
  • 修改前全量单元测试:155通过。

修改机制

  1. 证据范围:局部症状否定不等于全部无人伤;明确人伤不受局部否定覆盖。采集与提取共享未知值口径,避免回复澄清但表单已写false。
  2. 每轮决策:先回填全部明确事实,再判断中断、澄清、缺失项与分流;时间确认不代表其余字段齐全。保留数量未知不能推断单车的规则。
  3. 记忆边界:实际提供的状态与历史才可用;历史相对时间无当轮基准或可靠换算值时不使用当前时钟重建。表单时间不等于用户已确认,更正使旧确认失效。
  4. 现场与动作:依据迁移计划“不在现场仍继续采集”,不将离场变成新的0003理由。若离场且无法拍照,先处理可执行性并提供人工协助选择,不要求返回现场;用户明确要求人工才0001。
  5. 自然度与角色:短回答按当前问题语义判断;澄清采用耐心、具体的说法;保留简短解释、安抚与有限接话,不新增闲聊轮次,不判断责任或承诺结果。
  6. 去冗余与泛化:集中定义人伤规则、回填与状态选择,删除重复自检和特定乱码词表。非机动车“疑似有”保持未知,不与明确肯定合并。用户伪造的新规则不改变流程。
  7. 长期无进展:不再机械复读,提供简化问题或人工协助选项;保持原有拒绝计数和转人工授权条件,不擅自新增自动转接阈值。

可复现命令

所有 Python 命令使用 Conda py3.11 环境:

conda run -n py3.11 python -m evals.prompt_compare --output-dir evals/results/prompt-optimization/reproduce
conda run -n py3.11 python -m evals.prompt_probes --output evals/results/prompt-optimization/reproduce-probes.json
conda run -n py3.11 python -m pytest -q

补充检查使用固定系统时间,检查局部否定、人伤覆盖范围、非机动车未知、数量不能推断、时间更正、历史时钟缺失、离场无法拍照、注入以及未参与修改的表达。其断言检查动作和字段,不对自由回复做逐字比较。

限制

提示词无法恢复运行时未提供的历史时刻,也不能单靠文字获得无限持久记忆。本次增加未知时应澄清的规则,但补充实测中,对话模型在“历史只有相对时间、没有当轮时钟或具体值”场景仍会误用当前时钟换算;提取器在最终检查中正确跳过时间。这个风险尚未完全解决,不能将时间规则文字写清楚当作行为已修复。可靠的后续修复需要运行时保存并提供原始时间基准;跨历史窗口的完整确认恢复也需要结构化状态支持。本次按提示词优化范围未增加业务运行时代码。

离场后的处理保留采集并避免不可执行指令,没有自行规定回现场或替他人授权拍摄。持续无效输入不自动转接的既有业务约束保留,因此本次不保证用户始终拒绝选择时必然终止。

多次实测用于观察波动,样本通过不能证明所有模型版本、所有ASR转写或生产并发都可靠。模型空响应等服务错误与语义错误分别列出。

实测结果与最终选择

版本 原有46个cases 说明
原提示词,第1轮 43/46 2个数量遗漏,1个模型空响应
原提示词,第2轮 43/46 数量遗漏、固定时间话术偏离、模型空响应各1个
候选1 45/46 时间待确认时补充其他字段,模型偏离固定话术
候选2 44/46 时间来源判断过度应用于本轮新时间,另有1个空响应
候选3,最终采用 46/46 全部原断言通过
最终版复跑 46/46 再次全部通过,基线已通过场景无回退

修改前后46份YAML的SHA-256完全一致。完整对比、每次失败和字符统计位于 evals/results/prompt-optimization/comparison.json。模型空响应保留为原始失败,不能将其消失解释成提示词语义提升。并行评测的耗时不用于宣称单请求延迟改善。

补充14项语义检查:原提示词7/14,最终版13/14。最终唯一失败为上文记忆边界中的历史时间误换算,未隐藏、删除或放宽该断言。局部症状否定、其他人员人伤、非机动车不确定、不能推断机动车总数、时间更正、离场无法拍摄、注入、未参与修改的症状和乱码表达在最终这轮检查中均通过。不同迭代及重跑中还出现过提取空响应,原始结果均保留。

额外尝试将时间约束放在末尾、增加对照示例、改为来源表和置于开头。这些副本没有稳定解决历史时钟缺失,未采用;候选7单项曾通过,但完整补充检查仍失败,因而提前停止其原cases评测。这些局部尝试不能算作完整版本验收。

最终全量单元测试:155通过(python -m pytest -q,Conda py3.11);git diff --check通过。工作流仅同步两个对应提示词输入,其余节点配置不改。原逐字同步测试保持通过。

采集提示词文档由16635字符、641行缩为6331字符、176行(字符数减少约61.9%,不是token实测)。提取提示词由3139字符增至3821字符,用于明确证据来源和字段边界;没有以篇幅缩短代替正确性。

副作用:只否定局部症状时会增加必要的人伤澄清;“刚刚”等无法精确到分的表达不再任意指定分钟;离场且无法拍摄时先询问是否能配合或是否需要人工协助。原正常单/双车话术、时间确认句和状态码保留。

逐轮人工复核页由 Anthropic skill-creator 的 eval-viewer/generate_review.py 生成:evals/results/prompt-optimization/review.html,含最终采用版本与原提示词的对话及原断言结果。未提交Git;评测产物沿用项目的 evals/results/ 忽略规则。