Commit 40805d5a authored by alex yao's avatar alex yao

fix【记忆变量】: 修复修改【记忆变量】结构时,导致对话【记忆变量】缓存全量刷新 --bug==1009425

parent c577eac5
...@@ -10,6 +10,7 @@ import cn.com.poc.agent_application.query.DialogsIdsQueryByAgentIdQueryItem; ...@@ -10,6 +10,7 @@ import cn.com.poc.agent_application.query.DialogsIdsQueryByAgentIdQueryItem;
import cn.com.poc.agent_application.service.*; import cn.com.poc.agent_application.service.*;
import cn.com.poc.agent_application.utils.AgentApplicationTools; import cn.com.poc.agent_application.utils.AgentApplicationTools;
import cn.com.poc.common.constant.CommonConstant; import cn.com.poc.common.constant.CommonConstant;
import cn.com.poc.common.utils.Assert;
import cn.com.poc.common.utils.BlContext; import cn.com.poc.common.utils.BlContext;
import cn.com.poc.common.utils.JsonUtils; import cn.com.poc.common.utils.JsonUtils;
import cn.com.poc.knowledge.entity.BizKnowledgeDocumentEntity; import cn.com.poc.knowledge.entity.BizKnowledgeDocumentEntity;
...@@ -96,22 +97,9 @@ public class AgentApplicationInfoServiceImpl implements AgentApplicationInfoServ ...@@ -96,22 +97,9 @@ public class AgentApplicationInfoServiceImpl implements AgentApplicationInfoServ
@Override @Override
public BizAgentApplicationInfoEntity saveOrUpdate(BizAgentApplicationInfoEntity entity) throws Exception { public BizAgentApplicationInfoEntity saveOrUpdate(BizAgentApplicationInfoEntity entity) throws Exception {
// 如果存在agentId,则判断变量结构是否有变化,如果有变化,则删除redis中的数据 // 如果存在agentId,则判断变量结构是否有变化,如果有变化,则删除redis中的数据
boolean needClean = false;
if (StringUtils.isNotBlank(entity.getAgentId())) { if (StringUtils.isNotBlank(entity.getAgentId())) {
BizAgentApplicationInfoEntity infoEntity = bizAgentApplicationInfoService.getByAgentId(entity.getAgentId()); BizAgentApplicationInfoEntity infoEntity = bizAgentApplicationInfoService.getByAgentId(entity.getAgentId());
if (CollectionUtils.isEmpty(entity.getVariableStructure()) || CollectionUtils.isEmpty(infoEntity.getVariableStructure())) { updateStructVariable(entity.getAgentId(), infoEntity.getVariableStructure(), entity.getVariableStructure());
needClean = true;
} else if (infoEntity.getVariableStructure().size() != entity.getVariableStructure().size()) {
needClean = true;
} else {
String sourceVariable = JsonUtils.serialize(infoEntity.getVariableStructure());
String targetVariable = JsonUtils.serialize(entity.getVariableStructure());
needClean = !StringUtils.equals(sourceVariable, targetVariable);
}
}
if (needClean) {
MemoryVariableWriter.clean(entity.getAgentId() + ":" + entity.getAgentId());
} }
// 保存或更新 // 保存或更新
return StringUtils.isEmpty(entity.getAgentId()) ? return StringUtils.isEmpty(entity.getAgentId()) ?
...@@ -146,7 +134,7 @@ public class AgentApplicationInfoServiceImpl implements AgentApplicationInfoServ ...@@ -146,7 +134,7 @@ public class AgentApplicationInfoServiceImpl implements AgentApplicationInfoServ
if (CollectionUtils.isNotEmpty(items)) { if (CollectionUtils.isNotEmpty(items)) {
logger.info("variables structure cache remove,items:{}", items); logger.info("variables structure cache remove,items:{}", items);
for (DialogsIdsQueryByAgentIdQueryItem item : items) { for (DialogsIdsQueryByAgentIdQueryItem item : items) {
MemoryVariableWriter.clearByPre(AgentApplicationTools.identifier(item.getDialogsId(), bizAgentApplicationInfoEntity.getAgentId())); MemoryVariableWriter.cleanByPre(AgentApplicationTools.identifier(item.getDialogsId(), bizAgentApplicationInfoEntity.getAgentId()));
} }
} }
...@@ -796,4 +784,92 @@ public class AgentApplicationInfoServiceImpl implements AgentApplicationInfoServ ...@@ -796,4 +784,92 @@ public class AgentApplicationInfoServiceImpl implements AgentApplicationInfoServ
} }
/**
* 更新【记忆变量】结构
*
* @param agentId 应用ID
* @param originals 原字段结构
* @param transformed 变换后的字段结构
* @author alex.yao
* @deprecated 更新规则:
* 1. 原字段已存在,并存在值则不更新,否则更新并赋予该字段新结构默认值
* 2. 原字段不存在,则新增并赋予新结构的默认值
* 3. 原字段存在,但新结构中不存在,则删除原字段
* 注意: 若transformed为空会清除所有字段,删除对话中所有【记忆变量】缓存
*/
private void updateStructVariable(String agentId, List<Variable> originals, List<Variable> transformed) {
Assert.notBlank(agentId);
String identifier = AgentApplicationTools.identifier(agentId, agentId);
if (CollectionUtils.isEmpty(transformed)) {
// 清除所有字段
MemoryVariableWriter.clean(identifier);
}
// 原【变量记忆】为空,则不需要处理
if (CollectionUtils.isEmpty(originals)) {
return;
}
Map<Object, Object> memoryVariable = MemoryVariableWriter.get(identifier);
if (MapUtils.isEmpty(memoryVariable)) {
return;
}
// 1. 获取需要删除的字段集合
// 2. 获取需要更新值的字段集合
Set<String> delKeys = new HashSet<>();
Set<String> updateKeys = new HashSet<>();
for (Variable variable : originals) {
String key = variable.getKey();
boolean needDel = transformed.stream().noneMatch(v -> v.getKey().equals(key));
if (needDel) {
delKeys.add(key);
}
boolean needUpdate = transformed.stream().anyMatch(v -> v.getKey().equals(key));
if (needUpdate) {
Optional<Variable> target = transformed.stream().filter(v -> v.getKey().equals(key)).findFirst();
if (StringUtils.isBlank(target.get().getVariableDefault())) {
continue;
}
Map<Object, Object> map = MemoryVariableWriter.get(identifier);
if (map == null) {
map = new HashMap<>();
}
Object value = map.get(key);
if (value == null || StringUtils.isBlank(value.toString())) {
updateKeys.add(key);
}
}
}
// 3. 获取需要新增的字段集合
Set<String> addKeys = new HashSet<>();
for (Variable variable : transformed) {
String key = variable.getKey();
boolean needAdd = originals.stream().noneMatch(v -> v.getKey().equals(key));
if (needAdd) {
addKeys.add(key);
}
}
// 删除
if (!delKeys.isEmpty()) {
MemoryVariableWriter.delItem(identifier, delKeys.toArray(new String[0]));
}
if (!addKeys.isEmpty()) {
Map<String, Object> map = new HashMap<>();
for (String key : addKeys) {
Variable variable = transformed.stream().filter(v -> v.getKey().equals(key)).findFirst().get();
map.put(variable.getKey(), variable.getVariableDefault());
}
MemoryVariableWriter.addItem(identifier, map);
}
if (!updateKeys.isEmpty()) {
Map<String, Object> map = new HashMap<>();
for (String key : updateKeys) {
Variable variable = transformed.stream().filter(v -> v.getKey().equals(key)).findFirst().get();
map.put(variable.getKey(), variable.getVariableDefault());
}
MemoryVariableWriter.addItem(identifier, map);
}
}
} }
...@@ -3,7 +3,10 @@ package cn.com.poc.thirdparty.resource.demand.ai.function.memory_variable_writer ...@@ -3,7 +3,10 @@ package cn.com.poc.thirdparty.resource.demand.ai.function.memory_variable_writer
import cn.com.poc.common.service.RedisService; import cn.com.poc.common.service.RedisService;
import cn.com.poc.common.utils.BlContext; import cn.com.poc.common.utils.BlContext;
import cn.com.poc.common.utils.SpringUtils; import cn.com.poc.common.utils.SpringUtils;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class MemoryVariableWriter { public class MemoryVariableWriter {
...@@ -24,9 +27,42 @@ public class MemoryVariableWriter { ...@@ -24,9 +27,42 @@ public class MemoryVariableWriter {
redisService.del(redisKey); redisService.del(redisKey);
} }
public static void clearByPre(String key) { public static void cleanByPre(String key) {
String redisKey = MemoryVariableWriterConstants.REDIS_PREFIX + key + ":"; String redisKey = MemoryVariableWriterConstants.REDIS_PREFIX + key + ":";
RedisService redisService = SpringUtils.getBean(RedisService.class); RedisService redisService = SpringUtils.getBean(RedisService.class);
redisService.delByPre(redisKey); redisService.delByPre(redisKey);
} }
public static void delItem(String identifier, String... items) {
String redisKey = MemoryVariableWriterConstants.REDIS_PREFIX + identifier + ":" + BlContext.getCurrentUserNotException().getUserId().toString();
RedisService redisService = SpringUtils.getBean(RedisService.class);
redisService.hdel(redisKey, items);
}
public static void addItem(String identifier, Map<String, Object> map) {
String redisKey = MemoryVariableWriterConstants.REDIS_PREFIX + identifier + ":" + BlContext.getCurrentUserNotException().getUserId().toString();
RedisService redisService = SpringUtils.getBean(RedisService.class);
// 创建 JSONObject 对象
Map<String, Object> result = new HashMap<>();
if (redisService.hasKey(redisKey)) {
Map<Object, Object> hmget = redisService.hmget(redisKey);
hmget.putAll(map);
for (Map.Entry<Object, Object> entry : hmget.entrySet()) {
if (entry.getKey() instanceof String) {
String tempKey = (String) entry.getKey();
result.put(tempKey, entry.getValue());
}
}
}
result.putAll(map);
// 30天有效期
long expireTime = 30 * 60 * 24L;
redisService.hmset(redisKey, result, expireTime);
}
private static void setMap(JSONObject jsonObject, Map<String, Object> result) {
String key = jsonObject.getStr("key");
String value = jsonObject.getStr("value");
result.put(key, value);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment