docs(iit): Add IIT Manager Agent V2.9 development plan with multi-agent architecture

Features:
- Add V2.9 enhancements: Cron Skill, User Profiling, Feedback Loop, Multi-Intent Handling
- Create modular development plan documents (database, engines, services, memory, tasks)
- Add V2.5/V2.6/V2.8/V2.9 design documents for architecture evolution
- Add system design white papers and implementation guides

Architecture:
- Dual-Brain Architecture (SOP + ReAct engines)
- Three-layer memory system (Flow Log, Hot Memory, History Book)
- ProfilerService for personalized responses
- SchedulerService with Cron Skill support

Also includes:
- Frontend nginx config updates
- Backend test scripts for WeChat signature
- Database backup files

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-02-05 22:33:26 +08:00
parent 4b9b90ffb8
commit 0c590854b5
27 changed files with 7279 additions and 7 deletions

View File

@@ -0,0 +1,210 @@
# **IIT Manager Agent V2.9 补充设计:主动性与用户画像增强**
**目标:** 响应智能化评估中的 P0 需求,补齐“主动服务”和“个性化”短板,并增强复杂任务处理能力。
**原则:** 坚持 **Postgres-Only**,复用现有的 **Skill (JSON)****ToolsService**
## **1\. 主动提醒机制设计 (The Proactive Engine)**
我们不需要写死一堆 cron 脚本,而是将“主动提醒”抽象为一种特殊的 **Skill**
### **1.1 架构复用逻辑**
* **触发源**pg-boss 的定时任务 (Scheduler)。
* **规则载体**iit\_skills 表(新增 trigger\_type: 'cron')。
* **执行者**QcEngineService (复用现有的逻辑)。
### **1.2 数据库 Schema 扩展**
在 iit\_skills 表中增加调度字段:
model IitSkill {
// ... 原有字段
triggerType String @default("webhook") // 'webhook' | 'cron' | 'event'
cronSchedule String? // 例如: "0 9 \* \* \*" (每天9点)
// 核心配置 (JSON)
config Json
}
### **1.3 Skill 配置示例:访视提醒**
这是一个“每天早上9点检查即将到期访视”的技能配置。
{
"name": "即将到期访视提醒",
"description": "扫描未来3天内需要访视的患者",
// 核心:复用 Engine A 的逻辑来筛选数据
"hard\_rules": \[
// 这里我们稍微扩展一下 hard\_rules 的能力,支持 SQL-like 的筛选
// 或者直接调用工具获取列表
\],
// 核心:复用 Engine B (LLM) 来生成人性化通知
"soft\_instructions": \[
{
"instruction": "请调用 \`get\_upcoming\_visits(days=3)\` 工具。如果有数据,请根据【用户偏好】生成一条提醒消息。如果没有数据,什么都不做。",
"tools": \["get\_upcoming\_visits", "send\_wechat\_msg"\]
}
\]
}
### **1.4 代码实现 (SchedulerService.ts)**
// SchedulerService.ts
async initCronJobs() {
// 1\. 从数据库加载所有 triggerType \= 'cron' 的 Skill
const cronSkills \= await prisma.iitSkill.findMany({
where: { triggerType: 'cron', isActive: true }
});
for (const skill of cronSkills) {
// 2\. 注册到 pg-boss
await this.boss.schedule(
\`run-skill-${skill.id}\`,
skill.cronSchedule,
{ skillId: skill.id }
);
}
}
// Worker 处理逻辑
async handleCronSkill(job) {
const { skillId } \= job.data;
const skill \= await prisma.iitSkill.findUnique({ where: { id: skillId } });
// 3\. 复用现有的引擎!
// 就像处理 Webhook 一样处理 Cron架构极其统一
await this.qcEngine.runSoftAgent(
skill.config.soft\_instructions\[0\].instruction,
{ source: 'cron\_job' } // Context
);
}
**效果:** 你只需要在后台配一个 JSONAgent 就会每天早上 9 点醒来查数据然后发微信“张医生P005 明天该来复查了。”
## **2\. 用户画像增强 (User Profiling)**
我们已经在 V2.8 中设计了 iit\_project\_memory (Hot Memory),现在只需要把“画像”结构化。
### **2.1 存储设计**
在 iit\_user\_preferences 表中,我们将 preferences 字段细分为两类:
1. **显性偏好 (Explicit)**:用户明确说的(“我要简报”)。
2. **隐性画像 (Implicit)**:系统分析出来的(“他是 PI关注宏观数据”
// preferences 字段内容示例
{
"communication\_style": "concise", // 简练 | 详尽
"role\_tag": "PI", // PI | CRC | CRA
"focus\_areas": \["AE", "Enrollment"\], // 关注点
"notification\_time": "08:30", // 接收时间
"feedback\_history": { // 简单的反馈记录
"thumbs\_up": 12,
"thumbs\_down": 1
}
}
### **2.2 自动画像更新 (The Profiler)**
我们在 ChatService 结束一次对话后,异步触发一个微型任务:**“画像侧写”**。
// ProfilerService.ts
async updateProfile(userId: string, lastConversation: any\[\]) {
const currentProfile \= await this.getProfile(userId);
// 让 LLM 当心理分析师
const prompt \= \`
基于刚刚的对话,更新用户画像。
对话:${JSON.stringify(lastConversation)}
旧画像:${JSON.stringify(currentProfile)}
提取规则:
1\. 如果用户抱怨"太长了",将 style 设为 concise。
2\. 如果用户问了"安全性",将 AE 加入 focus\_areas。
返回新的 JSON。
\`;
const newProfile \= await this.llm.chat(prompt);
await this.saveProfile(userId, newProfile);
}
## **3\. 反馈循环 (Feedback Loop \- Lite)**
不要做复杂的强化学习RLHF只做简单的\*\*“点赞/点踩”\*\*。
### **3.1 交互设计**
在 Agent 回复的每条消息下面(如果是小程序/网页),加两个小按钮:👍 / 👎。
### **3.2 逻辑闭环**
1. **用户点踩 (👎)**
2. **前端**:弹窗询问“哪里不好?”(选项:太啰嗦、不准确、没听懂)。
3. **后端**
* 将这条 Negative Feedback 写入 iit\_conversation\_history。
* **关键动作**:触发一次 Hot Memory 更新。
* **Prompt**"用户对刚才的回答点了踩,原因是'太啰嗦'。请在 Hot Memory 中记下一条禁令:\[针对该用户,严禁输出超过 100 字的废话\]。"
**结果**Agent 下次遇到这个用户,真的会改。这就是最真实的“智能感”。
## **4\. 多意图与任务规划增强 (Multi-Intent Handling)**
针对“先做 A再做 B”的复杂指令“查一下 P001 的状态,然后通知张医生”),我们不需要引入重型 Planner而是通过 **ReAct \+ Prompt Engineering** 实现。
### **4.1 核心策略ReAct 自然涌现**
**结论**ReAct 引擎本身就是一个轻量级 Planner。
不需要额外的 Planner 模块,只需要在 **System Prompt** 中显式教导 Agent 如何拆解任务。
### **4.2 Prompt 增强设计**
在 backend/src/modules/iit-manager/engines/ReActEngine.ts 的系统提示词中加入以下**思维链Chain of Thought指令**
const REACT\_SYSTEM\_PROMPT \= \`
你是一个临床研究助手。你可以使用工具来回答问题。
核心原则:
1\. \*\*任务拆解\*\*:如果用户请求包含多个步骤(例如"先...再...""查完...发给..."),请务必分步执行。
\- 不要试图在一个步骤里做完所有事。
\- 比如:先调用查询工具,获得结果后,再调用发送工具。
2\. \*\*依赖管理\*\*:如果步骤 B 依赖步骤 A 的结果,必须先执行 A观察 A 的结果,再执行 B。
3\. \*\*完成检查\*\*:在输出 Final Answer 之前,检查是否完成了用户的所有指令。
思考格式示例:
Thought: 用户想查 P001 并通知张医生。我有两个任务。首先,我需要查 P001 的状态。
Action: 调用 read\_clinical\_data(id='P001')...
Observation: {"status": "Enrolled"}
Thought: 我已经查到了状态。现在我需要执行第二个任务:发消息给张医生。
Action: 调用 send\_wechat\_msg(to='Dr. Zhang', content='P001 status is Enrolled')...
...
\`;
### **4.3 为什么不用 Planner**
对于 2 人团队,显式 Planner先生成计划列表再循环执行过于沉重且难以维护状态。ReAct 的 **“边走边想”** 模式完全能够覆盖 90% 的“线性多步任务”。
## **5\. 总结与建议**
| 需求 | 解决方案 | 复杂度 | 推荐实施阶段 |
| :---- | :---- | :---- | :---- |
| **主动提醒** | **Cron Skill** (复用 pg-boss \+ QC Engine) | 低 | **Phase 4** (与周报一起做) |
| **用户画像** | **Profiler Job** (对话后异步分析) | 中 | **Phase 5** (智能化增强) |
| **反馈循环** | **点赞按钮 \+ 记忆写入** | 低 | **Phase 5** |
| **多意图处理** | **ReAct Prompt 优化** (无需新模块) | 极低 | **Phase 5** (开发 ReActEngine 时同步完成) |
### **对你的建议**
1. **全盘接受 P0 建议**:主动提醒和用户画像是成本低、收益大的功能。
2. **技术上保持克制**
* 别写专门的 Alert Engine用 Cron Skill 复用现有的引擎。
* 别搞复杂的推荐算法,用 JSON 存画像就够了。
* 别搞复杂的 Planner**Prompt** 教会 ReAct 拆解任务就够了。
这样,你的 V2.6+ 架构就真正补齐了“右脑”的情商短板,变成了一个 **“有记忆、会主动、懂人情、能办事”** 的完整 Agent。