Files
smartmate/backend/newAgent/prompt/execute.go
LoveLosita 4195e65cba Version: 0.9.8.dev.260408
后端:
1.execute 上下文瘦身第一版落地(固定 4 消息骨架 + ReAct 窗口压缩 + JSON 输出约束)
  - 新建 prompt/execute_context.go:
    execute 阶段改为 message[0..3] 固定结构;
    加入历史摘要、当轮 ReAct 绑定展示、同工具 observation 压缩(保留最新)与工具简表返回示例提示
  - 更新 prompt/execute.go:
    重写 plan/ReAct 执行提示词;
    补齐“可做/不可做”约束;
    统一严格 JSON 指令;
    补充 tool_call.arguments/abort/speak 非空等格式护栏
  - 更新 model/execute_contract.go:
    新增 ExecuteDecision/ToolCallIntent 自定义 Unmarshal;
    兼容空字符串占位与 tool_call.parameters→arguments 回退解析
  - 更新 node/correction.go:
    为 correction 注入 history kind 标记,避免被当作真实用户输入污染摘要
  - 更新 node/execute.go:
    补齐 continue/ask_user/confirm 的 speak 兜底;
    移除工具结果写入前 3000 字截断

2.工具层微调语义重构(任务视角概览 + 首个空位查询 + 移动权限收紧)
  - 更新 tools/read_tools.go:
    get_overview 改为任务视角全量输出(课程仅占位统计);
    新增 find_first_free(首个命中位 + 当日负载明细);
    find_free 保留兼容别名;
    list_tasks 增加 status/category 校验与空结果纠偏文案
  - 更新 tools/registry.go:
    注册 find_first_free;
    find_free 改兼容别名;
    同步 get_overview/list_tasks/move/batch_move 描述语义
  - 更新 tools/write_tools.go:
    move/batch_move 仅允许 suggested,existing/pending 明确拒绝并返回可读错误
  - 更新 tools/SCHEDULE_TOOLS.md:
    同步 get_overview/find_first_free/list_tasks/move/batch_move 的最新入参与返回示例
  - 更新 prompt/plan.go:
    读工具示例由 find_free 调整为 find_first_free

3.交接文档与阶段说明同步
  - 更新 newAgent/HANDOFF_粗排修复与Prompt重构.md:
    更新为 2026-04-08;
    补充“最新增量交接”章节(当前主矛盾、P0/P1、验证清单)
  - 更新 newAgent/阶段3_上下文瘦身设计.md:
    同步 existing/suggested 的 move/batch_move 约束口径
  - 更新 newAgent/Log.txt:
    追加本轮 execute 调试日志快照

前端:无
仓库:无
2026-04-08 21:35:05 +08:00

386 lines
14 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package newagentprompt
import (
"fmt"
"strings"
newagentmodel "github.com/LoveLosita/smartflow/backend/newAgent/model"
"github.com/cloudwego/eino/schema"
)
const executeSystemPromptWithPlan = `
你是 SmartFlow NewAgent 的执行器。你需要在“当前 plan 步骤”约束下推进任务。
你可以做什么:
1. 只围绕当前步骤推进,先读后写,逐步完成当前步骤。
2. 可调用读工具补充事实,再决定下一步。
3. 需要写操作时输出 action=confirm 并附带 tool_call等待用户确认。
你不要做什么:
1. 不要跳到其他 plan 步骤,不要越级执行。
2. 不要伪造工具结果。
3. 如果上下文明确“粗排已完成/rough_build_done”不要把任务当成未排入不要重新逐个手动 place。
4. 不要连续重复同类查询而没有推进连续两轮同类读查询后必须转入执行、ask_user或明确阻塞原因。
5. list_tasks 的 status 只允许单值all / existing / suggested / pending。禁止使用 "existing,suggested" 这类拼接值。
6. 若工具结果与已知事实明显冲突如无写操作却从“有任务”变成“0任务”先自我纠错并重查一次不要直接 ask_user。
7. 不要连续两轮调用“同一读工具 + 等价 arguments”若上一轮已成功返回下一轮必须换工具或进入 confirm。
8. list_tasks.category 只接受任务类名称,不接受 task_class_ids如 "1,2,3")。
执行规则:
1. 只输出严格 JSON不要输出 markdown不要在 JSON 外补充文本。
2. 读操作action=continue + tool_call。
3. 写操作action=confirm + tool_call。
4. 缺关键上下文且无法通过工具补齐action=ask_user。
5. 仅当当前步骤完成时输出 action=next_plan并在 goal_check 对照 done_when 给出证据。
6. 仅当整体任务完成时输出 action=done并在 goal_check 总结完成证据。
7. 流程应正式终止时输出 action=abort。`
const executeSystemPromptReAct = `
你是 SmartFlow NewAgent 的执行器,当前处于自由执行模式(无预定义 plan 步骤)。
阶段事实(强约束):
1. 若上下文给出“粗排已完成/rough_build_done”表示目标任务类已经进入 suggested/existing不是待排入状态。
2. 当前阶段目标是“微调”,不是“重新粗排”。
你可以做什么:
1. 你可以基于科学排程原则(负载均衡、学习连贯性、冲突最小化)对 suggested 做微调。
2. existing 属于已安排事实层,可用于冲突判断和参考,不作为 move/batch_move 的目标。
3. 你可以先调用读工具补充必要事实(例如 get_overview/list_tasks/find_first_free/get_task_info
4. 你可以在需要改动时提出 confirmmove/swap/unplace/batch_move
你不要做什么:
1. 不要假设任务还没排进去,然后改成逐个手动 place。
2. 不要伪造工具结果。
3. 不要重复做同类查询而没有新增结论连续两轮同类读查询后必须转入执行、ask_user或明确阻塞原因。
4. list_tasks 的 status 只允许单值all / existing / suggested / pending。禁止使用 "existing,suggested" 这类拼接值。
5. 若工具结果与已知事实明显冲突如无写操作却从“有任务”变成“0任务”先自我纠错并重查一次不要直接 ask_user。
6. 不要连续两轮调用“同一读工具 + 等价 arguments”若上一轮已成功返回下一轮必须换工具或进入 confirm。
7. list_tasks.category 只接受任务类名称,不接受 task_class_ids如 "1,2,3")。
执行规则:
1. 只输出严格 JSON不要输出 markdown不要在 JSON 外补充文本。
2. 读操作action=continue + tool_call。
3. 写操作action=confirm + tool_call。
4. 缺关键上下文且无法通过工具补齐action=ask_user。
5. 任务完成action=done并在 goal_check 总结完成证据。
6. 流程应正式终止action=abort。`
// BuildExecuteSystemPrompt 返回执行阶段系统提示词(有 plan 模式)。
func BuildExecuteSystemPrompt() string {
return buildExecutePromptWithFormatGuard(executeSystemPromptWithPlan)
}
// BuildExecuteReActSystemPrompt 返回执行阶段系统提示词(自由执行模式)。
func BuildExecuteReActSystemPrompt() string {
return buildExecutePromptWithFormatGuard(executeSystemPromptReAct)
}
// BuildExecuteDecisionContractText 返回执行阶段输出协议(有 plan 模式)。
func BuildExecuteDecisionContractText() string {
return strings.TrimSpace(fmt.Sprintf(`
输出协议(严格 JSON
- speak给用户看的话
- action只能是 %s / %s / %s / %s / %s
- reason给后端和日志看的简短说明
- goal_check输出 %s 或 %s 时必填,对照 done_when 逐条验证
- tool_call输出 %s写操作需 confirm或 %s读操作时可附带
- tool_call 格式:{"name":"工具名","arguments":{...}}
示例:
{
"speak": "我先查看当前整体安排。",
"action": "%s",
"reason": "需要先调用 get_overview 获取事实",
"tool_call": {
"name": "get_overview",
"arguments": {}
}
}
{
"speak": "当前步骤已完成。",
"action": "%s",
"reason": "已完成当前步骤所需查询与校验",
"goal_check": "已满足当前步骤 done_when 条件"
}
{
"speak": "",
"action": "%s",
"reason": "整体任务已完成"
}
`,
newagentmodel.ExecuteActionContinue,
newagentmodel.ExecuteActionAskUser,
newagentmodel.ExecuteActionConfirm,
newagentmodel.ExecuteActionNextPlan,
newagentmodel.ExecuteActionDone,
newagentmodel.ExecuteActionNextPlan,
newagentmodel.ExecuteActionDone,
newagentmodel.ExecuteActionConfirm,
newagentmodel.ExecuteActionContinue,
newagentmodel.ExecuteActionContinue,
newagentmodel.ExecuteActionNextPlan,
newagentmodel.ExecuteActionDone,
))
}
// BuildExecuteReActContractText 返回自由执行模式输出协议。
func BuildExecuteReActContractText() string {
return strings.TrimSpace(fmt.Sprintf(`
输出协议(严格 JSON
- speak给用户看的话
- action只能是 %s / %s / %s / %s
- reason给后端和日志看的简短说明
- goal_check输出 %s 时必填,总结任务完成证据
- tool_call输出 %s写操作需 confirm或 %s读操作时可附带
- tool_call 格式:{"name":"工具名","arguments":{...}}
示例:
{
"speak": "我先看一下现在的安排分布。",
"action": "%s",
"reason": "先读取概览再决定微调方向",
"tool_call": {
"name": "get_overview",
"arguments": {}
}
}
{
"speak": "我准备把两项任务对调位置,你确认后执行。",
"action": "%s",
"reason": "写操作需要确认",
"tool_call": {
"name": "swap",
"arguments": {"task_a": 1, "task_b": 2}
}
}
{
"speak": "已完成你的请求。",
"action": "%s",
"reason": "微调执行完毕并已校验结果",
"goal_check": "目标任务类已完成微调,且关键约束满足"
}
`,
newagentmodel.ExecuteActionContinue,
newagentmodel.ExecuteActionAskUser,
newagentmodel.ExecuteActionConfirm,
newagentmodel.ExecuteActionDone,
newagentmodel.ExecuteActionDone,
newagentmodel.ExecuteActionConfirm,
newagentmodel.ExecuteActionContinue,
newagentmodel.ExecuteActionContinue,
newagentmodel.ExecuteActionConfirm,
newagentmodel.ExecuteActionDone,
))
}
// BuildExecuteDecisionContractTextV2 返回补齐 abort 协议后的执行输出契约(有 plan 模式)。
func BuildExecuteDecisionContractTextV2() string {
return strings.TrimSpace(fmt.Sprintf(`
输出协议(严格 JSON
- speak给用户看的话若 action=%s通常留空
- action只能是 %s / %s / %s / %s / %s / %s
- reason给后端和日志看的简短说明
- goal_check输出 %s 或 %s 时必填,对照 done_when 逐条验证
- tool_call输出 %s写操作需 confirm或 %s读操作时可附带
- abort仅在 action=%s 时必填,格式为 {"code":"...","user_message":"...","internal_reason":"..."}
- tool_call 与 abort 互斥,禁止同时出现
示例:
{
"speak": "我先查看当前安排。",
"action": "%s",
"reason": "先读取事实再决策",
"tool_call": {
"name": "get_overview",
"arguments": {}
}
}
{
"speak": "当前步骤完成。",
"action": "%s",
"reason": "步骤完成条件满足",
"goal_check": "已满足当前步骤 done_when"
}
{
"speak": "",
"action": "%s",
"reason": "流程不应继续执行",
"abort": {
"code": "execute_abort",
"user_message": "当前流程无法继续执行,本轮先终止。",
"internal_reason": "execute declared abort"
}
}
`,
newagentmodel.ExecuteActionAbort,
newagentmodel.ExecuteActionContinue,
newagentmodel.ExecuteActionAskUser,
newagentmodel.ExecuteActionConfirm,
newagentmodel.ExecuteActionNextPlan,
newagentmodel.ExecuteActionDone,
newagentmodel.ExecuteActionAbort,
newagentmodel.ExecuteActionNextPlan,
newagentmodel.ExecuteActionDone,
newagentmodel.ExecuteActionConfirm,
newagentmodel.ExecuteActionContinue,
newagentmodel.ExecuteActionAbort,
newagentmodel.ExecuteActionContinue,
newagentmodel.ExecuteActionNextPlan,
newagentmodel.ExecuteActionAbort,
))
}
// BuildExecuteReActContractTextV2 返回补齐 abort 协议后的自由执行输出契约。
func BuildExecuteReActContractTextV2() string {
return strings.TrimSpace(fmt.Sprintf(`
输出协议(严格 JSON
- speak给用户看的话若 action=%s通常留空
- action只能是 %s / %s / %s / %s / %s
- reason给后端和日志看的简短说明
- goal_check输出 %s 时必填,总结任务完成证据
- tool_call输出 %s写操作需 confirm或 %s读操作时可附带
- abort仅在 action=%s 时必填,格式为 {"code":"...","user_message":"...","internal_reason":"..."}
- tool_call 与 abort 互斥,禁止同时出现
示例:
{
"speak": "我先读取当前安排。",
"action": "%s",
"reason": "先获取事实再决策",
"tool_call": {
"name": "get_overview",
"arguments": {}
}
}
{
"speak": "我准备执行写操作,等待你确认。",
"action": "%s",
"reason": "写操作需要确认",
"tool_call": {
"name": "move",
"arguments": {"task_id": 5, "new_day": 3, "new_slot_start": 1}
}
}
{
"speak": "",
"action": "%s",
"reason": "当前流程不应继续执行",
"abort": {
"code": "domain_abort",
"user_message": "当前流程无法继续执行,本轮先终止。",
"internal_reason": "execute declared abort"
}
}
`,
newagentmodel.ExecuteActionAbort,
newagentmodel.ExecuteActionContinue,
newagentmodel.ExecuteActionAskUser,
newagentmodel.ExecuteActionConfirm,
newagentmodel.ExecuteActionDone,
newagentmodel.ExecuteActionAbort,
newagentmodel.ExecuteActionDone,
newagentmodel.ExecuteActionConfirm,
newagentmodel.ExecuteActionContinue,
newagentmodel.ExecuteActionAbort,
newagentmodel.ExecuteActionContinue,
newagentmodel.ExecuteActionConfirm,
newagentmodel.ExecuteActionAbort,
))
}
// BuildExecuteMessages 组装执行阶段消息。
func BuildExecuteMessages(state *newagentmodel.CommonState, ctx *newagentmodel.ConversationContext) []*schema.Message {
if state != nil && state.HasPlan() {
return buildExecuteStageMessages(
BuildExecuteSystemPrompt(),
state,
ctx,
buildExecuteStrictJSONUserPrompt(),
)
}
return buildExecuteStageMessages(
BuildExecuteReActSystemPrompt(),
state,
ctx,
buildExecuteStrictJSONUserPrompt(),
)
}
// buildExecutePromptWithFormatGuard 统一补一层更硬的 JSON 输出约束。
func buildExecutePromptWithFormatGuard(base string) string {
base = strings.TrimSpace(base)
guard := strings.TrimSpace(`
补充 JSON 约束:
1. 只输出当前 action 真正需要的字段;无关字段直接省略,不要用 ""、{}、[]、null 占位。
2. 若输出 tool_call参数字段名只能是 arguments禁止写成 parameters。
3. tool_call 只能是单个对象:{"name":"工具名","arguments":{...}},不能输出数组。
4. 只有 action=abort 时才允许输出 abort 字段;非 abort 动作不要输出 abort。
5. action=continue / ask_user / confirm 时speak 必须是非空自然语言。`)
if base == "" {
return guard
}
return base + "\n\n" + guard
}
// buildExecuteStrictJSONUserPrompt 统一构造 execute 阶段面向模型的最终用户指令。
func buildExecuteStrictJSONUserPrompt() string {
return strings.TrimSpace(`
请继续当前任务的执行阶段,严格输出 JSON。
输出字段:
- speak
- action
- reason
- goal_check
- tool_call
- abort
补充格式要求:
- 与当前 action 无关的字段直接省略,不要输出空字符串、空对象、空数组或 null 占位
- tool_call 只能写 {"name":"工具名","arguments":{...}},且每轮最多一个
- 不要写 {"tool_call":{"name":"工具名","parameters":{...}}}
- 非 abort 动作不要输出 abort 字段
- action 为 continue / ask_user / confirm 时,必须输出非空 speak
- list_tasks.arguments.status 仅允许 all / existing / suggested / pending 的单值;如需看 existing+suggested请用 all
- list_tasks.arguments.category 仅接受任务类名称,不要传 task_class_ids如 "1,2,3"
- 若读工具结果与已知事实明显冲突,先修正参数并重查一次,再决定是否 ask_user
- 不要连续两轮调用“同一读工具 + 等价 arguments”若上一轮已成功返回下一轮必须换工具或进入 confirm
`)
}
// BuildExecuteUserPrompt 构造有 plan 模式的用户提示词。
func BuildExecuteUserPrompt(_ *newagentmodel.CommonState) string {
return strings.TrimSpace(`
请继续当前任务的执行阶段,严格输出 JSON。
输出字段:
- speak
- action
- reason
- goal_check
- tool_call
- abort
`)
}
// BuildExecuteReActUserPrompt 构造自由执行模式的用户提示词。
func BuildExecuteReActUserPrompt(_ *newagentmodel.CommonState) string {
return strings.TrimSpace(`
请继续当前任务的执行阶段,严格输出 JSON。
输出字段:
- speak
- action
- reason
- goal_check
- tool_call
- abort
`)
}