Version: 0.9.41.dev.260424

后端:
1. 随口记从 Execute 工具链路迁移到独立 QuickTask 轻量节点——单轮流式提取意图直接调 service,绕过 ReAct 循环
- 新增 QuickTask graph 节点 + Chat→QuickTask→END 分支
- Chat 路由提示词新增 quick_task 路由判别规则,execute 路由收窄为日程类
- Execute 提示词(有 plan / ReAct 两套)移除 quick_note_create / query_tasks 指令
- ToolRegistry 注销 quick_note_create / query_tasks,移除相关依赖与注册
- 依赖注入从 ToolRegistry 改为 Service 层直接注入 QuickTaskDeps

2. urgency_threshold_at 代码兜底 + API 返回补全
- priorityGroup=2 且有 deadline 但 LLM 未填时,自动设为 deadline-24h
- 任务查询接口返回结构补充 UrgencyThresholdAt 字段与转换映射

3. 记忆召回条数 5→10
This commit is contained in:
LoveLosita
2026-04-24 14:02:27 +08:00
parent c258602a2b
commit 8daae62812
19 changed files with 606 additions and 136 deletions

View File

@@ -14,10 +14,18 @@ const chatRoutingSystemPrompt = `
路由规则:
- direct_reply纯闲聊、简单问答、轻量生活建议、打招呼、感谢等不需要工具、也不需要长链路思考的请求。控制码后直接输出完整回复。
- execute需要用工具处理的请求记录任务/提醒、查询日程、移动课程、排课等),但不需要先制定计划。控制码后输出简短确认
- quick_task用户明确想记录/添加/修改/删除一个待办或提醒(如"记一下""提醒我""帮我记"),或查看/筛选任务列表(如"我有什么任务""待办清单""最近急事")。该路由走轻量快捷路径,延迟低、废话少。控制码后不要输出任何内容
- execute需要用工具处理的日程类请求查询日程、移动课程、排课等但不需要先制定计划。控制码后输出简短确认。
- deep_answer复杂问题但不需要工具如分析建议、知识解释、方案比较、深度讨论等需要深度思考后回答。控制码后不要输出任何占位过渡语后端会直接进入第二次正式回答。
- plan用户明确要求先制定计划或涉及多阶段复杂规划。控制码后输出简短确认。
quick_task 判别要点:
- 用户明确要"记/添加/提醒"一个待办 → quick_task
- 用户要查看/筛选/列出任务清单 → quick_task
- 用户要修改/删除某个任务 → quick_task
- 但如果用户同时提了日程排布(如"把明天的课调一下,再记一下周五开会"),混合操作走 execute
- 如果信息不足(如"帮我记一下"但没说记什么),走 direct_reply 追问
通用回答约束:
- 非日程、非任务类问题,只要不需要工具,也应当正常回答。
- 不要因为用户的问题不涉及排程,就说自己“只能处理日程/任务安排”。
@@ -44,7 +52,7 @@ const chatRoutingSystemPrompt = `
输出格式(严格两段式):
第一段(控制码,用户不可见,后端会截取):
<SMARTFLOW_ROUTE nonce="给定nonce" route="direct_reply|execute|deep_answer|plan" rough_build="false" refine="false" reorder="false" thinking="false"/>
<SMARTFLOW_ROUTE nonce="给定nonce" route="direct_reply|execute|deep_answer|plan|quick_task" rough_build="false" refine="false" reorder="false" thinking="false"/>
第二段(紧接控制码之后,用户可见):
根据路由输出对应内容。
@@ -59,6 +67,8 @@ const chatRoutingSystemPrompt = `
<SMARTFLOW_ROUTE nonce="给定nonce" route="direct_reply"/>
当然可以,我先直接回答你这个问题。
<SMARTFLOW_ROUTE nonce="给定nonce" route="quick_task"/>
<SMARTFLOW_ROUTE nonce="给定nonce" route="execute"/>
好的,我来帮你看看今天的安排。

View File

@@ -14,7 +14,7 @@ const executeSystemPromptWithPlan = `
你可以做什么:
1. 只围绕当前步骤推进,先读后写,逐步完成当前步骤。
2. 可调用读工具补充事实,再决定下一步。
3. 日程写操作时输出 action=confirm 并附带 tool_call等待用户确认。quick_note_create 不需要确认,用 action=continue若信息足够必须显式填写 priority_group若信息不足则先 ask_user不要盲猜。
3. 日程写操作时输出 action=confirm 并附带 tool_call等待用户确认。
4. 若用户给出了"二次微调方向"(如负载均衡、某天减负、某类任务后移),优先围绕该方向推进,并在 goal_check 说明满足情况。
5. 只有在用户明确允许打乱顺序时,才可使用 min_context_switch 做重排。
6. 多任务微调时默认走队列链路query_target_tasks(enqueue=true) → queue_pop_head → query_available_slots → queue_apply_head_move / queue_skip_head。
@@ -39,12 +39,10 @@ const executeSystemPromptWithPlan = `
1. 输出格式:先输出一行 <SMARTFLOW_DECISION>{JSON 决策}</SMARTFLOW_DECISION>然后换行输出给用户看的自然语言正文。JSON 中不要包含 speak 字段——用户可见的话放在标签之后。
2. 读操作action=continue + tool_call。
3. 写操作(日程变更,如 place/move/swap/batch_move/unplace/spread_even/min_context_switchaction=confirm + tool_call。
4. quick_note_create记录任务/提醒若信息足够action=continue + tool_call并显式填写 priority_group若信息不足且无法可靠推断action=ask_user 先追问。quick_note_create 调用时和调用后 speak 必须留空,收口由 deliver 阶段统一完成调用成功后可继续done/next_plan/continue处理其他任务但不要为 quick_note_create 本身补充说明
5. query_tasks查看/筛选任务列表读操作action=continue + tool_call。用于回答"我有什么任务""最近有什么急事"等问题,支持按象限、关键词、截止时间范围筛选和排序
6. 缺关键上下文且无法通过工具补齐action=ask_user
7. 仅当当前步骤完成时输出 action=next_plan并在 goal_check 对照 done_when 给出证据。
8. 仅当整体任务完成时输出 action=done并在 goal_check 总结完成证据。
9. 流程应正式终止时输出 action=abort。`
4. 缺关键上下文且无法通过工具补齐action=ask_user
5. 仅当当前步骤完成时输出 action=next_plan并在 goal_check 对照 done_when 给出证据
6. 仅当整体任务完成时输出 action=done并在 goal_check 总结完成证据
7. 流程应正式终止时输出 action=abort。`
const executeSystemPromptReAct = `
你是 SmartMate 的执行器,当前处于自由执行模式(无预定义 plan 步骤)。
@@ -59,7 +57,7 @@ const executeSystemPromptReAct = `
1. 你可以基于用户给定的二次微调方向,对 suggested 做定向微调。
2. existing 属于已安排事实层,可用于冲突判断和参考,不作为 move/batch_move/spread_even 的目标。
3. 你可以先调用读工具补充必要事实(例如 get_overview/query_target_tasks/query_available_slots/get_task_info
4. 你可以在需要日程写操作时提出 confirmmove/swap/unplace/batch_move/spread_evenquick_note_create 不需要确认,用 action=continue若信息足够必须显式填写 priority_group若信息不足则先 ask_user。
4. 你可以在需要日程写操作时提出 confirmmove/swap/unplace/batch_move/spread_even
5. 只有用户明确允许打乱顺序时,才可使用 min_context_switch。
6. 多任务处理默认使用队列链路:先 query_target_tasks(enqueue=true) 入队,再 queue_pop_head 逐项处理。
@@ -82,11 +80,9 @@ const executeSystemPromptReAct = `
1. 输出格式:先输出一行 <SMARTFLOW_DECISION>{JSON 决策}</SMARTFLOW_DECISION>然后换行输出给用户看的自然语言正文。JSON 中不要包含 speak 字段——用户可见的话放在标签之后。
2. 读操作action=continue + tool_call。
3. 写操作(日程变更,如 place/move/swap/batch_move/unplace/spread_even/min_context_switchaction=confirm + tool_call。
4. quick_note_create记录任务/提醒若信息足够action=continue + tool_call并显式填写 priority_group若信息不足且无法可靠推断action=ask_user 先追问。quick_note_create 调用时和调用后 speak 必须留空,收口由 deliver 阶段统一完成调用成功后可继续done/next_plan/continue处理其他任务但不要为 quick_note_create 本身补充说明
5. query_tasks查看/筛选任务列表):读操作,action=continue + tool_call。用于回答"我有什么任务""最近有什么急事"等问题,支持按象限、关键词、截止时间范围筛选和排序
6. 缺关键上下文且无法通过工具补齐action=ask_user。
7. 任务完成action=done并在 goal_check 总结完成证据。
8. 流程应正式终止action=abort。`
4. 缺关键上下文且无法通过工具补齐action=ask_user
5. 任务完成:action=done并在 goal_check 总结完成证据
6. 流程应正式终止action=abort。`
// BuildExecuteSystemPrompt 返回执行阶段系统提示词(有 plan 模式)。
func BuildExecuteSystemPrompt() string {

View File

@@ -0,0 +1,102 @@
package newagentprompt
import (
"fmt"
"strings"
"time"
newagentmodel "github.com/LoveLosita/smartflow/backend/newAgent/model"
"github.com/cloudwego/eino/schema"
)
const quickTaskSystemPrompt = `
你是 SmartMate 的快捷任务助手。用户想记录或查看待办任务。你需要从用户消息中提取操作意图和参数。
你能做的操作:
- create记录一条新任务/提醒
- query查看/筛选任务列表
输出格式(两阶段):
先输出一行决策标签,标签内是 JSON标签之后换行输出给用户看的自然语言正文。
决策标签格式:<SMARTFLOW_DECISION>{JSON}</SMARTFLOW_DECISION>
JSON 字段说明:
- action只能是 create / query / ask
- create 时title 必填deadline_at 必填priority_group 必填,范围 1-4urgency_threshold_at 满足条件时填写,条件在下面
- query 时quadrant 可选 1-4keyword 可选limit 可选
- ask 时question 必填
规则:
1. 优先级1=重要且紧急2=重要不紧急3=简单不重要4=复杂不重要;紧急判定:截止时间距今不超过 48 小时为紧急(1),超过 48 小时为不紧急(2),无截止时间默认 3
2. 信息不足时(如缺少 title输出 {"action":"ask","question":"追问内容"}
3. deadline_at 支持「明天下午3点」「下周一」「2026-04-20 18:00」等格式
4. 未提供的可选字段直接省略,不要填 null 或空字符串
5. JSON 中不要包含 speak 字段,给用户看的话放在 </SMARTFLOW_DECISION> 标签之后
6. 紧急分界时间,即任务从"重要不紧急"自动轮换到"重要且紧急"的时间点;格式同 deadline_at ——当 priority_group=2 时必填,你必须根据 deadline 自动推算一个合理的紧急分界时间(通常为 deadline 前 24-48 小时不要等用户提供priority_group 为 1、3、4 或无截止时间时不要输出此字段
示例:
<SMARTFLOW_DECISION>{"action":"create","title":"明天开会","deadline_at":"明天下午3点"}</SMARTFLOW_DECISION>
好的,我来帮你记一下。
<SMARTFLOW_DECISION>{"action":"create","title":"下周交报告","deadline_at":"下周五 18:00","priority_group":2,"urgency_threshold_at":"下周四 09:00"}</SMARTFLOW_DECISION>
好的,我也帮你记一下。
<SMARTFLOW_DECISION>{"action":"query","limit":5}</SMARTFLOW_DECISION>
我帮你查一下当前的任务。
<SMARTFLOW_DECISION>{"action":"ask","question":"你想记录什么呢?告诉我具体内容吧。"}</SMARTFLOW_DECISION>
你想记录什么呢?告诉我具体内容吧。`
// BuildQuickTaskSystemPrompt 返回快捷任务阶段的系统提示词。
func BuildQuickTaskSystemPrompt() string {
return strings.TrimSpace(quickTaskSystemPrompt)
}
// BuildQuickTaskMessagesSimple 组装快捷任务阶段的最简 messages无对话历史
func BuildQuickTaskMessagesSimple(userInput string) []*schema.Message {
systemMsg := schema.SystemMessage(BuildQuickTaskSystemPrompt())
userMsg := schema.UserMessage(buildQuickTaskUserPrompt(userInput))
return []*schema.Message{systemMsg, userMsg}
}
func buildQuickTaskUserPrompt(userInput string) string {
var sb strings.Builder
sb.WriteString(fmt.Sprintf("当前时间=%s\n", time.Now().In(time.Local).Format("2006-01-02 15:04")))
sb.WriteString("\n请从用户消息中提取操作意图和参数严格按 SMARTFLOW_DECISION 标签格式输出。\n\n")
trimmedInput := strings.TrimSpace(userInput)
if trimmedInput != "" {
sb.WriteString("用户输入:\n")
sb.WriteString(trimmedInput)
sb.WriteString("\n")
}
return sb.String()
}
// BuildQuickTaskMessages 组装快捷任务阶段的完整 messages含对话历史
func BuildQuickTaskMessages(
ctx *newagentmodel.ConversationContext,
userInput string,
toolSchemas []newagentmodel.ToolSchemaContext,
) []*schema.Message {
return buildUnifiedStageMessages(
ctx,
StageMessagesConfig{
SystemPrompt: BuildQuickTaskSystemPrompt(),
Msg1Content: buildChatConversationMessage(ctx),
Msg2Content: buildQuickTaskWorkspace(toolSchemas),
Msg3Suffix: buildQuickTaskUserPrompt(userInput),
Msg3Role: schema.User,
},
)
}
func buildQuickTaskWorkspace(toolSchemas []newagentmodel.ToolSchemaContext) string {
var sb strings.Builder
sb.WriteString("可用工具:\n")
for _, ts := range toolSchemas {
sb.WriteString(fmt.Sprintf("- %s: %s\n 参数: %s\n", ts.Name, ts.Desc, ts.SchemaText))
}
return sb.String()
}