优化行动链结构及相关组件、针对 ActionPlanner 相关组件做出调整

- 将existedMetaActions的实现由LinkedHashMap替换为HashMap,免去不必要的性能消耗
- 在 ActionCapability 中新增 listAvailableActions 方法用于获取当前存在的可用行动
- 将 ActionData 及相关类中的 LinkedHashMap 替换为普通Map,阶段并发将通过遍历key集合进行,而非针对原始行动链进行遍历
- 在 ActionPlanner 中完善行动链依赖修正逻辑,防止行动单元执行时的输入缺失
- 在 ActionEvaluator 中调整了 Prompt 构建方式
- 调整处理行动链相关代码,移除多余参数,简化方法签名
- 修正 EvaluatorResult 中行动链数据结构为Map,LLM将直接返回初始行动链,后续将加载行动数据并修复行动单元间的依赖关系
- 优化 InterventionHandler、ActionExecutor 等模块中对行动链Map的使用
This commit is contained in:
2025-12-01 17:20:54 +08:00
parent 3f59719e16
commit 4e32129b31
10 changed files with 152 additions and 45 deletions

View File

@@ -8,7 +8,6 @@ import work.slhaf.partner.core.action.entity.MetaActionInfo;
import work.slhaf.partner.core.action.entity.cache.CacheAdjustData; import work.slhaf.partner.core.action.entity.cache.CacheAdjustData;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Phaser; import java.util.concurrent.Phaser;
@@ -30,8 +29,6 @@ public interface ActionCapability {
ExecutorService getExecutor(ActionCore.ExecutorType type); ExecutorService getExecutor(ActionCore.ExecutorType type);
Set<String> getExistedMetaActions();
void putPhaserRecord(Phaser phaser, ActionData actionData); void putPhaserRecord(Phaser phaser, ActionData actionData);
void removePhaserRecord(Phaser phaser); void removePhaserRecord(Phaser phaser);
@@ -44,6 +41,8 @@ public interface ActionCapability {
MetaActionInfo loadMetaActionInfo(@NonNull String actionKey); MetaActionInfo loadMetaActionInfo(@NonNull String actionKey);
List<MetaActionInfo> listAvailableActions();
boolean checkExists(String... actionKeys); boolean checkExists(String... actionKeys);
void execute(MetaAction metaAction); void execute(MetaAction metaAction);

View File

@@ -53,7 +53,7 @@ public class ActionCore extends PartnerCore<ActionCore> {
/** /**
* 已存在的行动程序,键为目录名,值为从目录加载的行动程序元信息 * 已存在的行动程序,键为目录名,值为从目录加载的行动程序元信息
*/ */
private final LinkedHashMap<String, MetaActionInfo> existedMetaActions = new LinkedHashMap<>(); private final Map<String, MetaActionInfo> existedMetaActions = new HashMap<>();
private final List<PhaserRecord> phaserRecords = new ArrayList<>(); private final List<PhaserRecord> phaserRecords = new ArrayList<>();
private final SandboxRunnerClient sandboxRunnerClient = new SandboxRunnerClient(); private final SandboxRunnerClient sandboxRunnerClient = new SandboxRunnerClient();
@@ -177,8 +177,8 @@ public class ActionCore extends PartnerCore<ActionCore> {
} }
@CapabilityMethod @CapabilityMethod
public Set<String> getExistedMetaActions() { public List<MetaActionInfo> listAvailableActions() {
return existedMetaActions.keySet(); return existedMetaActions.values().stream().toList();
} }
@CapabilityMethod @CapabilityMethod

View File

@@ -11,8 +11,8 @@ import java.io.IOException;
import java.nio.file.*; import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import static work.slhaf.partner.common.Constant.Path.ACTION_PROGRAM; import static work.slhaf.partner.common.Constant.Path.ACTION_PROGRAM;
@@ -23,10 +23,10 @@ import static work.slhaf.partner.common.Constant.Path.ACTION_PROGRAM;
class ActionWatchService { class ActionWatchService {
private final HashMap<Path, WatchKey> registeredPaths = new HashMap<>(); private final HashMap<Path, WatchKey> registeredPaths = new HashMap<>();
private final LinkedHashMap<String, MetaActionInfo> existedMetaActions; private final Map<String, MetaActionInfo> existedMetaActions;
private final ExecutorService virtualExecutor; private final ExecutorService virtualExecutor;
public ActionWatchService(LinkedHashMap<String, MetaActionInfo> existedMetaActions, ExecutorService virtualExecutor) { public ActionWatchService(Map<String, MetaActionInfo> existedMetaActions, ExecutorService virtualExecutor) {
this.existedMetaActions = existedMetaActions; this.existedMetaActions = existedMetaActions;
this.virtualExecutor = virtualExecutor; this.virtualExecutor = virtualExecutor;
} }

View File

@@ -4,8 +4,8 @@ import cn.hutool.json.JSONObject;
import lombok.Data; import lombok.Data;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 行动模块传递的行动数据包含行动uuid、倾向、状态、行动链、结果、发起原因、行动描述等信息。 * 行动模块传递的行动数据包含行动uuid、倾向、状态、行动链、结果、发起原因、行动描述等信息。
@@ -28,7 +28,7 @@ public abstract class ActionData {
/** /**
* 行动链 * 行动链
*/ */
protected LinkedHashMap<Integer, List<MetaAction>> actionChain = new LinkedHashMap<>(); protected Map<Integer, List<MetaAction>> actionChain;
/** /**
* 行动阶段(当前阶段) * 行动阶段(当前阶段)
*/ */

View File

@@ -13,8 +13,8 @@ import work.slhaf.partner.core.action.entity.ImmediateActionData;
import work.slhaf.partner.core.action.entity.MetaAction; import work.slhaf.partner.core.action.entity.MetaAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Phaser; import java.util.concurrent.Phaser;
@@ -45,7 +45,7 @@ public class ActionExecutor extends AgentRunningSubModule<List<ImmediateActionDa
private void handleActionData(ImmediateActionData actionData) { private void handleActionData(ImmediateActionData actionData) {
virtualExecutor.execute(() -> { virtualExecutor.execute(() -> {
actionData.setStatus(ActionData.ActionStatus.EXECUTING); actionData.setStatus(ActionData.ActionStatus.EXECUTING);
LinkedHashMap<Integer, List<MetaAction>> actionChain = actionData.getActionChain(); Map<Integer, List<MetaAction>> actionChain = actionData.getActionChain();
List<MetaAction> virtual = new ArrayList<>(); List<MetaAction> virtual = new ArrayList<>();
List<MetaAction> platform = new ArrayList<>(); List<MetaAction> platform = new ArrayList<>();
Phaser phaser = new Phaser(); Phaser phaser = new Phaser();
@@ -64,7 +64,7 @@ public class ActionExecutor extends AgentRunningSubModule<List<ImmediateActionDa
platform.add(metaAction); platform.add(metaAction);
} }
} }
runGroupAction(virtual, platform, actionChain, phaser); runGroupAction(virtual, platform, phaser);
phaser.arriveAndAwaitAdvance(); phaser.arriveAndAwaitAdvance();
virtual.clear(); virtual.clear();
platform.clear(); platform.clear();
@@ -79,7 +79,7 @@ public class ActionExecutor extends AgentRunningSubModule<List<ImmediateActionDa
// 使用phaser来承担同组的动态任务新增 // 使用phaser来承担同组的动态任务新增
private void runGroupAction(List<MetaAction> virtual, List<MetaAction> platform, private void runGroupAction(List<MetaAction> virtual, List<MetaAction> platform,
LinkedHashMap<Integer, List<MetaAction>> actionChain, Phaser phaser) { Phaser phaser) {
runGroupAction(virtual, virtualExecutor, phaser); runGroupAction(virtual, virtualExecutor, phaser);
runGroupAction(platform, platformExecutor, phaser); runGroupAction(platform, platformExecutor, phaser);
} }
@@ -89,6 +89,9 @@ public class ActionExecutor extends AgentRunningSubModule<List<ImmediateActionDa
for (MetaAction action : actions) { for (MetaAction action : actions) {
executor.execute(() -> { executor.execute(() -> {
try { try {
//TODO 使用 LLM 填充行动参数信息
actionCapability.execute(action);
MetaAction.Result result = action.getResult(); MetaAction.Result result = action.getResult();
do { do {
// 该循环对应LLM的调整参数后重试 // 该循环对应LLM的调整参数后重试
@@ -97,7 +100,7 @@ public class ActionExecutor extends AgentRunningSubModule<List<ImmediateActionDa
// 若使用Phaser作为执行线程与反思、求助等调用流程的同步协调应当需要额外维护Phaser全局字段获取到反思结果或者用户反馈后 // 若使用Phaser作为执行线程与反思、求助等调用流程的同步协调应当需要额外维护Phaser全局字段获取到反思结果或者用户反馈后
// 调用对应的phaser注册任务在ActionExecutor中动态添加任务至actionChain,同时启动异步执行 // 调用对应的phaser注册任务在ActionExecutor中动态添加任务至actionChain,同时启动异步执行
// 而且由于执行与放入的为同一个MetaAction对象所以执行结果可被当前行动链获取但virtual、executor两个列表似乎不行需要重构执行模式建议将行动链直接重构为LinkedHashMaporder为键 // 而且由于执行与放入的为同一个MetaAction对象所以执行结果可被当前行动链获取但virtual、executor两个列表似乎不行需要重构执行模式建议将行动链直接重构为LinkedHashMaporder为键
String input = getInput(result.getData()); String input = buildFixInput(result.getData());
// 执行时不可使用`for in`和`forEach`,因为在`Intervention`相关模块存在动态调整 // 执行时不可使用`for in`和`forEach`,因为在`Intervention`相关模块存在动态调整
} }
actionCapability.execute(action); actionCapability.execute(action);
@@ -111,7 +114,7 @@ public class ActionExecutor extends AgentRunningSubModule<List<ImmediateActionDa
} }
} }
private String getInput(String data) { private String buildFixInput(String data) {
return null; return null;
} }

View File

@@ -18,8 +18,8 @@ import work.slhaf.partner.module.modules.action.interventor.handler.entity.Handl
import work.slhaf.partner.module.modules.action.interventor.handler.entity.HandlerInput.PreparedInterventionData; import work.slhaf.partner.module.modules.action.interventor.handler.entity.HandlerInput.PreparedInterventionData;
import java.util.Comparator; import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Phaser; import java.util.concurrent.Phaser;
@@ -130,7 +130,7 @@ public class InterventionHandler extends AgentRunningSubModule<HandlerInput, Voi
phaser.register(); phaser.register();
try { try {
LinkedHashMap<Integer, List<MetaAction>> actionChain = actionData.getActionChain(); Map<Integer, List<MetaAction>> actionChain = actionData.getActionChain();
actionChain.put(order, actions); actionChain.put(order, actions);
if (order == actionData.getExecutingStage()) { if (order == actionData.getExecutingStage()) {
@@ -159,7 +159,7 @@ public class InterventionHandler extends AgentRunningSubModule<HandlerInput, Voi
private void handleDelete(ActionData actionData, int order, List<MetaAction> actions) { private void handleDelete(ActionData actionData, int order, List<MetaAction> actions) {
if (order <= actionData.getExecutingStage()) return; if (order <= actionData.getExecutingStage()) return;
LinkedHashMap<Integer, List<MetaAction>> actionChain = actionData.getActionChain(); Map<Integer, List<MetaAction>> actionChain = actionData.getActionChain();
if (actionChain.containsKey(order)) { if (actionChain.containsKey(order)) {
actionChain.get(order).removeAll(actions); actionChain.get(order).removeAll(actions);
if (actionChain.get(order).isEmpty()) { if (actionChain.get(order).isEmpty()) {
@@ -174,7 +174,7 @@ public class InterventionHandler extends AgentRunningSubModule<HandlerInput, Voi
} }
private void handleRebuild(ActionData actionData, int order, List<MetaAction> actions) { private void handleRebuild(ActionData actionData, int order, List<MetaAction> actions) {
LinkedHashMap<Integer, List<MetaAction>> actionChain = actionData.getActionChain(); Map<Integer, List<MetaAction>> actionChain = actionData.getActionChain();
actionChain.put(order, actions); actionChain.put(order, actions);
} }

View File

@@ -1,6 +1,7 @@
package work.slhaf.partner.module.modules.action.planner; package work.slhaf.partner.module.modules.action.planner;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule; import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
import work.slhaf.partner.api.agent.factory.module.annotation.Init; import work.slhaf.partner.api.agent.factory.module.annotation.Init;
@@ -9,10 +10,7 @@ import work.slhaf.partner.api.chat.pojo.Message;
import work.slhaf.partner.common.vector.VectorClient; import work.slhaf.partner.common.vector.VectorClient;
import work.slhaf.partner.core.action.ActionCapability; import work.slhaf.partner.core.action.ActionCapability;
import work.slhaf.partner.core.action.ActionCore; import work.slhaf.partner.core.action.ActionCore;
import work.slhaf.partner.core.action.entity.ActionData; import work.slhaf.partner.core.action.entity.*;
import work.slhaf.partner.core.action.entity.ImmediateActionData;
import work.slhaf.partner.core.action.entity.MetaAction;
import work.slhaf.partner.core.action.entity.ScheduledActionData;
import work.slhaf.partner.core.action.entity.cache.CacheAdjustData; import work.slhaf.partner.core.action.entity.cache.CacheAdjustData;
import work.slhaf.partner.core.action.entity.cache.CacheAdjustMetaData; import work.slhaf.partner.core.action.entity.cache.CacheAdjustMetaData;
import work.slhaf.partner.core.cognation.CognationCapability; import work.slhaf.partner.core.cognation.CognationCapability;
@@ -33,6 +31,7 @@ import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowCon
import java.util.*; import java.util.*;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
/** /**
* 负责针对本次输入生成基础的行动计划,在主模型传达意愿后,执行行动或者放入计划池 * 负责针对本次输入生成基础的行动计划,在主模型传达意愿后,执行行动或者放入计划池
@@ -92,14 +91,15 @@ public class ActionPlanner extends PreRunningModule {
return null; return null;
} }
EvaluatorInput evaluatorInput = assemblyHelper.buildEvaluatorInput(extractorResult, context.getUserId()); EvaluatorInput evaluatorInput = assemblyHelper.buildEvaluatorInput(extractorResult, context.getUserId());
List<EvaluatorResult> evaluatorResults = actionEvaluator.execute(evaluatorInput); //并发操作均为访问 List<EvaluatorResult> evaluatorResults = actionEvaluator.execute(evaluatorInput); // 并发操作均为访问
setupActionInfo(evaluatorResults, context); putActionData(evaluatorResults, context);
updateTendencyCache(evaluatorResults, context.getInput(), extractorResult); updateTendencyCache(evaluatorResults, context.getInput(), extractorResult);
return null; return null;
}); });
} }
private void updateTendencyCache(List<EvaluatorResult> evaluatorResults, String input, ExtractorResult extractorResult) { private void updateTendencyCache(List<EvaluatorResult> evaluatorResults, String input,
ExtractorResult extractorResult) {
if (!VectorClient.status) { if (!VectorClient.status) {
return; return;
} }
@@ -137,7 +137,7 @@ public class ActionPlanner extends PreRunningModule {
} }
private void setupConfirmedActionInfo(PartnerRunningFlowContext context, ConfirmerResult result) { private void setupConfirmedActionInfo(PartnerRunningFlowContext context, ConfirmerResult result) {
//TODO 需考虑未确认任务的失效或者拒绝时机在action core中实现 // TODO 需考虑未确认任务的失效或者拒绝时机在action core中实现
List<String> uuids = result.getUuids(); List<String> uuids = result.getUuids();
if (uuids == null) { if (uuids == null) {
return; return;
@@ -151,10 +151,9 @@ public class ActionPlanner extends PreRunningModule {
} }
} }
private void putActionData(List<EvaluatorResult> evaluatorResults, PartnerRunningFlowContext context) {
private void setupActionInfo(List<EvaluatorResult> evaluatorResults, PartnerRunningFlowContext context) {
for (EvaluatorResult evaluatorResult : evaluatorResults) { for (EvaluatorResult evaluatorResult : evaluatorResults) {
ActionData actionData = assemblyHelper.buildMetaActionInfo(evaluatorResult); ActionData actionData = assemblyHelper.buildActionData(evaluatorResult);
if (evaluatorResult.isNeedConfirm()) { if (evaluatorResult.isNeedConfirm()) {
actionCapability.putPendingActions(context.getUserId(), actionData); actionCapability.putPendingActions(context.getUserId(), actionData);
} else { } else {
@@ -163,7 +162,6 @@ public class ActionPlanner extends PreRunningModule {
} }
} }
@Override @Override
protected Map<String, String> getPromptDataMap(PartnerRunningFlowContext context) { protected Map<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
HashMap<String, String> map = new HashMap<>(); HashMap<String, String> map = new HashMap<>();
@@ -233,15 +231,12 @@ public class ActionPlanner extends PreRunningModule {
return input; return input;
} }
private ActionData buildMetaActionInfo(EvaluatorResult evaluatorResult) { private ActionData buildActionData(EvaluatorResult evaluatorResult) {
LinkedHashMap<Integer, List<MetaAction>> actionChain = new LinkedHashMap<>(); Map<Integer, List<MetaAction>> actionChain = getActionChain(evaluatorResult);
for (MetaAction metaAction : evaluatorResult.getActionChain()) {
actionChain.computeIfAbsent(metaAction.getOrder(), k -> new ArrayList<>()).add(metaAction);
}
return switch (evaluatorResult.getType()) { return switch (evaluatorResult.getType()) {
case PLANNING -> { case PLANNING -> {
ScheduledActionData actionInfo = new ScheduledActionData(); ScheduledActionData actionInfo = new ScheduledActionData();
actionInfo.getActionChain().putAll(actionChain); actionInfo.setActionChain(actionChain);
actionInfo.setScheduleContent(evaluatorResult.getScheduleContent()); actionInfo.setScheduleContent(evaluatorResult.getScheduleContent());
actionInfo.setStatus(ActionData.ActionStatus.PREPARE); actionInfo.setStatus(ActionData.ActionStatus.PREPARE);
actionInfo.setUuid(UUID.randomUUID().toString()); actionInfo.setUuid(UUID.randomUUID().toString());
@@ -249,7 +244,7 @@ public class ActionPlanner extends PreRunningModule {
} }
case IMMEDIATE -> { case IMMEDIATE -> {
ImmediateActionData actionInfo = new ImmediateActionData(); ImmediateActionData actionInfo = new ImmediateActionData();
actionInfo.getActionChain().putAll(actionChain); actionInfo.setActionChain(actionChain);
actionInfo.setStatus(ActionData.ActionStatus.PREPARE); actionInfo.setStatus(ActionData.ActionStatus.PREPARE);
actionInfo.setUuid(UUID.randomUUID().toString()); actionInfo.setUuid(UUID.randomUUID().toString());
yield actionInfo; yield actionInfo;
@@ -257,6 +252,82 @@ public class ActionPlanner extends PreRunningModule {
}; };
} }
private @NotNull Map<Integer, List<MetaAction>> getActionChain(EvaluatorResult evaluatorResult) {
Map<Integer, List<MetaAction>> actionChain = new HashMap<>();
Map<Integer, List<String>> primaryActionChain = evaluatorResult.getPrimaryActionChain();
fixDependencies(primaryActionChain);
primaryActionChain.forEach((order, actionKeys) -> {
List<MetaAction> metaActions = actionKeys.stream()
.map(actionKey -> actionCapability.loadMetaAction(actionKey))
.toList();
actionChain.put(order, metaActions);
});
return actionChain;
}
private void fixDependencies(Map<Integer, List<String>> primaryActionChain) {
// 先将 primaryActionChain 的节点序号修正为从1开始依次增大
fixOrder(primaryActionChain);
List<Integer> fixedOrders = new ArrayList<>(primaryActionChain.keySet().stream().toList());
AtomicBoolean fixed = new AtomicBoolean(false);
do {
Set<Integer> tempOrders = new HashSet<>();
fixedOrders.sort(Integer::compareTo);
for (Integer fixedOrder : fixedOrders) {
int lastOrder = fixedOrder - 1;
List<String> actionKeys = primaryActionChain.get(fixedOrder);
for (String actionKey : actionKeys) {
// 根据 actionKey 加载行动信息,并检查是否存在必需前置依赖
MetaActionInfo metaActionInfo = actionCapability.loadMetaActionInfo(actionKey);
List<String> preActions = metaActionInfo.getPreActions();
boolean preActionsExist = preActions != null && !preActions.isEmpty();
if (!preActionsExist) {
continue;
}
if (!metaActionInfo.isStrictDependencies()) {
continue;
}
if (checkDependenciesExist(lastOrder, preActions, primaryActionChain)) {
continue;
}
// 如果存在前置依赖,则将其放置在当前order之前的位置,
// 放置位置优先选择已存在的上一节点,如果不存在(行动链的头节点时)则需要向行动链新增order
// 不需要检查行动链的当前节点的已存在 Action 是否为新 Action 的依赖项,因为这些 Action 实际来自 LLM
// 的评估结果,并非作为依赖项存在
fixed.set(true);
List<String> actionsInChain = primaryActionChain.computeIfAbsent(lastOrder,
list -> new ArrayList<>());
preActions = new ArrayList<>(preActions);
preActions.removeAll(actionsInChain);
actionsInChain.addAll(preActions);
tempOrders.add(lastOrder);
}
}
fixedOrders.clear();
fixedOrders.addAll(tempOrders);
} while (fixed.getAndSet(false));
}
private void fixOrder(Map<Integer, List<String>> primaryActionChain) {
Map<Integer, List<String>> tempChain = new HashMap<>(primaryActionChain);
primaryActionChain.clear();
int chainSize = tempChain.size();
for (int i = 0; i < chainSize; i++) {
primaryActionChain.put(i, tempChain.get(i));
}
}
private boolean checkDependenciesExist(int lastOrder, List<String> preActions,
Map<Integer, List<String>> primaryActionChain) {
if (!primaryActionChain.containsKey(lastOrder)) {
return false;
}
List<String> existActions = primaryActionChain.get(lastOrder);
//noinspection SlowListContainsAll
return existActions.containsAll(preActions);
}
private ConfirmerInput buildConfirmerInput(PartnerRunningFlowContext context) { private ConfirmerInput buildConfirmerInput(PartnerRunningFlowContext context) {
ConfirmerInput confirmerInput = new ConfirmerInput(); ConfirmerInput confirmerInput = new ConfirmerInput();
confirmerInput.setInput(context.getInput()); confirmerInput.setInput(context.getInput());

View File

@@ -1,24 +1,34 @@
package work.slhaf.partner.module.modules.action.planner.evaluator; package work.slhaf.partner.module.modules.action.planner.evaluator;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule; import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule;
import work.slhaf.partner.api.agent.factory.module.annotation.Init; import work.slhaf.partner.api.agent.factory.module.annotation.Init;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel; import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule; import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
import work.slhaf.partner.api.chat.pojo.ChatResponse; import work.slhaf.partner.api.chat.pojo.ChatResponse;
import work.slhaf.partner.common.thread.InteractionThreadPoolExecutor; import work.slhaf.partner.common.thread.InteractionThreadPoolExecutor;
import work.slhaf.partner.core.action.ActionCapability;
import work.slhaf.partner.core.action.entity.MetaActionInfo;
import work.slhaf.partner.core.memory.pojo.EvaluatedSlice;
import work.slhaf.partner.module.modules.action.planner.evaluator.entity.EvaluatorBatchInput; import work.slhaf.partner.module.modules.action.planner.evaluator.entity.EvaluatorBatchInput;
import work.slhaf.partner.module.modules.action.planner.evaluator.entity.EvaluatorInput; import work.slhaf.partner.module.modules.action.planner.evaluator.entity.EvaluatorInput;
import work.slhaf.partner.module.modules.action.planner.evaluator.entity.EvaluatorResult; import work.slhaf.partner.module.modules.action.planner.evaluator.entity.EvaluatorResult;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
@AgentSubModule @AgentSubModule
public class ActionEvaluator extends AgentRunningSubModule<EvaluatorInput, List<EvaluatorResult>> implements ActivateModel { public class ActionEvaluator extends AgentRunningSubModule<EvaluatorInput, List<EvaluatorResult>> implements ActivateModel {
@InjectCapability
private ActionCapability actionCapability;
private InteractionThreadPoolExecutor executor; private InteractionThreadPoolExecutor executor;
@Init @Init
@@ -30,7 +40,7 @@ public class ActionEvaluator extends AgentRunningSubModule<EvaluatorInput, List<
* 对输入的行为倾向进行评估,并根据评估结果,对缓存做出调整 * 对输入的行为倾向进行评估,并根据评估结果,对缓存做出调整
* *
* @param data 评估输入内容,包含提取/命中缓存的行动倾向、近几条聊天记录,正在生效的记忆切片内容 * @param data 评估输入内容,包含提取/命中缓存的行动倾向、近几条聊天记录,正在生效的记忆切片内容
* @return 评估结果集合,包含 * @return 评估结果集合
*/ */
@Override @Override
public List<EvaluatorResult> execute(EvaluatorInput data) { public List<EvaluatorResult> execute(EvaluatorInput data) {
@@ -39,12 +49,11 @@ public class ActionEvaluator extends AgentRunningSubModule<EvaluatorInput, List<
return executor.invokeAllAndReturn(tasks); return executor.invokeAllAndReturn(tasks);
} }
private List<Callable<EvaluatorResult>> getTasks(List<EvaluatorBatchInput> batchInputs) { private List<Callable<EvaluatorResult>> getTasks(List<EvaluatorBatchInput> batchInputs) {
List<Callable<EvaluatorResult>> list = new ArrayList<>(); List<Callable<EvaluatorResult>> list = new ArrayList<>();
for (EvaluatorBatchInput batchInput : batchInputs) { for (EvaluatorBatchInput batchInput : batchInputs) {
list.add(() -> { list.add(() -> {
ChatResponse response = this.singleChat(JSONObject.toJSONString(batchInput)); ChatResponse response = this.singleChat(buildPrompt(batchInput));
EvaluatorResult evaluatorResult = JSONObject.parseObject(response.getMessage(), EvaluatorResult.class); EvaluatorResult evaluatorResult = JSONObject.parseObject(response.getMessage(), EvaluatorResult.class);
evaluatorResult.setTendency(batchInput.getTendency()); evaluatorResult.setTendency(batchInput.getTendency());
return evaluatorResult; return evaluatorResult;
@@ -59,11 +68,34 @@ public class ActionEvaluator extends AgentRunningSubModule<EvaluatorInput, List<
EvaluatorBatchInput temp = new EvaluatorBatchInput(); EvaluatorBatchInput temp = new EvaluatorBatchInput();
BeanUtil.copyProperties(data, temp); BeanUtil.copyProperties(data, temp);
temp.setTendency(tendency); temp.setTendency(tendency);
Map<String, String> availableActions = new HashMap<>();
for (MetaActionInfo metaActionInfo : actionCapability.listAvailableActions()) {
availableActions.put(metaActionInfo.getKey(), metaActionInfo.getDescription());
}
temp.setAvailableActions(availableActions);
list.add(temp); list.add(temp);
} }
return list; return list;
} }
private String buildPrompt(EvaluatorBatchInput batchInput) {
JSONObject prompt = new JSONObject();
prompt.put("[行动倾向]", batchInput.getTendency());
JSONArray memoryData = prompt.putArray("[相关记忆切片]");
for (EvaluatedSlice evaluatedSlice : batchInput.getActivatedSlices()) {
JSONObject memory = memoryData.addObject();
memory.put("[日期]", evaluatedSlice.getDate());
memory.put("[摘要]", evaluatedSlice.getSummary());
}
JSONObject availableActionData = prompt.putObject("[可用行动单元]");
availableActionData.putAll(batchInput.getAvailableActions());
return prompt.toString();
}
@Override @Override
public String modelKey() { public String modelKey() {
return "action_evaluator"; return "action_evaluator";

View File

@@ -5,10 +5,12 @@ import work.slhaf.partner.api.chat.pojo.Message;
import work.slhaf.partner.core.memory.pojo.EvaluatedSlice; import work.slhaf.partner.core.memory.pojo.EvaluatedSlice;
import java.util.List; import java.util.List;
import java.util.Map;
@Data @Data
public class EvaluatorBatchInput { public class EvaluatorBatchInput {
private List<Message> recentMessages; private List<Message> recentMessages;
private List<EvaluatedSlice> activatedSlices; private List<EvaluatedSlice> activatedSlices;
private Map<String, String> availableActions;
private String tendency; private String tendency;
} }

View File

@@ -1,9 +1,9 @@
package work.slhaf.partner.module.modules.action.planner.evaluator.entity; package work.slhaf.partner.module.modules.action.planner.evaluator.entity;
import lombok.Data; import lombok.Data;
import work.slhaf.partner.core.action.entity.MetaAction;
import java.util.List; import java.util.List;
import java.util.Map;
@Data @Data
public class EvaluatorResult { public class EvaluatorResult {
@@ -11,7 +11,7 @@ public class EvaluatorResult {
private boolean needConfirm; private boolean needConfirm;
private ActionType type; private ActionType type;
private String scheduleContent; private String scheduleContent;
private List<MetaAction> actionChain; private Map<Integer, List<String>> primaryActionChain;
private String tendency; private String tendency;
public enum ActionType { public enum ActionType {