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>
8.4 KiB
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 字段细分为两类:
- 显性偏好 (Explicit):用户明确说的(“我要简报”)。
- 隐性画像 (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 逻辑闭环
- 用户点踩 (👎)。
- 前端:弹窗询问“哪里不好?”(选项:太啰嗦、不准确、没听懂)。
- 后端:
- 将这条 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 时同步完成) |
对你的建议
- 全盘接受 P0 建议:主动提醒和用户画像是成本低、收益大的功能。
- 技术上保持克制:
- 别写专门的 Alert Engine,用 Cron Skill 复用现有的引擎。
- 别搞复杂的推荐算法,用 JSON 存画像就够了。
- 别搞复杂的 Planner,用 Prompt 教会 ReAct 拆解任务就够了。
这样,你的 V2.6+ 架构就真正补齐了“右脑”的情商短板,变成了一个 “有记忆、会主动、懂人情、能办事” 的完整 Agent。