# **IIT Manager Agent V2.8:记忆检索与路由逻辑详解** **核心机制:** 意图驱动的按需检索 (Intent-Driven Retrieval) **目的:** 既保证 AI 懂当下(Hot),又保证 AI 懂历史(History),同时节省 Token。 ## **1\. 记忆存储全景图 (Storage Map)** 在 V2.8 中,我们有三个核心存储位置,各司其职: | 记忆类型 | 存储表 | 字段 | 内容特征 | 更新频率 | | :---- | :---- | :---- | :---- | :---- | | **1\. 流水账 (Raw Stream)** | iit\_conversation\_history | content (JSON) | 未经加工的原始对话。 | **实时** (每秒) | | **2\. 热记忆 (Hot Context)** | iit\_project\_memory | config (Markdown) | 用户偏好、当前状态、系统禁令。 | **每日** (AI 提炼) | | **3\. 历史书 (Weekly Reports)** | iit\_weekly\_reports | summary (Text) | 高度浓缩的周报、关键决策、踩坑记录。 | **每周** (AI 归档) | ## **2\. 调取顺序与逻辑 (Retrieval Logic)** 当 PI 发问时,系统并不是一股脑把所有记忆都塞进去,而是分三步走: ### **第一步:无条件注入 (Always On)** **无论 PI 问什么,必须先注入“热记忆”。** * **来源**:iit\_project\_memory * **内容**:用户偏好(如“PI 喜欢简报”)、当前项目状态。 * **理由**:这是 Agent 的“人设”和“底线”,一刻也不能忘。 ### **第二步:意图识别 (Intent Detection)** 系统分析 PI 的问题,判断他想问“现在”还是“过去”。 * **情况 A:问现在/执行任务** (如 "查下 P001", "生成本周周报") * **动作**:**不调取** 历史书。 * **理由**:解决当下问题不需要翻阅 3 年前的老黄历,避免干扰 AI。 * **Context** \= Hot Memory \+ Current Task Data * **情况 B:问历史/趋势/回顾** (如 "回顾下去年的入组情况", "我们为什么暂停了筛选?") * **动作**:**全量调取** 历史书 (iit\_weekly\_reports)。 * **理由**:需要上帝视角。 * **Context** \= Hot Memory \+ All Weekly Reports ### **第三步:上下文组装 (Prompt Assembly)** 最终发给 LLM 的 Prompt 是这样组装的: \[System Prompt\] 你是一个临床研究助手... \[Hot Memory\] (来自 iit\_project\_memory) \- 用户偏好: 简洁、数据驱动 \- 当前状态: 入组阶段 \[History Context\] (仅在情况 B 下注入) Week 1: 启动项目... Week 2: 发现 P001 不良事件... ... Week 50: 决定放宽标准... \[User Question\] 我们之前为什么暂停筛选? ## **3\. 实战场景演示 (Scenario Walkthrough)** ### **场景 1:PI 问 "P001 入组了吗?"** 1. **加载 Hot Memory**:获取偏好(简洁回复)。 2. **意图识别**:QUERY\_DATA (查数据)。 3. **决策**:**不需要** 查历史书。 4. **行动**:调用 read\_clinical\_data 工具去 REDCap 查实时数据。 5. **回答**:"已入组,时间是 2026-02-05。" ### **场景 2:PI 问 "最近入组太慢了,我们之前有没有讨论过怎么解决?"** 1. **加载 Hot Memory**:获取偏好。 2. **意图识别**:QUERY\_HISTORY (查历史决策)。 3. **决策**:**需要** 查历史书。 4. **行动**: * 从 iit\_weekly\_reports 拉取过去 20 周的 summary。 * 拼接成 3000 字的文本。 * 喂给 LLM。 5. **LLM 思考**:阅读周报,发现 Week 12 记录了“增加受试者交通补贴”的决策,Week 15 记录了“在门诊增派 CRC”的决策。 6. **回答**:"我们曾在第 12 周尝试增加补贴,第 15 周增派了 CRC,当时效果有短暂提升..." ### **场景 3:PI 问 "我上次跟你说的那个只要看结果的规矩,你记得吗?"** 1. **加载 Hot Memory**:获取偏好。 2. **AI 自检**:在 Hot Memory 里看到了 \- \[PI\]: 只要看结果 这条记录。 3. **回答**:"记得的,教授。您要求汇报时只列数据结论,不要冗长的过程描述。我会严格遵守。" * *注意:这个问题不需要查周报,也不需要查流水账,直接看 Hot Memory 就行。* ## **4\. 总结:给开发者的伪代码** // ChatService.ts async handleMessage(userId, message) { // 1\. 总是加载热记忆 (Hot) const hotMem \= await prisma.iitProjectMemory.findUnique(...); // 2\. 意图识别 const intent \= await this.intentService.detect(message); let historyContext \= ""; // 3\. 按需加载历史书 (History) if (intent.type \=== 'QUERY\_HISTORY' || intent.type \=== 'ANALYZE\_TREND') { const reports \= await prisma.iitWeeklyReport.findMany({ orderBy: { weekNumber: 'asc' } }); historyContext \= reports.map(r \=\> \`\[W${r.weekNumber}\]: ${r.summary}\`).join('\\n'); } // 4\. 组装最终 Prompt const finalPrompt \= \` ${hotMem.content} ${historyContext} User: ${message} \`; // 5\. 调用 LLM return await this.llm.chat(finalPrompt); } **记住这个口诀:** **“偏好时刻带,历史按需查,流水账只用来生成周报。”** ## **5\. 复杂度控制与防失控指南 (Safety Guardrails)** 为了防止系统变得“复杂不可控”,请严格遵守以下开发军规: ### **5.1 容量限制 (The Cap)** * **Hot Memory**: 限制在 **2000 Tokens** 以内。如果超标,触发 MemoryPruningJob (记忆修剪任务),让 AI 自动总结或通知管理员手动删除。 * **History Book**: 每次加载不超过 **50 周** 的周报。如果项目运行了 10 年,只加载最近 1 年的周报,或者先让 AI 生成“年度总结”。 ### **5.2 隔离原则 (Isolation)** * **任务隔离**:执行 QC\_TASK (质控) 时,**严禁**加载 History Context。质控必须基于当下的事实,不能受历史干扰。 * **数据隔离**:LLM 永远没有权限直接读取 iit\_conversation\_history 表。这条物理隔绝保证了 Agent 永远不会被海量噪音淹没。 ### **5.3 人工介入 (The Kill Switch)** * **可读可改**:后台必须提供 Hot Memory 的编辑器。如果 Agent 记住了错误的规则(例如“不需要查年龄”),医生可以直接进去删掉那一行 Markdown。**这是系统失控时的“急停按钮”。**