# **IIT Manager Agent V2.7:基于“双层文本记忆”的极简架构** **版本:** V2.7 (Clawbot Memory Edition) **日期:** 2026-02-05 **核心变更:** 废弃复杂的 pgvector 语义检索,采用 Clawbot 式的“流水账 \+ 沉淀物”双层文本记忆。 **优势:** 记忆可读、可改、透明、零黑盒。 ## **1\. 记忆架构重构 (Memory Refactoring)** 我们将记忆分为两层,完全模拟人类大脑运作,且摒弃不可解释的向量数据。 graph TD subgraph "层级 1: 流水账 (Daily Stream)" Log\[Conversation History\] Note\[Raw Actions\] desc1\[特点: Append-Only, 巨量, 易遗忘\] end subgraph "层级 2: 沉淀物 (The Sediment)" ProjectMem\[项目级 MEMORY.md\] PatientMem\[患者级 MEMORY.md\] UserMem\[用户级 MEMORY.md\] desc2\[特点: 精炼, 结构化, 人类可编辑\] end Log \--\>|每晚 Cron 归纳 (Gardening)| ProjectMem Admin\[管理员/医生\] \--\>|手动修正/编辑| ProjectMem ProjectMem \--\>|注入 System Prompt| LLM ## **2\. 数据库设计变更 (Schema Changes)** ### **2.1 新增 iit\_memory\_files 表** 我们不用磁盘文件,用数据库表来模拟文件,方便 Web 端管理。 model IitMemoryFile { id String @id @default(uuid()) projectId String targetType String // PROJECT | PATIENT | USER targetId String // 对应的 ID (如 projectId, recordId, userId) // 核心:这就是那个 MEMORY.md 的内容 content String @db.Text lastUpdatedBy String // 'system\_daily\_job' 或 'user\_001' updatedAt DateTime @updatedAt @@unique(\[projectId, targetType, targetId\]) @@map("iit\_memory\_files") @@schema("iit\_schema") } ### **2.2 废弃计划** * **废弃**:iit\_conversation\_history 中的 embedding 字段。 * **废弃**:Phase 5 中的向量检索服务。 ## **3\. 核心服务实现:MemoryService (V2.7)** ### **3.1 读取记忆 (Read)** 在 ChatService 启动对话前,简单的把文本读出来拼接到 Prompt 里。 // backend/src/modules/iit-manager/services/MemoryService.ts export class MemoryService { async getContext(projectId: string, userId: string, recordId?: string) { // 1\. 获取项目级记忆 (规则、偏好) const projectMem \= await this.loadMemory('PROJECT', projectId); // 2\. 获取用户级记忆 (习惯) const userMem \= await this.loadMemory('USER', userId); // 3\. (可选) 获取患者级记忆 const patientMem \= recordId ? await this.loadMemory('PATIENT', recordId) : ''; return \` \=== 长期记忆 (Long-Term Memory) \=== \[项目背景\]: ${projectMem} \[用户偏好\]: ${userMem} \[患者备注\]: ${patientMem} \================================ \`; } private async loadMemory(type: string, id: string) { const mem \= await prisma.iitMemoryFile.findUnique({ where: { projectId\_targetType\_targetId: { ... } } }); return mem?.content || ''; } } ### **3.2 记忆维护 (Gardening \- The Clawbot Way)** 这是最精彩的部分。我们不实时更新长期记忆(太乱),而是每天晚上让 AI 当“园丁”,修剪记忆。 **任务:Daily Memory Consolidation** * **触发**:每天凌晨 2 点。 * **输入**:当天的对话流水 (iit\_conversation\_history) \+ 旧的 MEMORY.md。 * **Prompt**:"这是今天的对话流水。请提取其中新的重要事实(如用户偏好、新的关键决策、患者的新状态),合并到旧的记忆文件中。保持 Markdown 格式。如果没有新信息,保持不变。" * **输出**:新的 Markdown 文本,覆盖数据库。 // SchedulerService.ts async runDailyMemoryConsolidation() { const logs \= await this.getDailyLogs(); const oldMem \= await this.memoryService.loadMemory('PROJECT', projectId); const newMem \= await this.llm.chat(\[ { role: 'system', content: '你是记忆整理员...' }, { role: 'user', content: \`旧记忆:\\n${oldMem}\\n\\n今日流水:\\n${logs}\` } \]); await this.memoryService.saveMemory('PROJECT', projectId, newMem); } ## **4\. 调整后的开发计划 (Phase 5 重构)** 我们将原计划 Week 5 的“向量检索”替换为“文本记忆系统”。 ### **Week 5:Clawbot 式记忆系统** | 时间 | 任务 | 说明 | | :---- | :---- | :---- | | **Day 24** | **记忆表结构与 CRUD** | 创建 iit\_memory\_files 表,实现读写 API。 | | **Day 25** | **记忆注入 Prompt** | 修改 ChatService,在 System Prompt 头部注入 Markdown 内容。 | | **Day 26** | **记忆整理 Worker** | 实现“每日记忆整理”的 Cron Job (pg-boss)。 | | **Day 27** | **记忆编辑 UI** | 在 Admin 后台增加一个简单的文本框,允许人工修改 MEMORY.md。 | ## **5\. 为什么这比向量库好?** 1. **完全透明 (White Box)**: * 向量库出了问题(比如 AI 突然变傻),你只能重新 Embed,甚至不知道哪条数据坏了。 * 文本记忆出了问题,你打开 Admin 界面,看到一行:“用户不喜欢红烧肉”,你把它删了,问题立刻解决。**这对医疗系统排查问题是无价的。** 2. **Token 可控**: * 向量库如果不加限制,可能召回 5000 字的无关内容。 * 文本记忆由“每日整理”压缩过,通常只有几百字的核心干货,Token 消耗极低。 3. **技术栈简化**: * 不需要 pgvector 插件(虽然你们装了,但不用也没关系)。 * 不需要 Embedding 模型调用。 * 纯字符串处理,Node.js 最擅长。 ## **6\. 结论** 这个建议**极具战略价值**。它把一个“高科技难题”(如何做语义检索)变成了一个“管理学问题”(如何整理笔记)。 **执行建议:** 全盘接受这个建议。在 V2.6 架构中,**移除 Embedding 层,替换为 Memory File 层。** 这会让你们的系统在面对 PI 的刁钻问题时,显得更有“记性”,同时让你们的运维工作变得无比轻松。