Files
AIclinicalresearch/docs/03-业务模块/IIT Manager Agent/05-测试文档/IIT Manager Agent V2.9 补充设计:主动性与用户画像增强.md
HaHafeng 0c590854b5 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>
2026-02-05 22:33:26 +08:00

8.4 KiB
Raw Blame History

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 存画像就够了。
    • 别搞复杂的 PlannerPrompt 教会 ReAct 拆解任务就够了。

这样,你的 V2.6+ 架构就真正补齐了“右脑”的情商短板,变成了一个 “有记忆、会主动、懂人情、能办事” 的完整 Agent。