推进行动干预模块

- 完善了 ActionInterventor 中的具体逻辑以及不同情况下的prompt填充内容;
- 调整了 PreRunningModule 中的 getPromptDataMap 方法;
- 在 ActionCapability 中新增了检查 actionKey 是否存在的逻辑
This commit is contained in:
2025-11-10 23:02:48 +08:00
parent c3ca4145b8
commit a1520f117b
9 changed files with 106 additions and 31 deletions

View File

@@ -4,6 +4,7 @@ import lombok.NonNull;
import work.slhaf.partner.api.agent.factory.capability.annotation.Capability;
import work.slhaf.partner.core.action.entity.ActionData;
import work.slhaf.partner.core.action.entity.MetaAction;
import work.slhaf.partner.core.action.entity.MetaActionInfo;
import work.slhaf.partner.core.action.entity.cache.CacheAdjustData;
import java.util.List;
@@ -41,4 +42,7 @@ public interface ActionCapability {
MetaAction loadMetaAction(@NonNull String actionKey);
MetaActionInfo loadMetaActionInfo(@NonNull String actionKey);
boolean checkExists(String... actionKeys);
}

View File

@@ -227,6 +227,20 @@ public class ActionCore extends PartnerCore<ActionCore> {
return phaserRecords;
}
@CapabilityMethod
public MetaActionInfo loadMetaActionInfo(@NonNull String actionKey) {
MetaActionInfo info = existedMetaActions.get(actionKey);
if (info == null) {
throw new MetaActionNotFoundException("未找到对应的行动程序描述信息: " + actionKey);
}
return info;
}
@CapabilityMethod
public boolean checkExists(String... actionKeys) {
return existedMetaActions.keySet().containsAll(Arrays.asList(actionKeys));
}
/**
* 命中缓存且评估通过时
*

View File

@@ -5,7 +5,7 @@ import lombok.EqualsAndHashCode;
import work.slhaf.partner.api.common.entity.PersistableObject;
import java.io.Serial;
import java.util.HashMap;
import java.util.Map;
@EqualsAndHashCode(callSuper = true)
@Data
@@ -15,5 +15,5 @@ public class AppendPromptData extends PersistableObject {
private static final long serialVersionUID = 1L;
private String moduleName;
private HashMap<String,String> appendedPrompt;
private Map<String, String> appendedPrompt;
}

View File

@@ -5,7 +5,7 @@ import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunn
import work.slhaf.partner.module.common.entity.AppendPromptData;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
import java.util.HashMap;
import java.util.Map;
/**
* 前置模块抽象类
@@ -15,7 +15,7 @@ public abstract class PreRunningModule extends AgentRunningModule<PartnerRunning
private synchronized void setAppendedPrompt(PartnerRunningFlowContext context) {
AppendPromptData data = new AppendPromptData();
data.setModuleName(moduleName());
HashMap<String, String> map = getPromptDataMap(context);
Map<String, String> map = getPromptDataMap(context);
data.setAppendedPrompt(map);
context.setAppendedPrompt(data);
}
@@ -24,7 +24,7 @@ public abstract class PreRunningModule extends AgentRunningModule<PartnerRunning
context.getCoreContext().addActiveModule(moduleName());
}
protected abstract HashMap<String, String> getPromptDataMap(PartnerRunningFlowContext context);
protected abstract Map<String, String> getPromptDataMap(PartnerRunningFlowContext context);
/**
* 用于在CoreModule接收到的模块Prompt中标识模块名称

View File

@@ -1,5 +1,6 @@
package work.slhaf.partner.module.modules.action.identifier;
import com.alibaba.fastjson2.JSONObject;
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.InjectModule;
@@ -21,10 +22,8 @@ import work.slhaf.partner.module.modules.action.identifier.recognizer.entity.Rec
import work.slhaf.partner.module.modules.action.identifier.recognizer.entity.RecognizerResult;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -38,7 +37,7 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
@InjectModule
private InterventionEvaluator interventionEvaluator;
@InjectModule
private InterventionHandler InterventionHandler;
private InterventionHandler interventionHandler;
@InjectCapability
private ActionCapability actionCapability;
@@ -51,7 +50,7 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
* 键: 本次调用uuid
* 值本次调用对应的prompt
*/
private Map<String, HashMap<String, String>> interventionPrompt = new HashMap<>();
private final Map<String, Map<String, String>> interventionPrompt = new HashMap<>();
@Override
protected void doExecute(PartnerRunningFlowContext context) {
@@ -72,16 +71,35 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
EvaluatorResult evaluatorResult = interventionEvaluator
.execute(buildEvaluatorInput(recognizedInterventions.keySet(), userId));
List<EvaluatedInterventionData> interventions = evaluatorResult.getDataList();
if (evaluatorResult.isOk()) {
if (evaluatorResult.isOk() && isActionKeysExist(interventions)) {
setupErrorInterventionPrompt(uuid);
} else if (evaluatorResult.isOk()) {
// 同步写入prompt异步处理干预行为
setupInterventionPrompt(uuid, interventions);
InterventionHandler.execute(buildHandlerInput(interventions));
interventionHandler.execute(buildHandlerInput(interventions));
} else {
// 同步写入prompt
setupInterventionIgnoredPrompt(uuid, interventions);
}
}
private void setupErrorInterventionPrompt(String uuid) {
interventionPrompt.put(uuid, Map.of(
"[识别状态] <是否识别到干预已存在行动的意图>", "识别出但出现了不存在的行动单元key",
"[干预行动] <将对已存在行动做出的行为>", "无行为"
));
}
private boolean isActionKeysExist(List<EvaluatedInterventionData> interventions) {
for (EvaluatedInterventionData intervention : interventions) {
String[] array = intervention.getActions().values().toArray(new String[0]);
if (!actionCapability.checkExists(array)) {
return false;
}
}
return true;
}
private HandlerInput buildHandlerInput(List<EvaluatedInterventionData> interventions) {
HandlerInput input = new HandlerInput();
List<HandlerInputData> inputDataList = input.getData();
@@ -97,15 +115,55 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
}
private void setupInterventionIgnoredPrompt(String uuid, List<EvaluatedInterventionData> dataList) {
String s = dataList.stream()
.map(data -> JSONObject.of(
"[干预倾向]", data.getTendency(),
"[未采用原因]", data.getDescription()).toString())
.collect(Collectors.joining(",", "[", "]"));
interventionPrompt.put(uuid, Map.of(
"[识别状态] <是否识别到干预已存在行动的意图>", "识别到,但都未采用",
"[忽略原因] <各个意图被忽略的原因>", s,
"[干预行动] <将对已存在行动做出的行为>", "无行为"
));
}
private void setupInterventionPrompt(String uuid, List<EvaluatedInterventionData> dataList) {
List<Map<String, String>> contents = new ArrayList<>();
List<String> actions = new ArrayList<>();
for (EvaluatedInterventionData data : dataList) {
if (!data.isOk()) {
continue;
}
String tendency = data.getTendency();
contents.add(Map.of(
"[干预倾向]", tendency,
"[干预类型]", data.getType().toString(),
"[行动链变动情况]", getActionChainStr(data.getActions())
));
actions.add(tendency);
}
interventionPrompt.put(uuid, Map.of(
"[识别状态] <是否识别到干预已存在行动的意图>", "识别到,将采用",
"[具体内容] <各个干预意图对应的具体信息>", contents.toString(),
"[干预行动] <将对已存在行动做出的行为>", actions.toString()
));
}
private String getActionChainStr(LinkedHashMap<Integer, String> actions) {
ArrayList<String> list = new ArrayList<>();
//虽说actionCapability那边做了异常抛出但说实话很明显放在这里不好处理啊🤔还是在前边统一检查一下吧
actions.forEach((order, actionKey) -> {
list.add(order + ":" + actionCapability.loadMetaActionInfo(actionKey).getDescription());
});
return list.toString();
}
private void setupNoInterventionPrompt(String uuid) {
interventionPrompt.put(uuid, Map.of(
"[识别状态] <是否识别到干预已存在行动的意图>", "未识别到干预意图",
"[干预行动] <将对已存在行动做出的行为>", "无行动"));
}
private EvaluatorInput buildEvaluatorInput(Set<String> interventionTendencies, String userId) {
@@ -137,8 +195,8 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
}
@Override
protected HashMap<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
return interventionPrompt.get(context.getUuid());
protected Map<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
return interventionPrompt.remove(context.getUuid());
}
@Override

View File

@@ -159,7 +159,7 @@ public class ActionPlanner extends PreRunningModule {
@Override
protected HashMap<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
protected Map<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
HashMap<String, String> map = new HashMap<>();
String userId = context.getUserId();
setupPendingActions(map, userId);
@@ -170,22 +170,22 @@ public class ActionPlanner extends PreRunningModule {
private void setupPendingActions(HashMap<String, String> map, String userId) {
List<ActionData> actionData = actionCapability.listPendingAction(userId);
if (actionData == null || actionData.isEmpty()) {
map.put("[待确认行动] <确认行动信息>", "无待确认行动");
map.put("[待确认行动] <等待用户确认行动信息>", "无待确认行动");
return;
}
for (int i = 0; i < actionData.size(); i++) {
map.put("[待确认行动 " + (i + 1) + " ]", generateActionStr(actionData.get(i)));
map.put("[待确认行动 " + (i + 1) + " ] <等待用户确认的行动信息>", generateActionStr(actionData.get(i)));
}
}
private void setupPreparedActions(HashMap<String, String> map, String userId) {
List<ActionData> actionData = actionCapability.listPreparedAction(userId);
if (actionData == null || actionData.isEmpty()) {
map.put("[预备行动] <预备行动信息>", "无预备行动");
map.put("[预备行动] <预备执行或放入计划池的行动信息>", "无预备行动");
return;
}
for (int i = 0; i < actionData.size(); i++) {
map.put("[预备行动 " + (i + 1) + " ]", generateActionStr(actionData.get(i)));
map.put("[预备行动 " + (i + 1) + " ] <预备执行或放入计划池的行动信息>", generateActionStr(actionData.get(i)));
}
}

View File

@@ -23,10 +23,7 @@ import work.slhaf.partner.module.modules.memory.selector.extractor.entity.Extrac
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.*;
@EqualsAndHashCode(callSuper = true)
@Data
@@ -133,7 +130,7 @@ public class MemorySelector extends PreRunningModule {
}
@Override
protected HashMap<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
protected Map<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
HashMap<String, String> map = new HashMap<>();
String userId = context.getUserId();
String dialogMapStr = memoryCapability.getDialogMapStr();
@@ -148,7 +145,7 @@ public class MemorySelector extends PreRunningModule {
String sliceStr = memoryCapability.getActivatedSlicesStr(userId);
if (sliceStr != null && !sliceStr.isEmpty()) {
map.put("[记忆切片] <你与最新一条消息的发送者的相关回忆, 不会与[记忆缓存]重复, 如果有重复你也可以指出来()>", sliceStr);
map.put("[记忆切片] <你与最新一条消息的发送者的相关回忆, 不会与[记忆缓存]重复, 如果有重复你也可以指出来>", sliceStr);
}
return map;
}

View File

@@ -10,6 +10,7 @@ import work.slhaf.partner.module.common.module.PreRunningModule;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Setter
@@ -24,7 +25,7 @@ public class PerceiveSelector extends PreRunningModule {
}
@Override
protected HashMap<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
protected Map<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
HashMap<String, String> map = new HashMap<>();
User user = perceiveCapability.getUser(context.getUserId());
map.put("[关系] <你与最新聊天用户的关系>", user.getRelation());

View File

@@ -15,6 +15,7 @@ import work.slhaf.partner.runtime.interaction.data.context.subcontext.CoreContex
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
@EqualsAndHashCode(callSuper = true)
@Data
@@ -58,7 +59,7 @@ public class PreprocessExecutor extends PreRunningModule {
@Override
protected HashMap<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
protected Map<String, String> getPromptDataMap(PartnerRunningFlowContext context) {
HashMap<String, String> map = new HashMap<>();
map.put("text", "这部分才是真正的用户输入内容, 就像你之前收到过的输入一样。但...不会是'同一个人'。");
map.put("datetime", "本次用户输入对应的当前时间");