From 3b236286b953de7c76751cf5f84b90b30651d7f5 Mon Sep 17 00:00:00 2001 From: slhafzjw Date: Sun, 5 Apr 2026 22:32:52 +0800 Subject: [PATCH] refactor(action): remove problematic action tendency cache --- .../partner/core/action/ActionCapability.java | 5 - .../slhaf/partner/core/action/ActionCore.java | 158 +-------------- .../action/entity/cache/ActionCacheData.java | 181 ------------------ .../module/action/planner/ActionPlanner.java | 25 --- .../planner/extractor/ActionExtractor.java | 14 +- 5 files changed, 6 insertions(+), 377 deletions(-) delete mode 100644 Partner-Core/src/main/java/work/slhaf/partner/core/action/entity/cache/ActionCacheData.java diff --git a/Partner-Core/src/main/java/work/slhaf/partner/core/action/ActionCapability.java b/Partner-Core/src/main/java/work/slhaf/partner/core/action/ActionCapability.java index 379cd87f..ab6633e5 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/core/action/ActionCapability.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/core/action/ActionCapability.java @@ -6,7 +6,6 @@ import work.slhaf.partner.api.agent.factory.capability.annotation.Capability; import work.slhaf.partner.core.action.entity.ExecutableAction; 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 work.slhaf.partner.core.action.entity.intervention.MetaIntervention; import work.slhaf.partner.core.action.runner.RunnerClient; @@ -22,10 +21,6 @@ public interface ActionCapability { Set listActions(@Nullable ExecutableAction.Status status, @Nullable String source); - List selectTendencyCache(String input); - - void updateTendencyCache(CacheAdjustData data); - ExecutorService getExecutor(ActionCore.ExecutorType type); MetaAction loadMetaAction(@NonNull String actionKey); diff --git a/Partner-Core/src/main/java/work/slhaf/partner/core/action/ActionCore.java b/Partner-Core/src/main/java/work/slhaf/partner/core/action/ActionCore.java index 7e01989e..be0c1cba 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/core/action/ActionCore.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/core/action/ActionCore.java @@ -6,14 +6,10 @@ import lombok.val; import org.jetbrains.annotations.Nullable; import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore; import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod; -import work.slhaf.partner.common.vector.VectorClient; import work.slhaf.partner.core.PartnerCore; import work.slhaf.partner.core.action.entity.ExecutableAction; import work.slhaf.partner.core.action.entity.MetaAction; import work.slhaf.partner.core.action.entity.MetaActionInfo; -import work.slhaf.partner.core.action.entity.cache.ActionCacheData; -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.intervention.InterventionType; import work.slhaf.partner.core.action.entity.intervention.MetaIntervention; import work.slhaf.partner.core.action.exception.MetaActionNotFoundException; @@ -26,8 +22,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; @SuppressWarnings("FieldMayBeFinal") @@ -37,11 +31,10 @@ public class ActionCore extends PartnerCore { public static final String BUILTIN_LOCATION = "builtin"; public static final String ORIGIN_LOCATION = "origin"; - private final Lock cacheLock = new ReentrantLock(); // 由于当前的执行器逻辑实现,平台线程池大小不得小于 2,这里规定为最小为 4 - private final ExecutorService platformExecutor = Executors - .newFixedThreadPool(Math.max(Runtime.getRuntime().availableProcessors(), 4)); + private final ExecutorService platformExecutor = Executors.newFixedThreadPool(Math.max(Runtime.getRuntime().availableProcessors(), 4)); private final ExecutorService virtualExecutor = Executors.newVirtualThreadPerTaskExecutor(); + /** * 已存在的行动程序,键格式为‘::’,值为 MCP Server 通过 Resources 相关渠道传递的行动程序元信息 */ @@ -50,10 +43,7 @@ public class ActionCore extends PartnerCore { * 持久行动池 */ private CopyOnWriteArraySet actionPool = new CopyOnWriteArraySet<>(); - /** - * 语义缓存与行为倾向映射 - */ - private List actionCache = new ArrayList<>(); + private RunnerClient runnerClient; public ActionCore() throws IOException, ClassNotFoundException { @@ -85,59 +75,6 @@ public class ActionCore extends PartnerCore { .collect(Collectors.toSet()); } - /** - * 计算输入内容的语义向量,根据与{@link ActionCacheData#getInputVector()}的相似度挑取缓存,后续将根据评估结果来更新计数 - * - * @param input 本次输入内容 - * @return 命中的行为倾向集合 - */ - @CapabilityMethod - public List selectTendencyCache(String input) { - if (!VectorClient.status) { - return null; - } - VectorClient vectorClient = VectorClient.INSTANCE; - // 计算本次输入的向量 - float[] vector = vectorClient.compute(input); - if (vector == null) - return null; - // 与现有缓存比对,将匹配到的收集并返回 - return actionCache.parallelStream() - .filter(ActionCacheData::isActivated) - .filter(data -> { - double compared = vectorClient.compare(vector, data.getInputVector()); - return compared > data.getThreshold(); - }) - .map(ActionCacheData::getTendency) - .collect(Collectors.toList()); - } - - @CapabilityMethod - public void updateTendencyCache(CacheAdjustData data) { - VectorClient vectorClient = VectorClient.INSTANCE; - List list = data.getMetaDataList(); - String input = data.getInput(); - float[] inputVector = vectorClient.compute(input); - - List matchAndPassed = new ArrayList<>(); - List matchNotPassed = new ArrayList<>(); - List notMatchPassed = new ArrayList<>(); - - for (CacheAdjustMetaData metaData : list) { - if (metaData.isHit() && metaData.isPassed()) { - matchAndPassed.add(metaData); - } else if (metaData.isHit()) { - matchNotPassed.add(metaData); - } else if (!metaData.isPassed()) { - notMatchPassed.add(metaData); - } - } - - platformExecutor.execute(() -> adjustMatchAndPassed(matchAndPassed, inputVector, input, vectorClient)); - platformExecutor.execute(() -> adjustMatchNotPassed(matchNotPassed, vectorClient)); - platformExecutor.execute(() -> adjustNotMatchPassed(notMatchPassed, inputVector, input, vectorClient)); - } - @CapabilityMethod public ExecutorService getExecutor(ExecutorType type) { return switch (type) { @@ -291,95 +228,6 @@ public class ActionCore extends PartnerCore { executableAction.getHistory().clear(); } - /** - * 命中缓存且评估通过时 - * - * @param matchAndPassed 该类型的带调整缓存信息列表 - * @param inputVector 本次输入内容的语义向量 - * @param vectorClient 向量客户端 - */ - private void adjustMatchAndPassed(List matchAndPassed, float[] inputVector, String input, - VectorClient vectorClient) { - matchAndPassed.forEach(adjustData -> { - // 获取原始缓存条目 - String tendency = adjustData.getTendency(); - ActionCacheData primaryCacheData = selectCacheData(tendency); - if (primaryCacheData == null) { - return; - } - primaryCacheData.updateAfterMatchAndPassed(inputVector, vectorClient, input); - }); - } - - /** - * 针对命中缓存、但评估未通过的条目与输入进行处理 - * - * @param matchNotPassed 该类型的带调整缓存信息列表 - * @param vectorClient 向量客户端 - */ - private void adjustMatchNotPassed(List matchNotPassed, VectorClient vectorClient) { - List toRemove = new ArrayList<>(); - matchNotPassed.forEach(adjustData -> { - // 获取原始缓存条目 - String tendency = adjustData.getTendency(); - ActionCacheData primaryCacheData = selectCacheData(tendency); - if (primaryCacheData == null) { - return; - } - boolean remove = primaryCacheData.updateAfterMatchNotPassed(vectorClient); - if (remove) { - toRemove.add(primaryCacheData); - } - - }); - cacheLock.lock(); - actionCache.removeAll(toRemove); - cacheLock.unlock(); - } - - /** - * 针对未命中但评估通过的缓存做出调整: - *
    - *

    如果存在缓存条目

    - *
  1. - * 若已生效,但此时未匹配到则说明尚未生效或者阈值、向量{@link ActionCacheData#getInputVector()}存在问题,调低阈值,同时带权移动平均 - *
  2. - *
  3. - * 若未生效,则只增加计数并带权移动平均 - *
  4. - *
- * 如果不存在缓存条目,则新增并填充字段 - * - * @param notMatchPassed 该类型的带调整缓存信息列表 - * @param inputVector 本次输入内容的语义向量 - * @param input 本次输入内容 - * @param vectorClient 向量客户端 - */ - private void adjustNotMatchPassed(List notMatchPassed, float[] inputVector, String input, - VectorClient vectorClient) { - notMatchPassed.forEach(adjustData -> { - // 获取原始缓存条目 - String tendency = adjustData.getTendency(); - ActionCacheData primaryCacheData = selectCacheData(tendency); - float[] tendencyVector = vectorClient.compute(tendency); - if (primaryCacheData == null) { - actionCache.add(new ActionCacheData(tendency, tendencyVector, inputVector, input)); - return; - } - primaryCacheData.updateAfterNotMatchPassed(input, inputVector, tendencyVector, vectorClient); - }); - } - - private ActionCacheData selectCacheData(String tendency) { - for (ActionCacheData actionCacheData : actionCache) { - if (actionCacheData.getTendency().equals(tendency)) { - return actionCacheData; - } - } - log.warn("[{}] 未找到行为倾向[{}]对应的缓存条目,可能是代码逻辑存在错误", getCoreKey(), tendency); - return null; - } - @Override protected String getCoreKey() { return "action-core"; diff --git a/Partner-Core/src/main/java/work/slhaf/partner/core/action/entity/cache/ActionCacheData.java b/Partner-Core/src/main/java/work/slhaf/partner/core/action/entity/cache/ActionCacheData.java deleted file mode 100644 index 38deccd7..00000000 --- a/Partner-Core/src/main/java/work/slhaf/partner/core/action/entity/cache/ActionCacheData.java +++ /dev/null @@ -1,181 +0,0 @@ -package work.slhaf.partner.core.action.entity.cache; - -import lombok.Data; -import work.slhaf.partner.common.vector.VectorClient; - -import java.util.ArrayList; -import java.util.List; - -@Data -public class ActionCacheData { - private boolean activated = false; - private int inputMatchCount = 1; - - private float[] inputVector; - private float[] tendencyVector; - private String tendency; - private double threshold = 0.75; - - private List validSamples = new ArrayList<>(); - private int failedCount = 0; - private Type type = Type.PRIMARY; - - public ActionCacheData(String tendency, float[] tendencyVector, float[] inputVector, String input) { - this.tendency = tendency; - this.inputVector = inputVector; - this.tendencyVector = tendencyVector; - this.validSamples.add(input); - } - - /** - * 命中缓存且评估通过时,根据输入内容的语义向量与现有的输入语义向量进行带权移动平均,以相似度为权重,同时降低失败计数,为零时置为上一级缓存类型{@link ActionCacheData.Type} - * - * @param inputVector 本次输入内容对应的语义向量 - * @param vectorClient 向量客户端 - * @param input 本次输入内容 - */ - public synchronized void updateAfterMatchAndPassed(float[] inputVector, VectorClient vectorClient, String input) { - updateInputVector(inputVector, vectorClient); - addValidSample(input); - reduceFailedCount(); - updateType(); - addInputMatchCount(); - } - - private void updateType() { - if (this.failedCount == 0) { - this.type = switch (type) { - case PRIMARY, REBUILD_V1 -> ActionCacheData.Type.PRIMARY; - case REBUILD_V2 -> ActionCacheData.Type.REBUILD_V1; - case REBUILD_V3 -> ActionCacheData.Type.REBUILD_V2; - }; - } - } - - private void reduceFailedCount() { - this.failedCount = Math.max(this.failedCount - 1, 0); - } - - private void addValidSample(String input) { - if (this.validSamples.size() == 12) { - this.validSamples.removeFirst(); - } - this.validSamples.add(input); - } - - private void updateInputVector(float[] inputVector, VectorClient vectorClient) { - this.inputVector = vectorClient.weightedAverage(inputVector, this.inputVector); - } - - /** - * 针对命中缓存、但评估未通过的条目与输入进行处理: 增加失败计数(必要时重建并更新类型等级)、调高阈值(0.02),由于缓存匹配但评估未通过,所以不进行带权移动平均 - * - * @param vectorClient 向量客户端 - * @return 是否需要删除(已在REBUILD_V3状态且达到最大误判次数的) - */ - public synchronized boolean updateAfterMatchNotPassed(VectorClient vectorClient) { - adjustThreshold(); - addFailedCount(); - if (this.failedCount < 3) { - return false; - } - if (this.type == Type.REBUILD_V3) { - return true; - } - rebuildAndSwitchType(vectorClient); - return false; - } - - private void rebuildAndSwitchType(VectorClient vectorClient) { - this.type = switch (this.type) { - case PRIMARY -> { - //样本顺序反转后,以全部样本重建 - this.validSamples = this.validSamples.reversed(); - rebuildWithSamples(vectorClient); - yield Type.REBUILD_V1; - } - case REBUILD_V1 -> { - //截取后一半样本,反转后以此重建 - List temp = this.validSamples.subList(this.validSamples.size() / 2, this.validSamples.size()); - this.validSamples = temp.reversed(); - rebuildWithSamples(vectorClient); - yield Type.REBUILD_V2; - } - case REBUILD_V2 -> { - //截取后四分之一样本,反转后以此重建 - List temp = this.validSamples.subList(this.validSamples.size() / 4, this.validSamples.size()); - this.validSamples = temp.reversed(); - rebuildWithSamples(vectorClient); - yield Type.REBUILD_V3; - } - case REBUILD_V3 -> null; - }; - //阈值减0.05,防止重建后一直升高 - this.threshold = Math.max(this.threshold - 0.05, 0.75); - this.failedCount = 0; - } - - private void rebuildWithSamples(VectorClient vectorClient) { - for (int i = 0; i < this.validSamples.size(); i++) { - String sample = this.validSamples.get(i); - if (i == 0) { - this.inputVector = vectorClient.compute(sample); - } else { - float[] newSampleVector = vectorClient.compute(sample); - this.inputVector = vectorClient.weightedAverage(this.inputVector, newSampleVector); - } - } - } - - private void addFailedCount() { - this.failedCount = Math.min(this.failedCount + 1, 3); - } - - private void adjustThreshold() { - double newThreshold = this.threshold + 0.03; - this.threshold = Math.min(newThreshold, 0.95); - } - - /** - * 针对未命中但评估通过的已存在缓存做出调整: - *
    - *
  1. - * 若已生效,但此时未匹配到则说明阈值或者向量{@link ActionCacheData#getInputVector()}存在问题,调低阈值,同时带权移动平均 - *
  2. - *
  3. - * 若未生效,则只增加计数并带权移动平均 - *
  4. - *
- * - * @param input 本次输入内容 - * @param inputVector 本次输入内容对应的语义向量 - * @param tendencyVector 本次倾向对应的语义向量 - * @param vectorClient 向量客户端 - */ - public synchronized void updateAfterNotMatchPassed(String input, float[] inputVector, float[] tendencyVector, VectorClient vectorClient) { - if (this.activated) { - reduceThreshold(); - this.inputVector = vectorClient.weightedAverage(inputVector, this.inputVector); - } else { - addValidSample(input); - this.tendencyVector = vectorClient.weightedAverage(tendencyVector, this.tendencyVector); - addInputMatchCount(); - } - } - - private void reduceThreshold() { - double newThreshold = this.threshold - 0.02; - this.threshold = Math.max(newThreshold, 0.75); - } - - private void addInputMatchCount() { - this.inputMatchCount += 1; - if (inputMatchCount >= 6) { - this.activated = true; - } - } - - public enum Type { - PRIMARY, REBUILD_V1, REBUILD_V2, REBUILD_V3 - } -} diff --git a/Partner-Core/src/main/java/work/slhaf/partner/module/action/planner/ActionPlanner.java b/Partner-Core/src/main/java/work/slhaf/partner/module/action/planner/ActionPlanner.java index 080f5fb6..0e2aa40e 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/module/action/planner/ActionPlanner.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/module/action/planner/ActionPlanner.java @@ -8,12 +8,9 @@ import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapabili import work.slhaf.partner.api.agent.factory.component.abstracts.AbstractAgentModule; import work.slhaf.partner.api.agent.factory.component.annotation.Init; import work.slhaf.partner.api.agent.factory.component.annotation.InjectModule; -import work.slhaf.partner.common.vector.VectorClient; import work.slhaf.partner.core.action.ActionCapability; import work.slhaf.partner.core.action.ActionCore; import work.slhaf.partner.core.action.entity.*; -import work.slhaf.partner.core.action.entity.cache.CacheAdjustData; -import work.slhaf.partner.core.action.entity.cache.CacheAdjustMetaData; import work.slhaf.partner.core.cognition.BlockContent; import work.slhaf.partner.core.cognition.CognitionCapability; import work.slhaf.partner.core.cognition.CommunicationBlockContent; @@ -135,33 +132,11 @@ public class ActionPlanner extends AbstractAgentModule.Running evaluatorResults = actionEvaluator.execute(evaluatorInput); // 并发操作均为访问 handleEvaluatorResults(evaluatorResults, source, input); - updateTendencyCache(evaluatorResults, input, extractorResult); cognitionCapability.contextWorkspace().expire(TENDENCIES_EVALUATING_BLOCK_NAME, getModuleName()); }); } - private void updateTendencyCache(List evaluatorResults, String input, ExtractorResult extractorResult) { - if (!VectorClient.status) { - return; - } - executor.execute(() -> { - CacheAdjustData data = new CacheAdjustData(); - List list = new ArrayList<>(); - List hitTendencies = extractorResult.getTendencies(); - for (EvaluatorResult result : evaluatorResults) { - CacheAdjustMetaData metaData = new CacheAdjustMetaData(); - metaData.setTendency(result.getTendency()); - metaData.setPassed(result.isOk()); - metaData.setHit(hitTendencies.contains(result.getTendency())); - list.add(metaData); - } - data.setMetaDataList(list); - data.setInput(input); - actionCapability.updateTendencyCache(data); - }); - } - private void handleEvaluatorResults(List evaluatorResults, String source, String input) { List passedActions = new ArrayList<>(); int approvedExecutableCount = 0; diff --git a/Partner-Core/src/main/java/work/slhaf/partner/module/action/planner/extractor/ActionExtractor.java b/Partner-Core/src/main/java/work/slhaf/partner/module/action/planner/extractor/ActionExtractor.java index 2294b0f0..d1b83f1a 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/module/action/planner/extractor/ActionExtractor.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/module/action/planner/extractor/ActionExtractor.java @@ -5,7 +5,6 @@ import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapabili import work.slhaf.partner.api.agent.factory.component.abstracts.AbstractAgentModule; import work.slhaf.partner.api.agent.model.ActivateModel; import work.slhaf.partner.api.agent.model.pojo.Message; -import work.slhaf.partner.core.action.ActionCapability; import work.slhaf.partner.core.cognition.CognitionCapability; import work.slhaf.partner.core.cognition.ContextBlock; import work.slhaf.partner.module.action.planner.extractor.entity.ExtractorResult; @@ -13,25 +12,18 @@ import work.slhaf.partner.module.action.planner.extractor.entity.ExtractorResult import java.util.List; public class ActionExtractor extends AbstractAgentModule.Sub implements ActivateModel { - @InjectCapability - private ActionCapability actionCapability; + @InjectCapability private CognitionCapability cognitionCapability; @Override public ExtractorResult execute(String input) { - List tendencyCache = actionCapability.selectTendencyCache(input); - if (tendencyCache != null && !tendencyCache.isEmpty()) { - ExtractorResult result = new ExtractorResult(); - result.setTendencies(tendencyCache); - return result; - } for (int i = 0; i < 3; i++) { try { List messages = List.of( cognitionCapability.contextWorkspace().resolve(List.of( - ContextBlock.VisibleDomain.ACTION, - ContextBlock.VisibleDomain.COGNITION + ContextBlock.VisibleDomain.COGNITION, + ContextBlock.VisibleDomain.ACTION )).encodeToMessage(), new Message(Message.Character.USER, input) );