Files
AIclinicalresearch/docs/03-业务模块/IIT Manager Agent/00-系统设计/IIT Manager Agent V2.2:工具泛化与灵活性提升指南.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

158 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# **IIT Manager Agent V2.2:工具泛化与灵活性提升指南**
**核心观点:** 灵活性来自“工具的设计粒度”而不是“连接协议MCP”。
**解决方案:** 通过设计 3-5 个“瑞士军刀型”通用工具,替代 100 个“特种螺丝刀型”专用工具。
## **1\. 直击灵魂MCP Server 真的更灵活吗?**
你担心 V2.1 方案Service Class不够灵活让我们来做个对比
| 维度 | MCP Server 方案 | V2.1 Service Class 方案 | 真相 |
| :---- | :---- | :---- | :---- |
| **新增工具** | 在 Server 进程里写代码 \-\> 重启 Server \-\> Agent 发现新工具 | 在 Service 类里写代码 \-\> 重启 Node.js \-\> Agent 发现新工具 | **工作量完全一样**。都要写代码逻辑。 |
| **工具调用** | Agent 发 JSON \-\> 网络传输 \-\> MCP 执行 | Agent 发 JSON \-\> 内存调用 \-\> Service 执行 | **V2.1 更快**。没有网络开销。 |
| **Agent 自主性** | LLM 看到的是 tool definitions (JSON) | LLM 看到的也是 tool definitions (JSON) | **LLM 根本分不清**你是 MCP 还是 Service。 |
**结论:**
* **MCP 的灵活性在于“解耦”**:比如你可以把 REDCap 工具给别人用,或者在运行时动态加载新的 Server。
* **V2.1 的灵活性在于“敏捷”**:代码都在一个工程里,改起来最快。对于 2 人团队,**改代码 \> 调协议**。
## **2\. 你的痛点:是不是要写很多工具?**
你担心:“如果有 100 个检查点,我是不是要写 check\_age, check\_gender, check\_bmi 一百个工具?”
**绝对不需要!** 这就是我说的\*\*“工具泛化”\*\*。
### **错误的设计(特种螺丝刀)**
写一堆具体的工具,导致 Service 类无限膨胀:
* get\_patient\_age(id)
* get\_patient\_history(id)
* check\_informed\_consent(id)
* ...
### **正确的设计(瑞士军刀)**
只写 **3 个** 通用工具,就能覆盖 99% 的场景。Agent 会通过**参数**来体现灵活性。
#### **工具 1read\_clinical\_data (全能查询器)**
* **功能**:读取 REDCap 里的任意数据。
* **参数**record\_id (患者ID), fields (想查什么字段), event (哪个访视)。
* **灵活性**
* 查年龄Agent 传 fields: \["age"\]。
* 查病史Agent 传 fields: \["medical\_history"\]。
* **你只需要写这一个函数Agent 就可以查任何东西。**
#### **工具 2eval\_logic (逻辑计算器)**
* **功能**:处理复杂的数值计算或逻辑判断(利用 json-logic
* **场景**Agent 算不清 BMI可以调这个工具帮它算。
#### **工具 3manage\_issue (通用反馈器)**
* **功能**:包括提出质疑、发送提醒、记录日志。
* **参数**type (QUERY | NOTIFY | LOG), message (内容), severity (严重程度)。
## **3\. 代码实现:如何实现“瑞士军刀”?**
在你的 ToolsService.ts 中,只需要实现这几个通用方法。
// backend/src/modules/iit-manager/services/ToolsService.ts
export const UNIVERSAL\_TOOL\_DEFS \= \[
{
name: "read\_clinical\_data",
description: "通用数据查询工具。当需要检查患者的某项指标时使用。",
parameters: {
type: "object",
properties: {
record\_id: { type: "string" },
// 关键:让 Agent 自己决定查什么字段
fields: {
type: "array",
items: { type: "string" },
description: "需要查询的REDCap变量名列表如 \['age', 's\_cr', 'ae\_desc'\]"
}
},
required: \["record\_id", "fields"\]
}
},
{
name: "manage\_issue",
description: "通用问题处理工具。用于提出质疑或发送通知。",
parameters: {
type: "object",
properties: {
record\_id: { type: "string" },
action\_type: { type: "string", enum: \["RAISE\_QUERY", "SEND\_WECHAT"\] },
message: { type: "string" }
},
required: \["record\_id", "action\_type", "message"\]
}
}
\];
export class ToolsService {
constructor(private redcapAdapter: RedcapAdapter) {}
async execute(name: string, args: any) {
switch (name) {
case 'read\_clinical\_data':
// 一个函数,通过参数变化应对无限需求
return await this.redcapAdapter.exportRecords({
recordId: args.record\_id,
fields: args.fields // \<--- 动态字段
});
case 'manage\_issue':
if (args.action\_type \=== 'RAISE\_QUERY') {
return await this.saveShadowQuery(args);
} else {
return await this.sendWechat(args);
}
}
}
}
## **4\. 场景演示Agent 的自主性如何体现?**
哪怕你只提供了 2 个工具Agent 依然表现得像个专家,因为**Skill (Prompt)** 在指导它如何组合使用这些工具。
### **场景 A检查肝功能**
* **Skill 配置**: "instruction": "检查 ALT 和 AST 是否超过正常值 3 倍。"
* **Agent 思考**: "我要查肝功能。"
* **Agent 行动**: 调用 read\_clinical\_data(fields=\['alt', 'ast'\])。
* **系统响应**: {"alt": 150, "ast": 40}
* **Agent 判断**: "ALT 150 \> 40\*3。违规。"
* **Agent 行动**: 调用 manage\_issue(action\_type='RAISE\_QUERY', message='ALT异常')。
### **场景 B检查入组年龄**
* **Skill 配置**: "instruction": "确保患者年龄 \> 18。"
* **Agent 思考**: "我要查年龄。"
* **Agent 行动**: 调用 read\_clinical\_data(fields=\['age'\])。
* **系统响应**: {"age": 16}
* **Agent 行动**: 调用 manage\_issue(action\_type='RAISE\_QUERY', message='年龄不合规')。
**看到没有?**
你**没有写** check\_liver 和 check\_age 两个函数。
你只写了一个 read\_clinical\_data。
**Agent 的大脑Prompt** \+ **通用工具Tool** 实现了无限的灵活性。
## **5\. 总结**
1. **MCP Server 不是灵活性的来源**:它只是一个连接标准。如果你的工具设计得烂(粒度太细),用 MCP 也一样累。
2. **通用参数是王道**:不要写“查年龄”的工具,要写“查字段”的工具。让 Agent 填参数,这就是最大的灵活性。
3. **V2.1 极简版足够强**:只要你的 ToolsService 按照“瑞士军刀”的思路去设计2 个开发人员维护 100 个项目的逻辑完全没有压力。
**行动建议:**
按照本文档的 **第 3 节**,把你的 ToolsService 重构一下,只保留 3-5 个通用方法。然后去测试一下 Agent 是否能聪明地自己填参数。