Files
Partner/doc/action/meta-action-and-action-chain.md

179 lines
7.1 KiB
Markdown
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.
# MetaAction 与行动链建模
本文说明 Partner 行动系统中 `MetaAction``ExecutableAction` 与行动链的建模方式。
行动系统把“要做什么”拆成两个层级:
- `ExecutableAction` 表示一次完整任务,包含来源、原因、描述、状态、阶段、结果与执行历史。
- `MetaAction` 表示行动链中的最小可执行单元,描述一个具体行动程序及其调用参数、执行结果。
因此,一次行动不是一个扁平 tool call而是一个可阶段化、可恢复、可纠偏、可调度的任务对象。
## 对象层级
```text
Action
├─ ExecutableAction
│ ├─ ImmediateExecutableAction
│ └─ SchedulableExecutableAction
└─ StateAction
ExecutableAction
├─ tendency
├─ actionChain: Map<Int, List<MetaAction>>
├─ stageDescriptions: Map<Int, String>
├─ executingStage
├─ history
└─ result
```
`Action` 是最上层的抽象,负责承载通用生命周期字段。`ExecutableAction` 表示真正包含行动链的任务。`StateAction` 不包含 `MetaAction` 链,而是用于定时或周期性触发状态更新、普通逻辑调用等系统行为。
## MetaAction
`MetaAction` 是行动链中的单一元素,封装调用外部行动程序所需的基本信息。
核心字段包括:
- `name`:行动名称,用于标识行动程序。
- `type`:行动程序类型,目前包括 `MCP``ORIGIN``BUILTIN`
- `location`:行动所在位置。对 MCP 来说通常是 MCP client id对 ORIGIN 来说是磁盘路径;对 BUILTIN 来说固定为 `builtin`
- `launcher`:启动器或解释器,主要用于 `ORIGIN` 类型。
- `io`:是否偏 IO 密集,用于执行器选择线程池。
- `params`:执行前由参数提取器填充的调用参数。
- `result`:单个 `MetaAction` 的执行结果,包含 `WAITING``SUCCESS``FAILED` 三种状态。
`MetaAction``key``location::name` 组成。行动规划阶段只会引用真实存在的 action key执行阶段再通过该 key 加载行动元信息、提取参数并提交给 runner。
## MetaAction 类型
当前实现中 `MetaAction.Type` 分三类:
- `MCP`:调用已注册的 MCP 工具,可以对应本地或远程服务。
- `ORIGIN`:临时生成或持久化的行动程序,通常需要启动器或解释器。
- `BUILTIN`:由本地内置注册表直接执行的行动。
这个类型划分让行动链只关心“要调用哪个行动单元”,不把执行通道细节硬编码进 planner。真正的路由由 action runner / capability 层负责。
## ExecutableAction
`ExecutableAction` 是一次完整行动任务的结构化容器。
核心字段包括:
- `uuid`:行动实例 id。
- `source`:行动来源,通常关联用户或触发源。
- `reason`:为什么要执行该行动。
- `description`:行动描述,用于人类可读说明和上下文反馈。
- `tendency`:上游 `ActionExtractor` 提取出的行动倾向。
- `status`:任务级状态。
- `actionChain`:阶段化行动链。
- `stageDescriptions`:每个阶段的执行目标说明。
- `executingStage`:当前执行阶段。
- `history`:每个阶段已经执行过的 `HistoryAction`
- `result`:最终行动结果。
它把“行动为什么存在”“当前执行到哪里”“每一步做了什么”“最终结果是什么”放在同一个对象里,便于调度、恢复、纠偏和上下文反馈。
## 行动链结构
行动链使用 `Map<Int, List<MetaAction>>` 表示。
- `Int` 是阶段序号。
- 同一阶段中的 `List<MetaAction>` 表示该阶段下的一组行动单元。
- 阶段之间按序推进。
- 同一阶段内的多个 `MetaAction` 可以被执行器并发提交。
示意:
```text
Stage 1
├─ MetaAction A
└─ MetaAction B
Stage 2
└─ MetaAction C
Stage 3
├─ MetaAction D
└─ MetaAction E
```
这种结构适合表达“先收集事实,再执行修改,最后验证结果”一类任务。规划阶段只负责形成阶段与行动单元,执行阶段负责提取参数、提交行动、收集结果并推进阶段。
## 阶段描述
`stageDescriptions` 为每个 stage 提供自然语言目标说明。它不是用户回复文案,也不是完整执行计划,而是给执行器和参数提取器使用的阶段目标。
例如:
```text
1 -> "读取当前配置文件"
2 -> "根据目标修改配置项"
3 -> "运行检查命令确认修改有效"
```
执行器在为某个 `MetaAction` 提取参数时,会把当前行动描述和当前阶段描述一起传给参数提取模块,帮助它生成更贴近阶段目标的参数。
## 依赖修正
行动评估结果中的 `primaryActionChain` 并不直接成为最终行动链。`ActionPlanner` 会在装配阶段做两类修正:
1. **顺序归一化**:把阶段序号修正为从 1 开始依次递增。
2. **前置依赖补齐**:读取 `MetaActionInfo.preActions``strictDependencies`,必要时把严格依赖的前置 action key 插入到当前阶段之前。
这意味着 LLM 评估结果可以表达主要行动链,但最终进入执行器的链会经过系统能力层校验和依赖补齐。若 action key 不存在、元信息加载失败或依赖无法处理planner 会放弃构造该行动。
## 即时行动与计划行动
`ExecutableAction` 有两个主要实现:
- `ImmediateExecutableAction`:立即进入执行器。
- `SchedulableExecutableAction`:实现 `Schedulable`,先进入调度器,到期后再交给执行器。
二者共享同一套行动链结构。差异只在执行时机和生命周期维护:计划行动执行后会记录 `ScheduleHistory`,并重置阶段、参数和单步结果,以便周期性任务下次继续运行。
## StateAction
`StateAction` 也是 `Action`,同时实现 `Schedulable`,但它不包含 `MetaAction` 链。
它的作用是承载定时或周期性触发的系统逻辑,例如:
- 周期性状态更新。
- 一次性逻辑调用。
- 即时行动 watcher。
`StateAction.Trigger` 目前包括:
- `Update<T>`:对某个状态源执行更新函数。
- `Call`:执行普通逻辑调用。
执行器收到 `StateAction` 时不会走行动链,而是直接触发 `trigger.onTrigger()`,并把触发事件写入上下文。
## 建模边界
行动建模层只负责把行动表示清楚,不负责完成所有执行细节。
它不负责:
- 判断用户意图是否应该行动化。
- 选择所有参数值。
- 执行 MCP / BUILTIN / ORIGIN 行动。
- 判断执行是否成功。
- 生成最终用户回复。
这些分别属于行动提取、行动评估、参数提取、行动执行、反馈闭环和沟通模块。
## 设计取向
`MetaAction` 与行动链建模的核心目标是把“系统要做的事”变成结构化任务,而不是把一次行动压缩成不可追踪的工具调用。
这种设计带来几个好处:
- 可以表达多阶段任务。
- 可以为每个阶段保留目标描述。
- 可以记录每个阶段的执行历史。
- 可以在失败或结果不满足目标时插入纠偏行动。
- 可以把同一行动链用于立即执行或未来调度。
- 可以把行动状态写入 `ContextWorkspace`,供后续认知和沟通使用。