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>
210 lines
8.4 KiB
Markdown
210 lines
8.4 KiB
Markdown
# **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
|
||
);
|
||
}
|
||
|
||
**效果:** 你只需要在后台配一个 JSON,Agent 就会每天早上 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。 |