feat(action): create prompts for submodules of ActionExecutor

This commit is contained in:
2026-04-17 15:01:45 +08:00
parent 503afecbe2
commit 8928ec9e07
7 changed files with 189 additions and 54 deletions

View File

@@ -12,29 +12,76 @@ import work.slhaf.partner.framework.agent.model.ActivateModel;
import work.slhaf.partner.framework.agent.model.pojo.Message; import work.slhaf.partner.framework.agent.model.pojo.Message;
import work.slhaf.partner.framework.agent.support.Result; import work.slhaf.partner.framework.agent.support.Result;
import work.slhaf.partner.module.TaskBlock; import work.slhaf.partner.module.TaskBlock;
import work.slhaf.partner.module.action.executor.entity.CorrectionRecognizerInput; import work.slhaf.partner.module.action.executor.entity.CorrectorInput;
import work.slhaf.partner.module.action.executor.entity.CorrectionRecognizerResult; import work.slhaf.partner.module.action.executor.entity.RecognizerResult;
import java.util.List; import java.util.List;
/** /**
* 负责在行动链执行过程中判断当前进度是否异常,是否需要引入 corrector 介入。 * 负责在行动链执行过程中判断当前进度是否异常,是否需要引入 corrector 介入。
*/ */
public class ActionCorrectionRecognizer extends AbstractAgentModule.Sub<CorrectionRecognizerInput, Result<CorrectionRecognizerResult>> implements ActivateModel { public class ActionCorrectionRecognizer extends AbstractAgentModule.Sub<CorrectorInput, Result<RecognizerResult>> implements ActivateModel {
private static final String MODULE_PROMPT = """
你负责在行动链执行过程中识别当前执行是否出现异常,并判断是否需要引入 corrector 介入。
你会收到:
- 一条结构化上下文消息,其中包含近期交流轨迹与当前活跃记忆切片;
- 一条任务消息,其中包含:
- executable_action_info当前正在执行的行动信息包括 executing_action_id、original_tendency、evaluation_passed_reason、description 与 from_who
- current_action_chain_overview当前行动链概览按 stage_count 分组,包含各阶段已有 meta_action 的 action_key、description 与 status。
你的任务:
- 基于当前上下文、当前行动信息与当前行动链概览,判断这条行动链是否仍在合理推进;
- 判断当前是否已经出现明显偏航、停滞、重复打转、条件失配、目标漂移,或与最新语境不再一致的情况;
- 若需要引入 corrector则返回 needCorrection=true并给出简洁明确的 reason
- 若当前仍可继续推进,则返回 needCorrection=false。
识别原则:
- executable_action_info 用于说明当前链路最初为何成立、要解决什么问题、当前由谁发起;你的判断必须围绕这条行动本身,而不是被无关历史带偏。
- executing_action_id 用于标识当前正在执行的行动current_action_chain_overview 用于说明当前链路整体结构与已知阶段状态。
- original_tendency 表示这条行动链最初要解决的问题;若当前链路明显偏离这一倾向,应优先视为异常信号。
- evaluation_passed_reason 与 description 表示该行动最初为何被判定为可推进;若当前状态已经与这些前提不再一致,应考虑触发纠正。
- current_action_chain_overview 是判断当前链路是否停滞、重复、缺步骤、顺序异常或整体失衡的主要依据。
- communication 域用于判断最新交流语境是否已发生明显变化,导致当前行动继续推进不再合适。
- memory 域只在与当前行动明显相关时作为辅助参考使用。
应优先考虑需要纠正的情形:
- 当前行动长期没有形成有效推进,只在重复相近步骤、相近动作或相近结论;
- 当前执行显著偏离 original_tendency开始围绕无关目标展开
- 当前行动所依赖的前提已被新的交流内容或上下文推翻;
- 当前行动链反复遇到同类失败、阻塞或空转迹象,继续按原链推进意义不大;
- 当前行动链已经明显需要改写策略、调整阶段顺序、补入新步骤或删除无效步骤,但现有链路无法自行收敛。
不应轻易触发纠正的情形:
- 只是正常的多步推进;
- 存在短暂等待、一次性失败或合理重试,但整体方向仍正确;
- 行动链整体仍与 original_tendency、evaluation_passed_reason 和当前语境保持一致;
- 仅凭旧对话、低相关记忆或轻微波动,不足以判定当前行动异常。
关于输出:
- needCorrection=true 表示当前应引入 corrector 介入。
- needCorrection=false 表示当前行动仍可继续按既有链路推进。
- reason 用于简洁说明判断依据;若 needCorrection=false也应给出简短理由说明为何当前仍可继续推进。
- 不要输出结构之外的解释、说明或额外文本。
输出要求:
- 严格按照 RecognizerResult 对应结构输出。
""";
@InjectCapability @InjectCapability
private CognitionCapability cognitionCapability; private CognitionCapability cognitionCapability;
@Override @Override
protected @NotNull Result<CorrectionRecognizerResult> doExecute(CorrectionRecognizerInput input) { protected @NotNull Result<RecognizerResult> doExecute(CorrectorInput input) {
List<Message> messages = List.of( List<Message> messages = List.of(
resolveContextMessage(), resolveContextMessage(),
resolveTaskMessage(input) resolveTaskMessage(input)
); );
return formattedChat(messages, CorrectionRecognizerResult.class); return formattedChat(messages, RecognizerResult.class);
} }
private Message resolveTaskMessage(CorrectionRecognizerInput input) { private Message resolveTaskMessage(CorrectorInput input) {
return new TaskBlock() { return new TaskBlock() {
@Override @Override
protected void fillXml(@NotNull Document document, @NotNull Element root) { protected void fillXml(@NotNull Document document, @NotNull Element root) {
@@ -47,18 +94,33 @@ public class ActionCorrectionRecognizer extends AbstractAgentModule.Sub<Correcti
return Unit.INSTANCE; return Unit.INSTANCE;
}); });
appendListElement(document, root, "current_action_chain_overview", "action_chain_stage", input.getActionChainOverview().entrySet(), (stageElement, stageData) -> {
stageElement.setAttribute("stage_count", String.valueOf(stageData.getKey()));
appendRepeatedElements(document, stageElement, "meta_action", stageData.getValue(), (metaActionElement, metaActionData) -> {
appendTextElement(document, metaActionElement, "action_key", metaActionData.getActionKey());
appendTextElement(document, metaActionElement, "description", metaActionData.getDescription());
appendTextElement(document, metaActionElement, "status", metaActionData.getStatus());
return Unit.INSTANCE;
});
return Unit.INSTANCE;
});
} }
}.encodeToMessage(); }.encodeToMessage();
} }
private Message resolveContextMessage() { private Message resolveContextMessage() {
return cognitionCapability.contextWorkspace().resolve(List.of( return cognitionCapability.contextWorkspace().resolve(List.of(
ContextBlock.FocusedDomain.ACTION, ContextBlock.FocusedDomain.COMMUNICATION,
ContextBlock.FocusedDomain.COGNITION,
ContextBlock.FocusedDomain.MEMORY ContextBlock.FocusedDomain.MEMORY
)).encodeToMessage(); )).encodeToMessage();
} }
@Override
@NotNull
public List<Message> modulePrompt() {
return List.of(new Message(Message.Character.SYSTEM, MODULE_PROMPT));
}
@NotNull @NotNull
@Override @Override
public String modelKey() { public String modelKey() {

View File

@@ -22,6 +22,70 @@ import java.util.List;
*/ */
public class ActionCorrector extends AbstractAgentModule.Sub<CorrectorInput, Result<CorrectorResult>> implements ActivateModel { public class ActionCorrector extends AbstractAgentModule.Sub<CorrectorInput, Result<CorrectorResult>> implements ActivateModel {
private static final String MODULE_PROMPT = """
你负责在行动链执行过程中进行纠偏。你的任务不是重新评估是否要启动这条行动,而是在当前行动已经进入执行后,根据原始行动意图、当前链路结构与最新语境,判断是否需要调整后续行动链。
你会收到:
- 一条结构化上下文消息,其中包含近期交流轨迹与当前活跃记忆切片;
- 一条任务消息,其中包含:
- executable_action_info当前正在执行的行动信息包括 executing_action_id、original_tendency、evaluation_passed_reason、description 与 from_who
- current_action_chain_overview当前行动链概览按 stage_count 分组,包含各阶段已有 meta_action 的 action_key、description 与 status。
你的任务:
- 基于当前上下文、原始行动意图与当前行动链进展,判断后续行动是否仍然符合目的;
- 若当前链路仍可继续推进,则不要随意干预;
- 若当前链路已明显跑偏、缺少必要步骤、顺序不合理、存在冗余、已经不再适合继续,或需要引入新的动作单元,则输出干预方案;
- correctionReason 用于简洁说明为何需要这些纠偏。
纠偏原则:
- executable_action_info 用于说明当前链路最初为何成立、要解决什么问题、当前由谁发起;你的纠偏必须围绕这条行动本身,而不是转向新的无关目标。
- executing_action_id 用于标识当前正在执行的行动current_action_chain_overview 用于说明当前链路整体结构与阶段状态。
- original_tendency 是这条行动链最初要解决的问题;后续行动的调整必须仍然围绕它。
- evaluation_passed_reason 与 description 表示该行动最初为何能够成立;若当前链路已经与这些前提不一致,可据此进行纠偏。
- current_action_chain_overview 是判断后续链路是否缺步骤、顺序失衡、重复冗余或整体方向错误的主要依据。
- communication 域用于判断最新交流语境是否已经变化,导致当前链路需要调整。
- memory 域只在与当前行动明显相关时作为辅助参考使用。
何时应考虑干预:
- 当前链路缺少继续推进所必需的动作;
- 当前链路顺序明显不合理,继续执行会降低成功率或偏离目的;
- 某些动作已经失效、重复、无意义,或不再适合当前状态;
- 当前链路在某一阶段之后整体方向需要重建;
- 当前行动已不应继续推进,应直接取消整条链路。
何时不应轻易干预:
- 当前只是正常的多步推进;
- 某一步刚完成,尚不足以说明后续链路错误;
- 没有足够依据证明当前行动链存在明显问题;
- 仅凭旧对话、低相关记忆或轻微波动,不足以支持修改行动链。
关于干预类型:
- APPEND: 在指定 order 之后追加新的动作。
- INSERT: 在指定 order 执行过程中即时插入并执行新的动作。
- DELETE: 删除指定 order 上的指定动作。
- CANCEL: 取消当前行动链后续执行。
- REBUILD: 清空当前行动链与既有执行进度,并用新的规划内容整体重建行动链。
关于 intervention 列表:
- 系统会按照 metaInterventionList 的顺序逐条应用干预;前面的干预可能改变后续可理解的 order 位置,因此你在生成后续 intervention 时,必须考虑前面 intervention 已经生效后的链路形态。
- 不要把一组本应整体表达的修改拆成互相冲突、顺序不自洽的 intervention。
- actions 中只能填写当前系统中真实存在、可用的 action_key不要编造不存在的动作。
- order 必须对应当前行动链中的合理阶段位置。
关于 REBUILD
- REBUILD 表示放弃当前既有链路,并重新给出新的整体规划。
- 一旦本次纠偏结果中使用了 REBUILD则 metaInterventionList 中所有 intervention 都必须是 REBUILD不要将 REBUILD 与 APPEND、INSERT、DELETE、CANCEL 混用。
- 使用 REBUILD 时,应把新的链路规划完整表达为一组按 order 分布的 REBUILD intervention而不是只局部补几步。
其他约束:
- 若无需干预,可返回空的 metaInterventionList并给出简短的 correctionReason 说明当前为何可继续推进。
- 不要输出结构之外的解释、说明或额外文本。
输出要求:
- 严格按照 CorrectorResult 对应结构输出。
- metaInterventionList 中每一项都必须是明确、可执行、且与其他 intervention 顺序一致的干预单元。
""";
@InjectCapability @InjectCapability
private CognitionCapability cognitionCapability; private CognitionCapability cognitionCapability;
@@ -63,13 +127,17 @@ public class ActionCorrector extends AbstractAgentModule.Sub<CorrectorInput, Res
private Message resolveContextMessage() { private Message resolveContextMessage() {
return cognitionCapability.contextWorkspace().resolve(List.of( return cognitionCapability.contextWorkspace().resolve(List.of(
ContextBlock.FocusedDomain.ACTION,
ContextBlock.FocusedDomain.COMMUNICATION, ContextBlock.FocusedDomain.COMMUNICATION,
ContextBlock.FocusedDomain.COGNITION,
ContextBlock.FocusedDomain.MEMORY ContextBlock.FocusedDomain.MEMORY
)).encodeToMessage(); )).encodeToMessage();
} }
@Override
@NotNull
public List<Message> modulePrompt() {
return List.of(new Message(Message.Character.SYSTEM, MODULE_PROMPT));
}
@NotNull @NotNull
@Override @Override
public String modelKey() { public String modelKey() {

View File

@@ -387,25 +387,25 @@ public class ActionExecutor extends AbstractAgentModule.Standalone {
if (!shouldRunCorrectionRecognizer(executableAction)) { if (!shouldRunCorrectionRecognizer(executableAction)) {
return RecognizerTaskRecord.disabled(); return RecognizerTaskRecord.disabled();
} }
val recognizerInput = assemblyHelper.buildRecognizerInput(executableAction); val recognizerInput = assemblyHelper.buildCorrectorInput(executableAction);
val task = buildRecognizerTask(recognizerInput, phaser); val task = buildRecognizerTask(recognizerInput, phaser);
Future<CorrectionRecognizerResult> future = virtualExecutor.submit(task); Future<RecognizerResult> future = virtualExecutor.submit(task);
return new RecognizerTaskRecord(true, future); return new RecognizerTaskRecord(true, future);
} }
private Callable<CorrectionRecognizerResult> buildRecognizerTask(CorrectionRecognizerInput input, Phaser phaser) { private Callable<RecognizerResult> buildRecognizerTask(CorrectorInput input, Phaser phaser) {
phaser.register(); phaser.register();
return () -> { return () -> {
try { try {
return actionCorrectionRecognizer.execute(input) return actionCorrectionRecognizer.execute(input)
.getOrDefault(new CorrectionRecognizerResult()); .getOrDefault(new RecognizerResult());
} finally { } finally {
phaser.arriveAndDeregister(); phaser.arriveAndDeregister();
} }
}; };
} }
private CorrectionRecognizerResult resolveRecognizerResult(RecognizerTaskRecord record) { private RecognizerResult resolveRecognizerResult(RecognizerTaskRecord record) {
if (record == null || !record.enabled() || record.future() == null) { if (record == null || !record.enabled() || record.future() == null) {
return null; return null;
} }
@@ -548,7 +548,7 @@ public class ActionExecutor extends AbstractAgentModule.Standalone {
private record MetaActionsListeningRecord(AtomicBoolean accepting, int phase) { private record MetaActionsListeningRecord(AtomicBoolean accepting, int phase) {
} }
private record RecognizerTaskRecord(boolean enabled, Future<CorrectionRecognizerResult> future) { private record RecognizerTaskRecord(boolean enabled, Future<RecognizerResult> future) {
private static RecognizerTaskRecord disabled() { private static RecognizerTaskRecord disabled() {
return new RecognizerTaskRecord(false, null); return new RecognizerTaskRecord(false, null);
} }
@@ -594,14 +594,5 @@ public class ActionExecutor extends AbstractAgentModule.Standalone {
.build(); .build();
} }
private CorrectionRecognizerInput buildRecognizerInput(ExecutableAction executableAction) {
return CorrectionRecognizerInput.builder()
.tendency(executableAction.getTendency())
.source(executableAction.getSource())
.reason(executableAction.getReason())
.description(executableAction.getDescription())
.actionId(executableAction.getUuid())
.build();
}
} }
} }

View File

@@ -23,6 +23,42 @@ import java.util.List;
*/ */
public class ParamsExtractor extends AbstractAgentModule.Sub<ExtractorInput, Result<ExtractorResult>> implements ActivateModel { public class ParamsExtractor extends AbstractAgentModule.Sub<ExtractorInput, Result<ExtractorResult>> implements ActivateModel {
private static final String MODULE_PROMPT = """
你负责为指定行动提取参数信息。
你会收到:
- 一条结构化上下文消息,其中可能包含当前行动相关状态、近期交流轨迹、以及活跃记忆切片;
- 一条任务消息,其中包含:
- target_action本次参数提取所面向的目标行动用于帮助你判断上下文中哪些内容与当前提取直接相关
- meta_action_info该行动对应的说明以及允许提取的参数列表。每个 <param name="..."> 节点的文本内容表示该参数的含义或期望内容。
你的任务:
- 根据当前上下文与目标行动信息,提取本次行动所需的参数;
- 只提取能够从当前输入、近期会话、相关行动历史或明确上下文中得到支持的参数;
- 若当前信息不足以支持可靠提取,则返回 ok=false而不是猜测或编造参数。
提取原则:
- target_action 用于帮助你在上下文中定位当前面对的是哪一个行动,不要把无关行动历史混入当前参数提取。
- action 域中的执行中行动块及其阶段历史,可作为理解当前行动推进位置、已知条件与已出现参数的参考。
- communication 域主要用于理解用户最近表达的条件、补充、修正、确认或否定信息。
- memory 域只在与当前目标行动明显相关时作为辅助参考使用。
- params 中只能填写 meta_action_info.params 中声明过的参数名,不要编造不存在的参数。
- 每个参数值都应尽量保持为简洁、明确、可直接使用的文本,不要输出冗长解释。
- 若某个参数无法从现有信息中可靠确定,就不要填写它。
关于输出:
- ok=true 表示你已经提取出了一组可用参数;不要求必须填满全部参数,但结果应足以支持后续执行继续推进。
- ok=false 表示当前信息不足以形成可靠参数结果。
- params 为参数项列表;每一项都必须包含:
- name: 参数名
- value: 参数值文本
- 不要把 params 输出为对象、Map 或其他结构,只能输出 ParamEntry 列表。
- 不要输出结构之外的解释、说明或额外文本。
输出要求:
- 严格按照 ExtractorResult 对应结构输出。
""";
@InjectCapability @InjectCapability
private CognitionCapability cognitionCapability; private CognitionCapability cognitionCapability;
@@ -69,6 +105,12 @@ public class ParamsExtractor extends AbstractAgentModule.Sub<ExtractorInput, Res
.encodeToMessage(); .encodeToMessage();
} }
@Override
@NotNull
public List<Message> modulePrompt() {
return List.of(new Message(Message.Character.SYSTEM, MODULE_PROMPT));
}
@NotNull @NotNull
@Override @Override
public String modelKey() { public String modelKey() {

View File

@@ -1,14 +0,0 @@
package work.slhaf.partner.module.action.executor.entity;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class CorrectionRecognizerInput {
private String tendency;
private String source;
private String reason;
private String description;
private String actionId;
}

View File

@@ -1,14 +0,0 @@
package work.slhaf.partner.module.action.executor.entity;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class CorrectionRecognizerMetaActionSnapshot {
private String key;
private String name;
private boolean io;
private String resultStatus;
private String resultData;
}

View File

@@ -3,7 +3,7 @@ package work.slhaf.partner.module.action.executor.entity;
import lombok.Data; import lombok.Data;
@Data @Data
public class CorrectionRecognizerResult { public class RecognizerResult {
private boolean needCorrection = false; private boolean needCorrection = false;
private String reason; private String reason;
} }