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:
@@ -0,0 +1,158 @@
|
||||
# **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 会通过**参数**来体现灵活性。
|
||||
|
||||
#### **工具 1:read\_clinical\_data (全能查询器)**
|
||||
|
||||
* **功能**:读取 REDCap 里的任意数据。
|
||||
* **参数**:record\_id (患者ID), fields (想查什么字段), event (哪个访视)。
|
||||
* **灵活性**:
|
||||
* 查年龄?Agent 传 fields: \["age"\]。
|
||||
* 查病史?Agent 传 fields: \["medical\_history"\]。
|
||||
* **你只需要写这一个函数,Agent 就可以查任何东西。**
|
||||
|
||||
#### **工具 2:eval\_logic (逻辑计算器)**
|
||||
|
||||
* **功能**:处理复杂的数值计算或逻辑判断(利用 json-logic)。
|
||||
* **场景**:Agent 算不清 BMI,可以调这个工具帮它算。
|
||||
|
||||
#### **工具 3:manage\_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 是否能聪明地自己填参数。
|
||||
Reference in New Issue
Block a user