Commit Graph

5 Commits

Author SHA1 Message Date
MIST
dcc8c9aed3
修复同一 Agent 多并发会话记忆混乱问题 (#458)
### 问题现象
同一 agent 开多个并发会话时(如 A1=查南京天气、A2=查北京天气),A2 在多轮 ReAct 执行中会"突然去查南京天气",表现为 A1 会话的上下文泄漏到 A2 会话。

### 根因4:Agent 实例共享 + state 覆盖(确认,仅状态显示问题)
确认点:
- AgentService.java:83-90 agentInstances 按 (agentId, modelKey) 缓存,不含 conversationId
- AgentService.java:598-624 getOrBuildAgentForConversation 只按 (agentId, provider, model) 解析,不按 conversationId
- AgentService.java:530-545 withLifecycleFlux 无锁 ,A/B/C 完全并发
影响: A 完成设 IDLE → B 仍在运行但显示 IDLE → 状态显示错乱。 不会直接导致记忆串台 ,但对用户可见。

## 二、根因与症状匹配度总结
根因 匹配度 触发条件 串台通道 1. SessionSearchTool ★★★★★ LLM 多轮遇到困难时主动调用 session_search 返回并发兄弟会话消息 2. 审批重放无过滤 ★★★☆☆ Plan-Execute + 审批 + 并发 awaiting_approval 误取兄弟会话计划 3. 结构化记忆共享 ★★★☆☆ A 会话 LLM 主动 remember_structured 写入 prefetch 注入到 B 会话 4. Agent 实例共享 ★★☆☆☆ 任意并发 state 显示错乱(非记忆串台)

用户描述的"B突然去查南京天气"最可能是根因1 ——因为 system prompt 明确引导 LLM 在遇到困难时用 session_search 回忆历史,而 SQL 会返回并发兄弟会话的"南京天气"内容。

## 三、修复方案(按优先级排序)
### 方案1:修复 SessionSearchTool(最优先,直接命中症状)
改动点 A — SessionSearchTool 增加 ToolContext 参数,强制读取真实 conversationId:

SessionSearchTool.java:37-44

改动点 B — SessionSearchService 增加运行状态过滤,排除并发兄弟会话:

SessionSearchService.java:60-73 SQL 增加:

或更保守:只返回 status = 'completed' 的会话,排除 running / awaiting_approval 的并发会话。

风险评估: 改动 SQL 查询条件,不影响写入逻辑。 completed 会话才是真正的"历史对话", running 会话是"正在进行"不应被搜索。功能上合理。

### 方案2:修复审批重放跨会话取计划(确凿 bug,必须修)
改动点 A — PlanningService.findAwaitingApprovalContext 增加 conversationId 参数:

PlanningService.java:228-232

改动点 B — 调用方传入 conversationId:

StateGraphPlanExecuteAgent.java:100

风险评估: 需确认 PlanEntity 有 conversationId 字段(从之前排查看应存在)。改动最小,仅加查询过滤,不影响其他逻辑。

### 方案3:结构化记忆引入会话级隔离(改动较大,需评估)
问题: 当前 ownerKey = user:<requesterId> ,3 会话共享。如果改为 conversation:<conversationId> ,会破坏"用户长期记忆跨会话共享"的设计意图(用户画像、偏好等应跨会话)。

建议方案: 不改 ownerKey 机制,而是在 StructuredMemoryTool.remember_structured 的 system prompt 说明中 明确限制 只记住"长期有效的事实",临时任务结果(如天气查询)不应写入。或在 type 枚举中新增 transient 类型,该类型按 conversationId 隔离,会话结束自动清除。

风险评估: 改动较大,涉及记忆分层设计。建议作为中长期优化,本次先修方案1和2。

### 方案4:Agent 实例 state 按 conversationId 隔离(可选)
改动点: BaseAgent.java:33 AtomicReference<AgentState> state 改为 Map<String, AtomicReference<AgentState>> (按 conversationId)。

风险评估: 影响所有 getState() / setState() 调用点,改动面广。且这只是状态显示问题,不影响记忆串台。建议暂不修,或在前端按 conversationId 单独查询状态。

--------------------------------------------
本次完成bug1、2修复;3、4未动
2026-06-30 09:23:26 +08:00
matevip
eca4229751 feat(plans): per-step agent delegation + fix kanban pending column (issue #385) 2026-06-21 21:20:58 +08:00
matevip
c656aff349 feat(plans): Kanban boards in the Agents workspace
Live lifecycle board (grid<->board toggle) plus an assignee-swimlane plan
board that groups follow-up re-runs of one goal into a single xN card.
Custom right-side detail/goal panels with markdown output. Fixes plans
being persisted under the per-run trace id so the board actually populates.

Closes #385
2026-06-20 17:52:29 +08:00
matevip
762218cd32 refactor(db): drop @TableLogic on all entities, purge soft-deleted rows 2026-04-18 23:31:48 +08:00
matevip
579d60125b Initial commit: MateClaw — Java + Vue 3 AI Assistant System
Full-stack AI assistant built on Spring AI Alibaba.
Features: ReAct Agent, Plan-and-Execute, MCP Protocol, Multi-Model, Multi-Channel.

Apache-2.0 License
2026-04-04 19:03:49 +08:00