后端: 1. execute 主链路重构为“上下文工具域 + 主动优化候选闭环”——移除 order_guard,粗排后默认进入主动微调,先诊断再从后端候选中选择 move/swap,避免 LLM 自由全局乱搜 2. 工具体系升级为动态注入协议——新增 context_tools_add / remove、工具域与二级包映射、主动优化白名单;schedule / taskclass / web 工具按域按包暴露,msg0 规则包与 execute 上下文同步重写 3. analyze_health 升级为主动优化唯一裁判入口——补齐 rhythm / tightness / profile / feasibility 指标、候选扫描与复诊打分、停滞信号、forced imperfection 判定,并把连续优化状态写回运行态 4. 任务类能力并入新 Agent 执行链——新增 upsert_task_class 写工具与启动注入事务写入;任务类模型补充学科画像与整天屏蔽配置,粗排支持 excluded_days_of_week,steady 策略改为基于目标位置/单日负载/分散度/缓冲的候选打分 5. 运行态与路由补齐优化模式语义——新增 active tool domain/packs、pending context hook、active optimize only、taskclass 写入回盘快照;区分 first_full / global_reopt / local_adjust,并完善首次粗排后默认 refine 的判定 前端: 6. 助手时间线渲染细化——推理内容改为独立 reasoning block,支持与工具/状态/正文按时序交错展示,自动收口折叠,修正 confirm reject 恢复动作 仓库: 7. newAgent 文档整体迁入 docs/backend,补充主动优化执行规划与顺序约束拆解文档,删除旧调试日志文件 PS:这次科研了2天,总算是有些进展了——LLM永远只适合做选择题、判断题,不适合做开放创新题。
635 lines
28 KiB
Markdown
635 lines
28 KiB
Markdown
# SmartFlow NewAgent P1-P1.5 执行改动计划(代码实施版)
|
||
|
||
## 0. 文档定位
|
||
- 文档类型:代码实施计划(非 PRD)。
|
||
- 对齐范围:仅覆盖已冻结 PRD 的 `P1` 与 `P1.5`。
|
||
- 执行目标:先跑通“首次编排主动优化闭环(P1)+ 对话内任务类共创可用版(P1.5)”。
|
||
|
||
---
|
||
|
||
## 1. 目标与边界
|
||
|
||
### 1.1 本轮目标(必须完成)
|
||
- P1:在 `execute` 主链路中引入分析型读工具,形成“观测 -> 调整 -> 复盘 -> 收口”的可执行闭环。
|
||
- P1:保持旧写工具链路主执行地位(`move/swap/unplace/...`),分析工具只做观测,不直接执行改动。
|
||
- P1.5:在对话内提供“完整任务类草案”能力,并通过 `upsert_task_class` 完成确认后的统一落库。
|
||
|
||
### 1.2 本轮非目标(明确不做)
|
||
- 不做多版本日程管理(已定 P2)。
|
||
- 不做配置化持久禁改清单(仅对话内轻量语义)。
|
||
- 不做聊天外按钮触发任务类共创。
|
||
- 不做 `analyze_deadlines`(当前 `ScheduleState` 无单任务 deadline/priority 数据源,不满足稳定落地条件)。
|
||
|
||
---
|
||
|
||
## 2. 现状代码锚点(实施入口)
|
||
|
||
### 2.1 执行主链路
|
||
- [execute.go](/D:/SmartFlow-Agent/backend/newAgent/node/execute.go)
|
||
- [agent_nodes.go](/D:/SmartFlow-Agent/backend/newAgent/node/agent_nodes.go)
|
||
- [common_graph.go](/D:/SmartFlow-Agent/backend/newAgent/graph/common_graph.go)
|
||
|
||
### 2.2 工具注册与调度态
|
||
- [registry.go](/D:/SmartFlow-Agent/backend/newAgent/tools/registry.go)
|
||
- [state.go](/D:/SmartFlow-Agent/backend/newAgent/tools/schedule/state.go)
|
||
- [read_tools.go](/D:/SmartFlow-Agent/backend/newAgent/tools/schedule/read_tools.go)
|
||
- [read_filter_tools.go](/D:/SmartFlow-Agent/backend/newAgent/tools/schedule/read_filter_tools.go)
|
||
- [task-class.go](/D:/SmartFlow-Agent/backend/dao/task-class.go)
|
||
|
||
### 2.3 Prompt 与工具可见性
|
||
- [execute.go](/D:/SmartFlow-Agent/backend/newAgent/prompt/execute.go)
|
||
- [execute_context.go](/D:/SmartFlow-Agent/backend/newAgent/prompt/execute_context.go)
|
||
- [chat.go](/D:/SmartFlow-Agent/backend/newAgent/node/chat.go)
|
||
|
||
### 2.4 状态持久化与恢复
|
||
- [common_state.go](/D:/SmartFlow-Agent/backend/newAgent/model/common_state.go)
|
||
- [graph_run_state.go](/D:/SmartFlow-Agent/backend/newAgent/model/graph_run_state.go)
|
||
- [state_store.go](/D:/SmartFlow-Agent/backend/newAgent/model/state_store.go)
|
||
|
||
---
|
||
|
||
## 3. 总体改造方案(分层)
|
||
|
||
### 3.1 工具层(新增能力)
|
||
- 新增 5 个分析读工具(P1):
|
||
- `analyze_health`
|
||
- `analyze_load`
|
||
- `analyze_subjects`
|
||
- `analyze_context`
|
||
- `analyze_tolerance`
|
||
- P1.5 不新增“任务类草案工具”;任务类草案由主 LLM 按 prompt 在对话内生成。
|
||
- P1.5 新增 1 个任务类写库工具:`upsert_task_class`(创建/更新统一入口,走 confirm)。
|
||
|
||
### 3.2 策略层(执行行为约束)
|
||
- 通过 `chat -> execute` 路由策略 + `execute prompt` 约束,控制“何时走全局分析,何时走局部旧链路”。
|
||
- 保持“单轮单工具调用”与现有 `confirm` 闸门不变。
|
||
|
||
### 3.3 状态层(最小增量)
|
||
- 建议新增轻量执行模式标记到 `CommonState`(避免全靠 prompt 猜):
|
||
- `OptimizationMode string`,建议取值:
|
||
- `first_full`(首次编排全流程)
|
||
- `local_adjust`(后续局部请求)
|
||
- `global_reopt`(用户明确触发全局重优化)
|
||
|
||
说明:如你希望“最小侵入”,该字段也可先不加,改用 `PinnedBlock` 过渡;但建议保留,后续可测试性更好。
|
||
|
||
---
|
||
|
||
## 4. 统一数据契约(新增工具)
|
||
|
||
### 4.1 分析工具统一返回包络(强约束)
|
||
所有分析工具返回 `string(JSON)`,顶层统一:
|
||
|
||
```json
|
||
{
|
||
"tool": "analyze_xxx",
|
||
"success": true,
|
||
"metric_schema": {},
|
||
"metrics": {},
|
||
"issues": [
|
||
{
|
||
"issue_id": "issue_xxx",
|
||
"dimension": "load|subjects|context|tolerance|feasibility|health",
|
||
"severity": "critical|warning|info",
|
||
"trigger": {
|
||
"metric": "metric_key",
|
||
"operator": ">=|<=|>|<|==",
|
||
"threshold": 0,
|
||
"actual": 0
|
||
}
|
||
}
|
||
],
|
||
"next_actions": [
|
||
{
|
||
"action_id": "na_xxx",
|
||
"priority": 1,
|
||
"intent_code": "rebalance_load|reduce_switch|increase_tolerance|...",
|
||
"target_filter": {},
|
||
"slot_filter": {},
|
||
"candidate_scope": {
|
||
"day_range": [],
|
||
"categories": [],
|
||
"task_pool": "placed|pending|mixed"
|
||
},
|
||
"required_reads": [],
|
||
"success_criteria": {},
|
||
"candidate_write_tools": ["move|swap|spread_even|..."]
|
||
}
|
||
],
|
||
"error": "",
|
||
"error_code": ""
|
||
}
|
||
```
|
||
|
||
### 4.2 统一错误与成功语义(强约束)
|
||
- 所有新增工具统一返回 `string(JSON)`。
|
||
- 顶层字段固定:
|
||
- `tool`: 工具名。
|
||
- `success`: `true|false`。
|
||
- `metric_schema`: 指标字典(每个指标的含义、单位、方向)。
|
||
- `metrics`: 指标数据本体。
|
||
- `issues`: 问题数据本体(机器可判定触发条件)。
|
||
- `next_actions`: 下一步动作意图(不给最终写参数)。
|
||
- `error`: 失败时的人类可读错误文案。
|
||
- `error_code`: 失败时稳定机器码(如 `invalid_args` / `insufficient_data`)。
|
||
- `feasibility`(可选):可行性快照(`is_feasible/capacity_gap/reason_code`)。
|
||
- 成功时必须返回 `metrics/issues/next_actions`。
|
||
|
||
### 4.2.1 精简协议原则(新增)
|
||
- 不在协议中放大段中文解释,不依赖 `summary/reason` 驱动执行。
|
||
- 协议只提供三类最小必要信息:
|
||
- 数据含义:`metric_schema`
|
||
- 当前状态:`metrics/issues`
|
||
- 下一步方向:`next_actions`
|
||
- LLM 通过 prompt 规则 + 上述结构化数据完成后续读写决策。
|
||
|
||
### 4.2.2 目标对象选择原则(新增)
|
||
- 后端只提供“方向+作用范围+成功判据”,不下发最终写参数,不指定唯一 `task_id`。
|
||
- `next_actions` 的 `candidate_scope/target_filter/slot_filter` 只定义可行动边界与禁区。
|
||
- LLM 负责在边界内自主选择目标对象与写工具参数(如选哪个任务、挪到哪个槽位)。
|
||
- 执行层负责合法性校验与证据化回传(本次操作命中哪个 issue、是否满足 success_criteria),不替代 LLM 做确定性选点。
|
||
|
||
### 4.3 工具详规:`analyze_load`
|
||
适用场景:
|
||
- 首次编排后的全局负载体检。
|
||
- 用户诉求命中“太满/太空/不均匀/某几天压力大”。
|
||
|
||
入参定义(建议):
|
||
- `scope`: `full|week|day_range`,默认 `full`。
|
||
- `week_from/week_to`: `scope=week` 时可选;缺失则覆盖窗口内所有周。
|
||
- `day_from/day_to`: `scope=day_range` 时必填。
|
||
- `granularity`: `day|week|time_of_day`,默认 `day`。
|
||
- `detail`: `summary|full`,默认 `summary`。
|
||
|
||
计算口径:
|
||
- `total_used = course_used + task_used`(总占用)。
|
||
- `utilization = total_used / total_slots`。
|
||
- `load_std_dev`: 按天 `total_used` 计算样本标准差。
|
||
- `load_range = max_day_total_used - min_day_total_used`。
|
||
- 时段拆分固定:上午 `1-4`,下午 `5-8`,晚上 `9-12`。
|
||
- `delta_from_prev = today_total_used - yesterday_total_used`。
|
||
|
||
输出字段重点:
|
||
- `metrics.summary`: `total_used/course_used/task_used/pending_count`、`utilization_rate`、`peak/valley`、`load_std_dev`、`load_range`。
|
||
- `metrics.days`: 每日 `total_used/course_used/task_used`、时段分解、负载等级。
|
||
- `metrics.weeks`: 周级聚合(仅 `granularity=week` 或 `detail=full` 时返回)。
|
||
|
||
issues 判定(normal 档):
|
||
- `critical`: 任意天利用率 `>= 0.90`,或 `load_std_dev >= 3.0` 且 `peak_day_load - valley_day_load >= 7`。
|
||
- `warning`: 任意天利用率 `0.80~0.90`,或 `load_std_dev 2.0~3.0`。
|
||
- `info`: 利用率整体正常但有轻微波动。
|
||
|
||
阈值档位偏移:
|
||
- `strict`: 比 normal 更严格(提前约 10% 触发)。
|
||
- `relaxed`: 比 normal 更宽松(延后约 10% 触发)。
|
||
|
||
next_actions 生成规则:
|
||
- 阈值判断基于 `total_used`,但建议动作仅作用任务层(`task_used/pending`),不建议“优化课程占位”。
|
||
- 负载过高建议:`move`、`queue_apply_head_move`、`spread_even`。
|
||
- 波动过大建议:跨天分流,优先“峰值日 -> 低负载日”。
|
||
- 仅给建议,不输出可直接执行写操作。
|
||
|
||
失败返回:
|
||
- 参数非法、范围越界、窗口为空时返回 `success=false`。
|
||
|
||
### 4.4 工具详规:`analyze_subjects`
|
||
适用场景:
|
||
- 用户问“某科排得怎么样”“某任务类是不是太集中”。
|
||
- 首次编排后检查任务类节奏与预算进度。
|
||
|
||
入参定义(建议):
|
||
- `category`: 可选;为空表示全科目。
|
||
- `include_pending`: `true|false`,默认 `true`。
|
||
- `detail`: `summary|full`,默认 `summary`。
|
||
|
||
计算口径:
|
||
- `present_days`: 该科目出现过落位的 `day_index` 集合。
|
||
- `gaps`: 相邻出现日的间隔天数(`next_day - prev_day - 1`)。
|
||
- `avg/max/min/std_gap`: 基于 `gaps` 统计。
|
||
- `concentration`: 建议用按天时段占比的归一化 HHI(`0` 分散,`1` 集中)。
|
||
- `budget_progress = used_slots / total_slots`(`total_slots` 来自 `TaskClassMeta`)。
|
||
|
||
输出字段重点:
|
||
- `metrics.subjects[]`: `task_count/placed/pending`、`present_days/gaps`、`concentration`、`budget_progress`。
|
||
- 可选返回 `days_to_end`(当任务类存在 `end_date` 且可解析)。
|
||
|
||
issues 判定(normal 档):
|
||
- `critical`: `max_gap >= 6`,或 `concentration >= 0.85`,或 `budget_progress < 0.4` 且截止临近。
|
||
- `warning`: `max_gap 4~5`,或 `concentration 0.70~0.85`。
|
||
- `info`: 节奏基本稳定但有可优化空间。
|
||
|
||
next_actions 生成规则:
|
||
- 过于集中:建议 `spread_even` 或多次 `move` 分散。
|
||
- 空窗过长:建议插入中间复习点。
|
||
- 预算滞后:建议提高该科目近期优先级。
|
||
|
||
失败返回:
|
||
- `category` 不存在时可返回 `success=true` + 空结果,不建议硬失败。
|
||
|
||
### 4.5 工具详规:`analyze_context`
|
||
适用场景:
|
||
- 用户反馈“切换太多、心累、一天很碎”。
|
||
- 首次编排后认知负荷体检。
|
||
|
||
入参定义(建议):
|
||
- `day_from/day_to`: 可选;缺省覆盖窗口全量。
|
||
- `detail`: `summary|day_detail`,默认 `summary`。
|
||
- `hard_categories`: 可选数组;用于“硬课相邻”判定。
|
||
|
||
计算口径:
|
||
- `sequence`: 按时段顺序提取当日科目序列(仅已落位任务)。
|
||
- `switch_count`: 相邻非空且科目变化次数。
|
||
- `blocks`: 连续同科目块。
|
||
- `fragmentation = switch_count / max(occupied_slots-1, 1)`。
|
||
- `heavy_adjacent`: 相邻 pair 同时命中 `hard_categories`。
|
||
|
||
输出字段重点:
|
||
- `metrics.overall`: 总切换次数、日均切换、最长同科目连续块、平均块长度。
|
||
- `metrics.days[]`: `switch_count`、`fragmentation`、`adjacent_pairs`、`blocks`。
|
||
|
||
issues 判定(normal 档):
|
||
- `critical`: `switch_count >= 5` 且 `fragmentation >= 0.75`。
|
||
- `warning`: `switch_count 3~4` 或 `fragmentation 0.55~0.75`。
|
||
- `info`: 结构基本可接受但可继续聚合。
|
||
|
||
next_actions 生成规则:
|
||
- 优先建议同科目聚合(`move/swap`)。
|
||
- P1 明确不把 `min_context_switch` 作为候选写工具,避免“窗口内强行并排”造成学习间隔恶化。
|
||
|
||
失败返回:
|
||
- 无落位任务时返回 `success=true` + 空指标,不硬失败。
|
||
|
||
### 4.6 工具详规:`analyze_tolerance`
|
||
适用场景:
|
||
- 用户反馈“排太满”“想留余量”“希望更抗突发”。
|
||
- 与 PRD 中“容错”概念保持一致(替代旧“空窗”话术)。
|
||
|
||
入参定义(建议):
|
||
- `scope`: `full|week|day_range`,默认 `full`。
|
||
- `week_from/week_to/day_from/day_to`: 按 scope 生效。
|
||
- `min_usable_size`: 默认 `2`(>=2 连续空位视为可用块)。
|
||
- `min_daily_buffer`: 默认 `2`(每日最少可用余量阈值)。
|
||
- `detail`: `summary|full`,默认 `summary`。
|
||
|
||
计算口径:
|
||
- `total_free_slots`: 所有空闲时段总和。
|
||
- `usable_slots`: 处于“可用空窗块(长度>=min_usable_size)”内的空闲时段。
|
||
- `fragmented_slots`: 碎片空窗时段数。
|
||
- `fragmentation_rate = fragmented_slots / total_free_slots`。
|
||
- `buffer_sufficient`: 每天 `usable_slots >= min_daily_buffer`。
|
||
|
||
输出字段重点:
|
||
- `metrics.overall`: `total_free/usable/fragmented`、`fragmentation_rate`、`days_without_buffer`。
|
||
- `metrics.days[]`: 每日空窗块细节、相邻任务类型、是否满足缓冲。
|
||
|
||
issues 判定(normal 档):
|
||
- `critical`: `days_without_buffer >= 2` 或 `fragmentation_rate >= 0.65`。
|
||
- `warning`: `days_without_buffer = 1` 或 `fragmentation_rate 0.45~0.65`。
|
||
- `info`: 容错足够但可进一步优化分布。
|
||
|
||
next_actions 生成规则:
|
||
- 容错过低:建议把边缘任务外移、打散拥堵日。
|
||
- 碎片过高:建议合并连续学习块,减少“1节孤岛”。
|
||
|
||
失败返回:
|
||
- `min_usable_size<=0` 或参数范围非法时返回 `success=false`。
|
||
|
||
### 4.7 工具详规:`analyze_health`
|
||
适用场景:
|
||
- 首次编排全流程的默认首入口。
|
||
- 用户明确要求“整体体检/全局重优化”。
|
||
|
||
入参定义(建议):
|
||
- `dimensions`: 可选,默认 `["load","subjects","context","tolerance"]`。
|
||
- `threshold`: `strict|normal|relaxed`,默认 `normal`。
|
||
- `detail`: `summary|full`,默认 `summary`。
|
||
|
||
聚合策略:
|
||
- 内部复用各分析器的统计函数,不在工具内二次调用 registry 工具(避免链式循环与重复成本)。
|
||
- `issues` 合并后按 `severity -> impact_score -> recency` 排序。
|
||
- 对同源问题去重(同维度、同天、同任务的重复报警合并)。
|
||
- 聚合前先做可行性判定;若不可行,必须追加 `dimension=feasibility` 的 `critical` 问题。
|
||
|
||
输出字段重点:
|
||
- `metrics`: 各维度精简核心指标。
|
||
- `issues`: 标准化问题清单(用于 execute 单轮主问题域选择)。
|
||
- `next_actions`: 最多 3 条高价值建议动作(仅建议)。
|
||
- `feasibility`: `{ "is_feasible": bool, "capacity_gap": int, "reason_code": string }`。
|
||
|
||
issues 生成口径:
|
||
- 直接沿用各维度阈值档位。
|
||
- 若 `critical=0 && warning<=1`,在 `metrics` 明确写出“可接受收口”信号。
|
||
- 若 `is_feasible=false`,无论其它维度如何,都必须输出 `feasibility` 的 `critical` 问题。
|
||
|
||
失败返回:
|
||
- `dimensions` 全非法时返回 `success=false`。
|
||
|
||
#### 4.7.1 可行性判定(强约束)
|
||
目的:
|
||
- 解决“窗口太小/约束过严,导致持续 critical 且无法优化”的循环问题。
|
||
|
||
判定输入:
|
||
- `required_task_slots`:当前仍需排入或重排的任务时段需求总量。
|
||
- `feasible_slots`:在当前窗口与约束下,可承载任务的可用时段总量。
|
||
- `capacity_gap = required_task_slots - feasible_slots`。
|
||
|
||
判定规则:
|
||
- `capacity_gap <= 0`:`is_feasible=true`,继续常规优化。
|
||
- `capacity_gap > 0`:`is_feasible=false`,进入“不可行协商分支”。
|
||
|
||
不可行协商分支(由 `analyze_health.next_actions` 输出建议):
|
||
- `ask_expand_window`:建议扩展时间窗。
|
||
- `ask_relax_constraints`:建议放松禁排时段/容错目标/顺序限制。
|
||
- `ask_reduce_scope_or_budget`:建议缩范围或降低预算。
|
||
- `accept_risk_and_close`:若用户坚持当前约束,按“有风险收口”结束本轮。
|
||
|
||
### 4.8 P1.5 草案生成原则(无新工具)
|
||
适用场景:
|
||
- 用户在聊天内要求“帮我设计任务类/补全参数/给个可排的草案”。
|
||
- 输出应是“完整草案”,不是散点建议。
|
||
|
||
生成机制:
|
||
- 草案由主 LLM 在 prompt 引导下直接生成,不新增后端草案工具。
|
||
- 来源优先级固定:`user_explicit > memory > web_common_knowledge`。
|
||
- 冲突必须显式标记为 `conflicts`,不得静默覆盖用户明确偏好。
|
||
|
||
字段分级(按 PRD 冻结):
|
||
- 关键字段(必须 ask_user 确认):`time_window`、`strategy`、`total_slots`、`tolerance_preference`、`excluded_slots`、`task_items_integrity`、`task_item_priority_or_dependency`(用户给出时)。
|
||
- 普通字段(可静默落):`time_of_day_preference_weight`、`same_category_aggregation_preference`、`milestone_split_suggestion`、`knowledge_tags_and_path_notes`(命中统一标准时结构化)。
|
||
|
||
后置校验原则:
|
||
- 各类字段合法性与完整性校验放在写流程之后执行。
|
||
- 若写后校验失败,返回可修复反馈并进入下一轮对话修订。
|
||
|
||
### 4.9 工具详规:`upsert_task_class`(P1.5 写库)
|
||
适用场景:
|
||
- 草案与关键字段确认完成后,将任务类落库(新建或更新)。
|
||
- 用户明确要求“创建任务类/更新任务类参数”。
|
||
|
||
工具定位:
|
||
- 这是 P1.5 唯一新增写工具,不负责草案生成。
|
||
- 通过 `id` 语义统一创建与更新:`id=0` 创建,`id>0` 更新。
|
||
- 必须走 confirm 闸门,避免模型在未确认关键字段时直接写库。
|
||
|
||
入参定义(建议):
|
||
- `id`: `int`,可选,默认为 `0`(创建);`>0` 表示更新已有任务类。
|
||
- `task_class`: 任务类主体字段(名称、时间窗、策略、总预算、容错偏好、禁排时段等)。
|
||
- `items`: 任务项数组(任务项名称、时长/预算、优先级或依赖等)。
|
||
- `source`: 可选,记录来源(`chat|memory|web`),用于审计与回显。
|
||
|
||
执行语义:
|
||
- 工具内部以事务写库:先 upsert 任务类主体,再 upsert 任务项。
|
||
- 复用 DAO 现有能力:`AddOrUpdateTaskClass` + `AddOrUpdateTaskClassItems`。
|
||
- 写后执行字段合法性与完整性校验;失败时返回可修复错误,不做静默成功。
|
||
|
||
输出字段重点:
|
||
- `success`: 是否写库成功。
|
||
- `task_class_id`: 最终任务类 ID(创建时为新 ID,更新时为原 ID)。
|
||
- `created`: `true|false`(是否新建)。
|
||
- `validation`: 写后校验结果(`ok/issues[]`)。
|
||
- `error/error_code`: 写库或校验失败时的稳定错误信息。
|
||
|
||
失败返回:
|
||
- 关键字段缺失、字段非法、用户越权、事务失败时返回 `success=false`。
|
||
- 校验失败时返回 `success=false` + 可修复 `issues`,由 LLM 继续 ask_user/修订。
|
||
|
||
---
|
||
|
||
## 5. P1 实施清单(逐项)
|
||
|
||
## 5.1 P1-A:分析工具落地(工具层)
|
||
定义:
|
||
- 在 `tools/schedule` 新增分析工具实现,全部只读,不改 `ScheduleState`。
|
||
|
||
改动动作:
|
||
- 新增文件建议:
|
||
- `analyze_common.go`(通用统计、分级、JSON封装)
|
||
- `analyze_load.go`
|
||
- `analyze_subjects.go`
|
||
- `analyze_context.go`
|
||
- `analyze_tolerance.go`
|
||
- `analyze_health.go`
|
||
|
||
- 每个工具遵循“参数校验失败返回 `success=false` JSON 错误”口径,与 `query_available_slots` 风格一致。
|
||
|
||
验收标准:
|
||
- 每个工具在 `ScheduleState` 空/小/大样本下可稳定返回合法 JSON。
|
||
- 不产生任何状态写入副作用。
|
||
|
||
---
|
||
|
||
## 5.2 P1-B:注册表接线(工具可发现)
|
||
定义:
|
||
- 将新工具纳入 `ToolRegistry`,并确保被 Execute 看见。
|
||
|
||
改动动作:
|
||
- 修改 [registry.go](/D:/SmartFlow-Agent/backend/newAgent/tools/registry.go)
|
||
- `NewDefaultRegistryWithDeps` 注册 5 个分析工具。
|
||
- 保持其为读工具(不加入 `writeTools`)。
|
||
- 增加 P1 运行态工具可见性约束:`min_context_switch` 对 execute 模型侧默认隐藏(仅保留既有写工具链路中的 `move/swap/...`)。
|
||
|
||
验收标准:
|
||
- `ToolRegistry.ToolNames()` 可见新增工具。
|
||
- `IsWriteTool` 对新增工具全部返回 `false`。
|
||
- P1 模式下 execute 可见写工具集合不包含 `min_context_switch`。
|
||
|
||
---
|
||
|
||
## 5.3 P1-C:Prompt 策略升级(行为约束)
|
||
定义:
|
||
- 让 LLM 在正确场景优先使用分析工具,且不过度主动。
|
||
|
||
改动动作:
|
||
- 修改 [execute.go](/D:/SmartFlow-Agent/backend/newAgent/prompt/execute.go)
|
||
- 增加规则:
|
||
- `first_full/global_reopt` 模式优先 `analyze_health`。
|
||
- `local_adjust` 模式默认旧链路(`query_target_tasks/query_available_slots/...`)。
|
||
- 未命中全局触发条件,不要滥用全局分析。
|
||
- 增加“先定范围再写入”规则:先用分析/读取工具锁定 `candidate_scope`,再选择写工具执行。
|
||
- 增加“自主选目标”规则:后端不指定具体任务,LLM 在边界内自行选择目标与参数,并在后续复盘中验证是否命中 success_criteria。
|
||
- 在 P1 提示词中禁用 `min_context_switch`(不作为候选动作)。
|
||
|
||
- 修改 [execute_context.go](/D:/SmartFlow-Agent/backend/newAgent/prompt/execute_context.go)
|
||
- 为新增工具补“返回类型+最小示例”。
|
||
|
||
验收标准:
|
||
- 同样输入下,首次编排与局部调整的工具选择有明显分流。
|
||
- 不出现“局部请求强行全局体检”的高频行为。
|
||
- 日志可还原“本轮 scope 是什么、为何选择该任务、成功判据是否达成”。
|
||
|
||
---
|
||
|
||
## 5.4 P1-D:执行模式标记(状态层,建议)
|
||
定义:
|
||
- 给执行链路显式模式,避免仅靠 prompt 推断。
|
||
|
||
改动动作(建议):
|
||
- 修改 [common_state.go](/D:/SmartFlow-Agent/backend/newAgent/model/common_state.go)
|
||
- 新增 `OptimizationMode string`。
|
||
- 在 [chat.go](/D:/SmartFlow-Agent/backend/newAgent/node/chat.go) 路由处设置模式:
|
||
- 首次编排粗排后微调 -> `first_full`
|
||
- 局部调整请求 -> `local_adjust`
|
||
- 明确全局重优化请求 -> `global_reopt`
|
||
|
||
验收标准:
|
||
- `execute` 运行日志中可观测到模式值。
|
||
- 恢复场景不丢模式(随 RuntimeState 快照持久化)。
|
||
|
||
---
|
||
|
||
## 5.5 P1-E:收口与质量防抖(执行层)
|
||
定义:
|
||
- 不改变现有阈值,只补齐可观测数据与兜底日志。
|
||
|
||
改动动作:
|
||
- 使用现有收口规则:`critical=0 && warning<=1`、连续无效 3 轮收口、60 轮上限。
|
||
- 在 `analyze_health` 返回里统一输出 `issues`,供 LLM 与日志一致引用。
|
||
- 当 `feasibility.is_feasible=false` 时,禁止继续常规微调回路(`move/swap` 反复试探)。
|
||
|
||
验收标准:
|
||
- 收口判断与 PRD 一致。
|
||
- 日志可还原“每轮依据哪个 issue 在优化”。
|
||
- 不可行场景下不会跑满无意义轮次。
|
||
|
||
---
|
||
|
||
## 5.6 P1-F:不可行协商分支(新增)
|
||
定义:
|
||
- 把“排不下”与“排不好”拆开处理;不可行时转入用户协商,而非继续磨轮次。
|
||
|
||
改动动作:
|
||
- 在 [execute.go](/D:/SmartFlow-Agent/backend/newAgent/node/execute.go) 增加分支规则:
|
||
- 若最近一次 `analyze_health` 明确 `is_feasible=false`:
|
||
- 本轮优先 `ask_user`,给出四类选项(扩窗口/放松约束/降范围预算/接受风险收口)。
|
||
- 若用户未调整约束且明确继续当前方案,允许“有风险收口”。
|
||
- 若用户调整了约束,重开一轮入场判定并继续。
|
||
|
||
- 在 [prompt/execute.go](/D:/SmartFlow-Agent/backend/newAgent/prompt/execute.go) 增加硬约束提示:
|
||
- 不可行时禁止继续无目标微调。
|
||
- 不可行时必须先沟通约束变更。
|
||
|
||
验收标准:
|
||
- 人工构造“明显排不下”样例时,模型会在少量轮次内进入协商,不会持续 `critical` 循环。
|
||
- 协商后可恢复正常优化或风险收口,路径清晰可追溯。
|
||
|
||
---
|
||
|
||
## 6. P1.5 实施清单(逐项)
|
||
|
||
## 6.1 P1.5-A:Prompt 草案生成
|
||
定义:
|
||
- 提供“完整任务类草案”生成能力(聊天触发),不新增后端草案工具。
|
||
|
||
改动动作:
|
||
- 修改 [chat.go](/D:/SmartFlow-Agent/backend/newAgent/prompt/chat.go) 与 [execute.go](/D:/SmartFlow-Agent/backend/newAgent/prompt/execute.go):
|
||
- 明确“任务类草案由 LLM 直接生成”的提示词约束。
|
||
- 明确“关键字段必须 ask_user,普通字段可静默落”的输出约束。
|
||
- 明确“来源优先级与冲突显式化”规则。
|
||
|
||
验收标准:
|
||
- 任意输入可生成完整草案结构(无新增工具调用)。
|
||
- 关键字段缺失时会触发 ask_user,不会直接进入 `upsert_task_class`。
|
||
|
||
---
|
||
|
||
## 6.2 P1.5-B:写库工具落地(`upsert_task_class`)
|
||
定义:
|
||
- 新增统一任务类写库入口,承接“草案确认后落库”。
|
||
|
||
改动动作:
|
||
- 新增文件建议:
|
||
- `tools/task_class_write.go`
|
||
- `tools/task_class_write_types.go`
|
||
- 修改 [registry.go](/D:/SmartFlow-Agent/backend/newAgent/tools/registry.go):
|
||
- 注册 `upsert_task_class`。
|
||
- 加入 `writeTools`(必须 confirm)。
|
||
- 加入 `scheduleFreeTools`(不依赖 `ScheduleState`,可在纯聊天草案场景调用)。
|
||
- 工具内部复用 DAO 事务能力:`AddOrUpdateTaskClass` + `AddOrUpdateTaskClassItems`。
|
||
- 写后补齐字段合法性与完整性校验,统一返回可修复 `issues`。
|
||
|
||
验收标准:
|
||
- `id=0` 可创建成功,`id>0` 可更新成功,且返回稳定 `task_class_id`。
|
||
- confirm 拒绝时不发生写入。
|
||
- 写后校验失败时可稳定回到对话修订,不出现“写入后静默失败”。
|
||
|
||
---
|
||
|
||
## 6.3 P1.5-C:触发策略(聊天入口)
|
||
定义:
|
||
- 仅聊天触发,不加按钮分支。
|
||
|
||
改动动作:
|
||
- 调整 [chat.go](/D:/SmartFlow-Agent/backend/newAgent/prompt/chat.go) 路由提示:
|
||
- 识别“设计任务类/补全任务类参数/生成任务类草案”等意图。
|
||
- 路由建议继续走 `execute`(复用现有链路),不新增节点、不新增草案工具。
|
||
- 调整 [execute.go](/D:/SmartFlow-Agent/backend/newAgent/prompt/execute.go):
|
||
- 明确草案阶段只读/对话,落库阶段统一调用 `upsert_task_class`。
|
||
- 明确“关键字段未确认禁止写库”的硬约束。
|
||
|
||
验收标准:
|
||
- 用户自然语言可稳定触发草案生成流程。
|
||
- 关键字段确认后可稳定触发 `upsert_task_class` 落库。
|
||
- 不出现“创建第二聊天区”的交互分叉。
|
||
|
||
---
|
||
|
||
## 7. 分阶段提交建议(按 PR 切)
|
||
|
||
### PR-1(P1 工具层)
|
||
- 新增 5 分析工具实现 + 单元级自测(本地运行后清理临时测试文件)。
|
||
- 不动 prompt,不动 chat 路由。
|
||
|
||
### PR-2(P1 策略层)
|
||
- registry 注册 + execute prompt/示例补齐 + 可选 `OptimizationMode`。
|
||
- 联调首次编排与局部请求两条路径。
|
||
- 联调“不可行协商分支”(避免持续 critical 循环)。
|
||
- 联调“后端给边界,LLM 自主选目标”的读写闭环,并验证 P1 隐藏 `min_context_switch`。
|
||
|
||
### PR-3(P1.5 草案能力)
|
||
- prompt 草案生成约束 + 关键字段确认流 + `upsert_task_class` 写库工具接线 + 写后校验回传约束。
|
||
|
||
### PR-4(联调与收口)
|
||
- 统一日志字段、错误返回格式、文档回填(含 PRD 对应项映射)。
|
||
|
||
---
|
||
|
||
## 8. 验收与回滚
|
||
|
||
### 8.1 验收检查
|
||
- 功能验收:
|
||
- 首次编排触发全流程分析策略。
|
||
- 局部调整默认旧链路,不误触发全局分析。
|
||
- 任务类草案可聊天触发,按“草案 -> 关键字段确认 -> 写入 -> 写后校验”链路闭环。
|
||
- 任务类最终落库统一通过 `upsert_task_class`,且受 confirm 闸门保护。
|
||
|
||
- 质量验收:
|
||
- 无新增死循环风险(轮次与无效轮次机制保持)。
|
||
- 写工具确认闸门不退化(A/B/C 硬规则仍生效)。
|
||
- 不可行场景可被识别并进入协商分支,不再无效磨轮。
|
||
- 写入前具备 scope 证据,且目标对象由 LLM 自主选择(非后端硬编码选点)。
|
||
|
||
### 8.2 回滚策略
|
||
- 工具级开关:先通过注册表控制可见性(临时下线单工具不影响主链)。
|
||
- Prompt级回滚:保留旧提示模板版本,出现偏航可快速切回。
|
||
- 状态字段回滚:新增字段仅追加,删除前先做兼容读取。
|
||
|
||
---
|
||
|
||
## 9. 本轮对齐清单(逐项勾选)
|
||
- [ ] 1. 是否采用 `OptimizationMode` 显式模式字段(建议:采用)?
|
||
- [ ] 2. P1 是否严格限定 5 个分析工具(不含 deadlines)?
|
||
- [ ] 3. 分析工具返回包络是否冻结为 `metrics/issues/next_actions`?
|
||
- [ ] 4. P1.5 是否确认复用 execute 链路,不新增独立 graph 节点?
|
||
- [ ] 5. PR 拆分是否采用 `PR-1~PR-4` 顺序?
|
||
- [ ] 6. 是否冻结“可行性判定 + 不可行协商分支”为 P1 必做项?
|
||
- [ ] 7. 是否冻结“后端只给边界,LLM 自主选目标与参数”为执行原则?
|
||
- [ ] 8. 是否冻结 P1 默认禁用 `min_context_switch`(不暴露给 execute 候选写工具)?
|
||
- [ ] 9. 是否冻结“P1.5 不新增 `build_task_class_draft`,草案改为纯 prompt 生成 + 写后校验”?
|
||
- [ ] 10. 是否冻结“P1.5 新增 `upsert_task_class` 作为唯一任务类写库入口(必须 confirm)”?
|
||
|
||
---
|
||
|
||
## 10. 备注(关键现实约束)
|
||
- 当前 `ScheduleState` 不含单任务 `deadline_at/priority_group/urgency_threshold_at`,故不建议在 P1 实现 `analyze_deadlines`。
|
||
- 若后续要做 `analyze_deadlines`,需先在 `conv/schedule_state.go` 映射 task 维度截止信息到工具态,再进入 P2。
|