推进行动干预模块; 接下来将进一步完善 InterventionHandler 的具体内容

- 调整相关目录为 interventor
-  调整了某些 ActionInterventor 的子模块用到的数据类结构
- 完善了 InterventionEvaluator 的具体逻辑
- 为 InterventionType 添加了注释,并新增了 CANCEL 干预类型
This commit is contained in:
2025-11-11 16:11:09 +08:00
parent a1520f117b
commit 264cdb09e5
14 changed files with 195 additions and 83 deletions

View File

@@ -1,28 +0,0 @@
package work.slhaf.partner.module.modules.action.identifier.evaluator;
import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule;
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.module.modules.action.identifier.evaluator.entity.EvaluatorInput;
import work.slhaf.partner.module.modules.action.identifier.evaluator.entity.EvaluatorResult;
@AgentSubModule
public class InterventionEvaluator extends AgentRunningSubModule<EvaluatorInput, EvaluatorResult> implements ActivateModel {
@Override
public EvaluatorResult execute(EvaluatorInput data) {
//基于干预意图、记忆切片、交互上下文、已有行动程序综合评估,尝试选取出合适的行动程序,对目标行动链做出调整
return null;
}
@Override
public String modelKey() {
return "intervention_evaluator";
}
@Override
public boolean withBasicPrompt() {
return true;
}
}

View File

@@ -1,16 +0,0 @@
package work.slhaf.partner.module.modules.action.identifier.handler;
import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
import work.slhaf.partner.module.modules.action.identifier.handler.entity.HandlerInput;
@AgentSubModule
public class InterventionHandler extends AgentRunningSubModule<HandlerInput,Void> {
@Override
public Void execute(HandlerInput data) {
return null;
}
}

View File

@@ -1,5 +0,0 @@
package work.slhaf.partner.module.modules.action.identifier.handler.entity;
public enum InterventionType {
APPEND, INSERT, REBUILD, DELETE
}

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.action.identifier; package work.slhaf.partner.module.modules.action.interventor;
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.capability.annotation.InjectCapability;
@@ -10,16 +10,16 @@ import work.slhaf.partner.core.action.ActionCore.PhaserRecord;
import work.slhaf.partner.core.cognation.CognationCapability; import work.slhaf.partner.core.cognation.CognationCapability;
import work.slhaf.partner.core.memory.MemoryCapability; import work.slhaf.partner.core.memory.MemoryCapability;
import work.slhaf.partner.module.common.module.PreRunningModule; import work.slhaf.partner.module.common.module.PreRunningModule;
import work.slhaf.partner.module.modules.action.identifier.evaluator.InterventionEvaluator; import work.slhaf.partner.module.modules.action.interventor.evaluator.InterventionEvaluator;
import work.slhaf.partner.module.modules.action.identifier.evaluator.entity.EvaluatorInput; import work.slhaf.partner.module.modules.action.interventor.evaluator.entity.EvaluatorInput;
import work.slhaf.partner.module.modules.action.identifier.evaluator.entity.EvaluatorResult; import work.slhaf.partner.module.modules.action.interventor.evaluator.entity.EvaluatorResult;
import work.slhaf.partner.module.modules.action.identifier.evaluator.entity.EvaluatorResult.EvaluatedInterventionData; import work.slhaf.partner.module.modules.action.interventor.evaluator.entity.EvaluatorResult.EvaluatedInterventionData;
import work.slhaf.partner.module.modules.action.identifier.handler.InterventionHandler; import work.slhaf.partner.module.modules.action.interventor.handler.InterventionHandler;
import work.slhaf.partner.module.modules.action.identifier.handler.entity.HandlerInput; import work.slhaf.partner.module.modules.action.interventor.handler.entity.HandlerInput;
import work.slhaf.partner.module.modules.action.identifier.handler.entity.HandlerInput.HandlerInputData; import work.slhaf.partner.module.modules.action.interventor.handler.entity.HandlerInput.HandlerInputData;
import work.slhaf.partner.module.modules.action.identifier.recognizer.InterventionRecognizer; import work.slhaf.partner.module.modules.action.interventor.recognizer.InterventionRecognizer;
import work.slhaf.partner.module.modules.action.identifier.recognizer.entity.RecognizerInput; import work.slhaf.partner.module.modules.action.interventor.recognizer.entity.RecognizerInput;
import work.slhaf.partner.module.modules.action.identifier.recognizer.entity.RecognizerResult; import work.slhaf.partner.module.modules.action.interventor.recognizer.entity.RecognizerResult;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
import java.util.*; import java.util.*;
@@ -60,23 +60,23 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
String uuid = context.getUuid(); String uuid = context.getUuid();
String userId = context.getUserId(); String userId = context.getUserId();
RecognizerResult recognizerResult = interventionRecognizer RecognizerResult recognizerResult = interventionRecognizer
.execute(buildRecognizerInput(userId, context.getInput())); .execute(buildRecognizerInput(userId, context.getInput())); //此处的输入内容携带了所有 PhaserRecord
if (!recognizerResult.isOk()) { if (!recognizerResult.isOk()) {
// 设置相应prompt // 设置相应prompt
setupNoInterventionPrompt(uuid); setupNoInterventionPrompt(uuid);
return; return;
} }
// 存在则进一步评估评估通过则并直接添加行动程序至对应行动链 // 存在则进一步评估评估通过则并直接添加行动程序至对应行动链
Map<String, PhaserRecord> recognizedInterventions = recognizerResult.getInterventions(); Map<String, PhaserRecord> recognizedInterventions = recognizerResult.getInterventions(); //这里的 PhaserRecord 已包含从 ActionCore 获取到的执行状态下的行动及其Phaser实例
EvaluatorResult evaluatorResult = interventionEvaluator EvaluatorResult evaluatorResult = interventionEvaluator
.execute(buildEvaluatorInput(recognizedInterventions.keySet(), userId)); .execute(buildEvaluatorInput(recognizedInterventions, userId));
List<EvaluatedInterventionData> interventions = evaluatorResult.getDataList(); List<EvaluatedInterventionData> interventions = evaluatorResult.getDataList(); //这里的 EvaluatedInterventionData 中的 tendency 即为 recognizedInterventions 中的键
if (evaluatorResult.isOk() && isActionKeysExist(interventions)) { if (evaluatorResult.isOk() && isActionKeysExist(interventions)) {
setupErrorInterventionPrompt(uuid); setupErrorInterventionPrompt(uuid);
} else if (evaluatorResult.isOk()) { } else if (evaluatorResult.isOk()) {
// 同步写入prompt异步处理干预行为 // 同步写入prompt异步处理干预行为异步 interventionHandler 中体现
setupInterventionPrompt(uuid, interventions); setupInterventionPrompt(uuid, interventions);
interventionHandler.execute(buildHandlerInput(interventions)); interventionHandler.execute(buildHandlerInput(interventions, recognizedInterventions));
} else { } else {
// 同步写入prompt // 同步写入prompt
setupInterventionIgnoredPrompt(uuid, interventions); setupInterventionIgnoredPrompt(uuid, interventions);
@@ -100,7 +100,7 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
return true; return true;
} }
private HandlerInput buildHandlerInput(List<EvaluatedInterventionData> interventions) { private HandlerInput buildHandlerInput(List<EvaluatedInterventionData> interventions, Map<String,PhaserRecord> recognizedInterventions) {
HandlerInput input = new HandlerInput(); HandlerInput input = new HandlerInput();
List<HandlerInputData> inputDataList = input.getData(); List<HandlerInputData> inputDataList = input.getData();
for (EvaluatedInterventionData interventionData : interventions) { for (EvaluatedInterventionData interventionData : interventions) {
@@ -109,6 +109,7 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
inputData.setDescription(interventionData.getDescription()); inputData.setDescription(interventionData.getDescription());
inputData.setType(interventionData.getType()); inputData.setType(interventionData.getType());
inputData.setActions(interventionData.getActions()); inputData.setActions(interventionData.getActions());
inputData.setRecord(recognizedInterventions.get(interventionData.getTendency()));
inputDataList.add(inputData); inputDataList.add(inputData);
} }
return input; return input;
@@ -166,9 +167,9 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
"[干预行动] <将对已存在行动做出的行为>", "无行动")); "[干预行动] <将对已存在行动做出的行为>", "无行动"));
} }
private EvaluatorInput buildEvaluatorInput(Set<String> interventionTendencies, String userId) { private EvaluatorInput buildEvaluatorInput(Map<String,PhaserRecord> recognizedInterventions, String userId) {
EvaluatorInput input = new EvaluatorInput(); EvaluatorInput input = new EvaluatorInput();
input.setInterventionTendencies(interventionTendencies); input.setInterventionTendencies(recognizedInterventions);
input.setRecentMessages(cognationCapability.getChatMessages()); input.setRecentMessages(cognationCapability.getChatMessages());
input.setActivatedSlices(memoryCapability.getActivatedSlices(userId)); input.setActivatedSlices(memoryCapability.getActivatedSlices(userId));
return input; return input;

View File

@@ -0,0 +1,92 @@
package work.slhaf.partner.module.modules.action.interventor.evaluator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
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.runtime.interaction.flow.abstracts.ActivateModel;
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.Message;
import work.slhaf.partner.core.action.ActionCapability;
import work.slhaf.partner.core.action.ActionCore.ExecutorType;
import work.slhaf.partner.core.action.ActionCore.PhaserRecord;
import work.slhaf.partner.core.memory.pojo.EvaluatedSlice;
import work.slhaf.partner.module.modules.action.interventor.evaluator.entity.EvaluatorInput;
import work.slhaf.partner.module.modules.action.interventor.evaluator.entity.EvaluatorResult;
import work.slhaf.partner.module.modules.action.interventor.evaluator.entity.EvaluatorResult.EvaluatedInterventionData;
@Slf4j
@AgentSubModule
public class InterventionEvaluator extends AgentRunningSubModule<EvaluatorInput, EvaluatorResult>
implements ActivateModel {
@InjectCapability
private ActionCapability actionCapability;
@Override
public EvaluatorResult execute(EvaluatorInput data) {
// 基于干预意图、记忆切片、交互上下文、已有行动程序综合评估,尝试评估并选取出合适的行动程序,交付给 ActionInterventor
EvaluatorResult result = new EvaluatorResult();
List<EvaluatedInterventionData> evaluatedDataList = result.getDataList();
Map<String, PhaserRecord> interventionTendencies = data.getInterventionTendencies();
Set<String> tendencies = interventionTendencies.keySet();
ExecutorService executor = actionCapability.getExecutor(ExecutorType.VIRTUAL);
CountDownLatch latch = new CountDownLatch(tendencies.size());
tendencies.forEach(tendency -> {
executor.execute(() -> {
try {
String input = buildPrompt(data.getRecentMessages(), data.getActivatedSlices(),
interventionTendencies.get(tendency), tendency);
ChatResponse response = singleChat(input);
EvaluatedInterventionData evaluatedData = JSONObject.parseObject(response.getMessage(),
EvaluatedInterventionData.class);
synchronized (evaluatedDataList) {
evaluatedDataList.add(evaluatedData);
}
} catch (Exception e) {
log.error("干预意图评估出错: " + tendency, e);
} finally {
latch.countDown();
}
});
});
try {
latch.await();
} catch (InterruptedException e) {
log.warn("CountDownLatch阻塞已中断");
}
return result;
}
private String buildPrompt(List<Message> recentMessages, List<EvaluatedSlice> activatedSlices,
PhaserRecord phaserRecord, String tendency) {
JSONObject json = new JSONObject();
json.put("干预倾向", tendency);
json.putArray("近期对话").addAll(recentMessages);
json.putArray("参考记忆").addAll(activatedSlices);
json.put("将干预的行动", JSONObject.toJSONString(phaserRecord.actionData()));
return json.toJSONString();
}
@Override
public String modelKey() {
return "intervention_evaluator";
}
@Override
public boolean withBasicPrompt() {
return false;
}
}

View File

@@ -1,15 +1,16 @@
package work.slhaf.partner.module.modules.action.identifier.evaluator.entity; package work.slhaf.partner.module.modules.action.interventor.evaluator.entity;
import lombok.Data; import lombok.Data;
import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.api.chat.pojo.Message;
import work.slhaf.partner.core.action.ActionCore.PhaserRecord;
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.Set; import java.util.Map;
@Data @Data
public class EvaluatorInput { public class EvaluatorInput {
private Set<String> interventionTendencies; private Map<String,PhaserRecord> interventionTendencies;
private List<EvaluatedSlice> activatedSlices; private List<EvaluatedSlice> activatedSlices;
private List<Message> recentMessages; private List<Message> recentMessages;
} }

View File

@@ -1,10 +1,11 @@
package work.slhaf.partner.module.modules.action.identifier.evaluator.entity; package work.slhaf.partner.module.modules.action.interventor.evaluator.entity;
import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import lombok.Data; import lombok.Data;
import work.slhaf.partner.module.modules.action.identifier.handler.entity.InterventionType; import work.slhaf.partner.module.modules.action.interventor.handler.entity.InterventionType;
/** /**
* 干预倾向评估结果包含评估通过的倾向文本对行动链的行为指定操作的行动单元key未通过的原因 * 干预倾向评估结果包含评估通过的倾向文本对行动链的行为指定操作的行动单元key未通过的原因
@@ -15,7 +16,7 @@ public class EvaluatorResult {
* 是否存在通过的干预倾向 * 是否存在通过的干预倾向
*/ */
private boolean ok; private boolean ok;
private List<EvaluatedInterventionData> dataList; private List<EvaluatedInterventionData> dataList = new ArrayList<>();
@Data @Data
public static class EvaluatedInterventionData { public static class EvaluatedInterventionData {

View File

@@ -0,0 +1,36 @@
package work.slhaf.partner.module.modules.action.interventor.handler;
import java.util.List;
import java.util.concurrent.ExecutorService;
import lombok.extern.slf4j.Slf4j;
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.runtime.interaction.flow.abstracts.AgentRunningSubModule;
import work.slhaf.partner.core.action.ActionCapability;
import work.slhaf.partner.core.action.ActionCore.ExecutorType;
import work.slhaf.partner.module.modules.action.interventor.handler.entity.HandlerInput;
import work.slhaf.partner.module.modules.action.interventor.handler.entity.HandlerInput.HandlerInputData;
@Slf4j
@AgentSubModule
public class InterventionHandler extends AgentRunningSubModule<HandlerInput, Void> {
@InjectCapability
private ActionCapability actionCapability;
@Override
public Void execute(HandlerInput data) {
ExecutorService executor = actionCapability.getExecutor(ExecutorType.VIRTUAL);
executor.execute(() -> {
log.debug("干预开始执行");
List<HandlerInputData> dataList = data.getData();
for (HandlerInputData inputData : dataList) {
log.debug("干预操作: {}, 干预类型: {}",inputData.getTendency(),inputData.getType());
}
});
return null;
}
}

View File

@@ -1,10 +1,11 @@
package work.slhaf.partner.module.modules.action.identifier.handler.entity; package work.slhaf.partner.module.modules.action.interventor.handler.entity;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import lombok.Data; import lombok.Data;
import work.slhaf.partner.core.action.ActionCore.PhaserRecord;
@Data @Data
public class HandlerInput { public class HandlerInput {
@@ -17,5 +18,6 @@ public class HandlerInput {
private String description; private String description;
private InterventionType type; private InterventionType type;
private LinkedHashMap<Integer,String> actions; private LinkedHashMap<Integer,String> actions;
private PhaserRecord record;
} }
} }

View File

@@ -0,0 +1,28 @@
package work.slhaf.partner.module.modules.action.interventor.handler.entity;
public enum InterventionType {
/**
* 追加行动: 追加至指定行动链序列之后才执行
*/
APPEND,
/**
* 插入行动: 指定行动链序列执行过程中即时新增并执行
*/
INSERT,
/**
* 重建行动: 重建指定行动链序列之后的所有行动内容
*/
REBUILD,
/**
* 删除行动: 删除指定行动链序列上的指定行动单元
*/
DELETE,
/**
* 取消行动链: 中断并取消指定行动链的执行
*/
CANCEL
}

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.action.identifier.recognizer; package work.slhaf.partner.module.modules.action.interventor.recognizer;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -10,9 +10,9 @@ import work.slhaf.partner.api.chat.pojo.ChatResponse;
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.ActionData;
import work.slhaf.partner.module.modules.action.identifier.recognizer.entity.MetaRecognizerResult; import work.slhaf.partner.module.modules.action.interventor.recognizer.entity.MetaRecognizerResult;
import work.slhaf.partner.module.modules.action.identifier.recognizer.entity.RecognizerInput; import work.slhaf.partner.module.modules.action.interventor.recognizer.entity.RecognizerInput;
import work.slhaf.partner.module.modules.action.identifier.recognizer.entity.RecognizerResult; import work.slhaf.partner.module.modules.action.interventor.recognizer.entity.RecognizerResult;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.action.identifier.recognizer.entity; package work.slhaf.partner.module.modules.action.interventor.recognizer.entity;
import lombok.Data; import lombok.Data;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.action.identifier.recognizer.entity; package work.slhaf.partner.module.modules.action.interventor.recognizer.entity;
import lombok.Data; import lombok.Data;
import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.api.chat.pojo.Message;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.action.identifier.recognizer.entity; package work.slhaf.partner.module.modules.action.interventor.recognizer.entity;
import lombok.Data; import lombok.Data;
import work.slhaf.partner.core.action.ActionCore; import work.slhaf.partner.core.action.ActionCore;