Files
smartmate/backend/newAgent/HANDOFF_粗排修复与Prompt重构.md
LoveLosita 07d307fe07 Version: 0.9.4.dev.260407
后端:
1.粗排结果/预览语义修复(task_item suggested 保真 + existing/嵌入识别补全)
- 更新conv/schedule_state.go:LoadScheduleState 补齐 event.rel_id / schedules.embedded_task_id / task_item.embedded_time 三种“已落位”信号;嵌入任务强制 existing + 继承 host slots;补充 task_item duration/name/slot helper;Diff 相关英文注释改中文
- 更新conv/schedule_preview.go:预览层新增 shouldMarkSuggestedInPreview,pending 任务与 source=task_item 的建议态任务统一输出 suggested
2.newAgent 状态快照增强(ScheduleState/OriginalScheduleState 跨轮恢复)
- 更新model/state_store.go:AgentStateSnapshot 新增 ScheduleState / OriginalScheduleState
- 更新model/graph_run_state.go:AgentGraphRunInput/AgentGraphState 接入两份 schedule 状态;恢复旧快照时自动补 original clone
- 更新service/agentsvc/agent_newagent.go:loadOrCreateRuntimeState 返回并恢复 schedule/original;runNewAgentGraph 透传到 graph
- 更新node/agent_nodes.go:saveAgentState 一并保存 schedule/original 到 Redis 快照 3.Execute 链路纠偏(只写内存不落库 + 完整打点 + 恢复消息去重)
- 更新node/execute.go:AlwaysExecute/confirm resume 路径取消 PersistScheduleChanges,仅保留内存写;新增 execute LLM 完整上下文日志;新增工具调用前后 state 摘要日志;thinking 模式改为 enabled
- 更新node/chat.go:pending resume 不再重复写入同一轮 user message
- 更新service/agentsvc/agent_newagent.go:新增 deliver preview write/state 摘要日志,便于排查 suggested 丢失问题
4.AlwaysExecute 贯通 Plan→Graph→Execute
- 更新node/plan.go:PlanNodeInput 新增 AlwaysExecute;plan_done 后支持自动确认直接进入执行
- 更新graph/common_graph.go:branchAfterPlan 支持 PhaseExecuting/PhaseDone 分支
5.排课上下文补强(显式注入 task_class_ids,减少 Execute 误 ask_user)
- 更新prompt/execute.go:Plan/ReAct 两种 execute prompt 都显式写入任务类 ID,声明“上下文已完整,无需追问”
- 更新node/rough_build.go:粗排完成 pinned block 显式标注任务类 ID,避免 Execute 找不到 ID 来源
6.流式输出与预览调试工具修复
- 更新stream/emitter.go:保留换行,修复 pseudo stream 分片后文本黏连/双换行问题
- 更新infra/schedule_preview_viewer.html:升级预览工具,支持 candidate_plans / hybrid_entries

前端:无
仓库:
1.更新了infra内的html,适应了获取日程接口
2026-04-07 21:13:59 +08:00

12 KiB
Raw Blame History

Handoff

以下内容可直接交给下一位助理继续做。

目标

当前有两条主线要继续推进:

  1. 粗排算法修复与链路纠偏
    目标:粗排完成后,不应该再把 LLM 引导到“手动一个个 place 补洞”。如果粗排后仍有 pending,按当前业务理解,这属于异常,应直接终止并报错,而不是继续优化或补排。

  2. execute 上下文瘦身 + 可插拔 prompt 重构
    目标:把现在的“消息流水账堆砌”改成“结构化执行简报”,并且 prompt 不能写死成排程专用,要能复用于排程、加任务、学习计划等不同任务域。

用户已经明确确认的业务结论

  • always_execute、后端是否自动放行、是否写库,这些是后端执行层语义,不应写进 prompt。
  • LLM 只需要按统一协议产出 continue / confirm / ask_user / done / abort 这类动作;后端怎么处理是后端自己的事。
  • 对排程场景LLM 的主要职责是“粗排后的优化器”,不是“粗排补洞工”。
  • 如果“粗排完成后仍有 pending 任务”,这不是要让 LLM 手工 place 的正常状态,而是异常状态。
  • prompt 需要明显的文字引导,必须有编号和子编号,让 LLM 每轮都收到一份规范文本。
  • prompt 必须是可插拔的,不能写死成“排程优化”专用。

已经完成的改动

  • 已修复“同一轮 user message 重复写入上下文”的问题。
    实现位置:backend/newAgent/node/chat.go
    改动点:handleChatResume 不再重复 AppendHistory(schema.UserMessage(...)),现在 user message 只在 service 层统一写入一次。

  • 已经给 execute 节点加了完整上下文调试打点。
    实现位置:backend/newAgent/node/execute.go
    关键函数:formatExecuteLLMMessagesForDebug

  • 之前已经做过一轮粗排结果接入修复:makeRoughBuildFunc 改为使用 HybridScheduleWithPlanMultiFuncentries 结果,而不是只看 []TaskClassItem
    实现位置:backend/service/agentsvc/agent_newagent.go

当前上下文链路的真实现状

execute 真正喂给 LLM 的消息来自:

  • backend/newAgent/node/execute.go
  • backend/newAgent/prompt/execute.go
  • backend/newAgent/prompt/base.go

当前拼装顺序是:

  • system:基础 persona + execute 阶段规则
  • system:工具摘要
  • history:完整历史消息
  • systempinned blocks
  • user:运行时执行提示词

这套链路的核心问题不是“少了什么”,而是“保留了太多不该保留的东西”。

已确认的上下文膨胀问题

基于用户提供的第 13 轮上下文样本,当前冗余主要有这些:

  • 大型 tool result 长期保留。
    典型是 get_overviewlist_tasksfind_free 的超长结果被反复塞进 history。

  • 同工具同参数的重复查询长期保留。
    例如 find_free(duration=2) 连续多次查询,主体内容几乎相同;list_tasks(all)get_overview 也重复大量信息。

  • 大量 assistant 过程性话术进入 history。
    例如“我先查一下”“我需要先获取”“我将安排……请确认”这类文本,对后续决策价值很低,却持续吃 token。

  • 失败回合被原样保留。
    例如 placetask_idfind_freeduration 的失败记录,不需要完整原文链路,只需要摘要化保留“最近失败模式”。

  • 指令层重复。
    renderStateSummary、pinned blocks、运行时 user prompt 存在明显重叠。

  • newAgent 目前没有接旧链路那套历史 token budget 裁剪。
    对照位置:

    • 新链路:backend/service/agentsvc/agent_newagent.go
    • 旧链路:backend/service/agentsvc/agent.go
    • token budget 工具:backend/pkg/token_budget.go

当前排程链路里最需要纠偏的错误引导

当前这段逻辑已经不符合用户现在确认的业务前提:

  • backend/newAgent/node/rough_build.go

这里现在会在粗排后写入一段 pinned 文本,大意是:

  • 如果还有 pending,就让 LLM 去 get_overview/find_free/place
  • 重复 place直到 pending 归零

这段引导现在应视为错误业务语义。下一位助理需要重点改掉它。

粗排算法主线的交接意见

下一位助理要继续查两件事:

  • 粗排算法本体是否真的仍会漏排。
    重点排查:

    • makeRoughBuildFunc
    • RunRoughBuildNode
    • placements 写入 ScheduleState 后,是否所有目标任务都应有初始落位
  • 如果业务上“粗排不应漏排”已经成立,那么链路要改成:

    • 粗排完成且 pending > 0:直接异常结束
    • 不再把 LLM 引导成“手工补排”
    • 最好在执行层支持 abort 语义,而不是让模型继续乱试

prompt 重构主线的交接意见

用户已经认可的新方向是:把 prompt 改成“通用执行内核 + 可插拔领域模块 + 当前任务简报”。

推荐的 3-message 结构如下。

第一条消息:通用执行内核

职责:

  • 定义 agent 身份
  • 定义通用规则
  • 定义通用动作协议
  • 提供最小必要的 JSON 示例

第二条消息:领域模块

职责:

  • 注入当前领域名称、职责边界、目标、非目标
  • 注入领域工具简表
  • 注入领域硬约束、软目标
  • 注入异常定义与完成判定

第三条消息:运行时任务简报

职责:

  • 给出用户原始目标与最新补充
  • 给出当前实例级约束
  • 给出最新状态快照
  • 给出最近操作摘要
  • 给出上一次工具调用结果
  • 给出本轮目标

用户已经认可的 prompt 设计原则

  • 必须保留 JSON 示例,否则 LLM 容易不会按协议输出。
  • prompt 必须有显式编号和子编号,例如 1. / 1.1 / 2.1
  • prompt 不能写死成排程专用。
  • 排程只是一个领域模块示例,不是通用内核的一部分。
  • 对排程领域来说,应明确:
    • 这是“粗排后的优化器”
    • 不是“补排器”
    • pending > 0 是异常条件,不是待办事项
  • 对不同领域,应通过占位参数注入,不要把具体业务写进通用层。

已产出的可插拔 prompt 方案要点

建议最终落地成这三层:

通用执行内核

  • 身份
  • 通用规则
  • 通用动作协议
  • 输出字段定义
  • 最小 JSON 示例

领域模块

  • domain_name
  • task_type
  • domain_primary_responsibility
  • domain_out_of_scope
  • domain_goals
  • domain_non_goals
  • tool_catalog_brief
  • tool_usage_rules
  • tool_required_args_rules
  • tool_common_failures
  • hard_constraints
  • soft_objectives
  • abort_conditions
  • abort_handling_rules
  • done_conditions
  • abort_output_conditions

运行时任务简报

  • original_user_goal
  • latest_user_instruction
  • current_effective_goal
  • current_phase
  • current_round
  • instance_constraints
  • latest_state_summary
  • latest_state_delta
  • latest_risks
  • recent_operation_summary
  • recent_failure_patterns
  • last_tool_name
  • last_tool_arguments_summary
  • last_tool_result_summary
  • last_tool_success
  • last_tool_state_change
  • last_tool_takeaway
  • current_round_goal
  • recommended_next_action

排程领域的具体模块语义

如果当前领域是“粗排后的排程优化”,建议这样填:

  • domain_name = schedule_optimization
  • domain_primary_responsibility = 在粗排结果基础上优化排程质量
  • domain_out_of_scope = 手工补排粗排遗漏任务
  • domain_goals = 更均匀、更符合学习规律、更平衡每日负载
  • domain_non_goals = 把 pending 任务一个个 place 进去
  • abort_conditions = 粗排完成后仍有 pending 任务
  • abort_handling_rules = 不再继续优化,不再 place直接 abort
  • done_conditions = 方案满足硬约束且整体分布合理

代码层建议的实施顺序

建议下一位助理按这个顺序做,风险最低:

  1. 先改粗排后 pinned 引导
    重点文件:backend/newAgent/node/rough_build.go
    目标删掉“pending 继续 place”的提示换成“pending 是异常”的提示。

  2. 再补 abort 动作语义
    重点文件:

  • backend/newAgent/node/execute.go
  • 相关 decision model 定义文件
  • 可能涉及 deliver / graph 分支
    目标:让 LLM 可以正规地终止异常流程,而不是只能 continue / done / ask_user / confirm。
  1. 再做 prompt 结构重构
    重点文件:
  • backend/newAgent/prompt/base.go
  • backend/newAgent/prompt/execute.go
  • 如有必要,可新增一个领域模块文件
    目标把目前“system/tool/history/pinned/runtime prompt”重组为“通用内核 + 领域模块 + 任务简报”。
  1. 最后再做历史瘦身
    目标:
  • 同工具同参数结果只保留最近一份原文
  • 更早历史改摘要
  • assistant 废话不入 history
  • 失败模式摘要化
  • 必要时接入 token budget

关于历史瘦身,已达成的结论

下一位助理可以直接照这个原则做:

  • 不再把几十条 assistant/tool 原始流水账直接喂给模型
  • 把历史改成“状态快照 + 最近摘要 + 上一次结果 + 本轮目标”
  • tool result 只保留:
    • 最新一条原文
    • 更早的同类结果摘要
  • 重复查询要压缩:
    • 同工具同参数只保留最新一条
  • assistant 过程话术要剔除:
    • “我先查一下”“我将继续……”之类原则上不入模型历史
  • 保留最近失败模式:
    • 例如 placetask_id
    • 例如 find_freeduration

测试与验证注意事项

  • 运行 go test 后,必须清理项目根目录 .gocache
  • 当前环境可能会因为网络限制导致 go test 拉依赖失败;之前已经出现过这种情况。
  • 项目要求:
    • 注释、接口文案、说明、评审反馈都用中文
    • 文件编码 UTF-8无 BOM
    • 不要把 agent 改回写库逻辑;当前用户明确要求 agent 操作只写内存,不写数据库
  • 代码中若改动复杂逻辑,注释要同步更新,且注释必须用中文

关键文件清单

  • 执行节点与上下文打点:backend/newAgent/node/execute.go
  • prompt 拼装基础:backend/newAgent/prompt/base.go
  • execute promptbackend/newAgent/prompt/execute.go
  • 粗排节点:backend/newAgent/node/rough_build.go
  • graph 节点装配:backend/newAgent/node/agent_nodes.go
  • newAgent service 入口:backend/service/agentsvc/agent_newagent.go
  • 旧链路 token budget 参考:backend/service/agentsvc/agent.go
  • token budget 工具:backend/pkg/token_budget.go

一句话总结给下一位助理

当前要做的,不是继续 patch 某个 prompt 文案,而是同时完成两件事:

  • 把“粗排后 pending 还让 LLM 手工补排”的错误业务语义彻底清掉
  • execute 从“消息流水账喂模”重构成“通用执行内核 + 可插拔领域模块 + 运行时任务简报”的结构化 prompt

TODO Checklist

粗排算法与异常语义

  • 确认粗排算法本体是否真的会漏排
  • 确认 placements 写入 ScheduleState 后是否所有目标任务都已有初始落位
  • 删除 rough_build 节点里“pending 继续 place”的错误提示
  • 改成“粗排后 pending > 0 即异常”的提示语义
  • 在执行决策层补齐 abort 动作语义

Prompt 重构

  • 抽出通用执行内核 prompt
  • 抽出领域模块 prompt
  • 抽出运行时任务简报拼装逻辑
  • 保留最小必要 JSON 示例
  • 清除后端执行层语义对 LLM 的干扰
  • 让排程领域以模块方式接入,而不是写死在内核

历史瘦身

  • 同工具同参数仅保留最新一条原文
  • 更早同类结果改为摘要
  • assistant 过程性废话不再进入模型历史
  • 最近失败模式摘要化保留
  • 必要时接入 token budget