链接--医疗多agent项目 langgraph
·
[一] Debug 调试总结 & 调度流程深入讲解
一、Debug 调试总结
你调试的内容 (debug_agent.py)
debug_agent.py 手动按顺序调用了 5 个 Agent:
| 步骤 | 函数 | 测试内容 |
|---|---|---|
| 1 | test_intake() |
将原始文本 → 结构化 patient_info |
| 2 | test_diagnosis() |
patient_info → 差异化诊断 + needs_more_info |
| 3 | test_treatment() |
diagnosis → 治疗方案(含药物相互作用检查) |
| 4 | test_coding() |
diagnosis + treatment_plan → ICD-10/DRGs 编码 |
| 5 | test_audit() |
全量数据 → HIPAA 合规报告 |
核心发现:每个 Agent 都是纯函数,输入是 ClinicalState,输出是 dict(要更新的状态字段)。
二、Pipeline 调度流程详解
2.1 核心文件关系
routes.py (API入口)
↓ POST /api/v1/clinical/analyze
clinical_pipeline.py (LangGraph 图定义)
↓
5个 Agent (intake/diagnosis/treatment/coding/audit)
↓
state.py (ClinicalState 数据流转)
2.2 clinical_pipeline.py — 图结构拆解
第 1 步:构建节点 (add_node)
workflow = StateGraph(ClinicalState)
workflow.add_node("intake", intake_agent) # 节点名 = Agent函数
workflow.add_node("diagnosis", diagnosis_agent)
workflow.add_node("treatment", treatment_agent)
workflow.add_node("coding", coding_agent)
workflow.add_node("audit", audit_agent)
每个 Agent 是一个 LangGraph Node,"intake" 只是节点名称,实际执行的是 intake_agent 函数。
第 2 步:定义入口和边 (edge)
workflow.set_entry_point("intake") # 起点:intake
workflow.add_edge("intake", "diagnosis") # intake 完成后自动去 diagnosis
workflow.add_edge("treatment", "coding") # treatment 完成后自动去 coding
workflow.add_edge("coding", "audit") # coding 完成后自动去 audit
workflow.add_edge("audit", END) # audit 完成后结束
第 3 步:条件路由 (conditional_edges) — 关键
workflow.add_conditional_edges(
"diagnosis", # 监听 diagnosis 节点
_route_after_diagnosis, # ← 路由决策函数
{
"intake": "intake", # needs_more_info=True → 回到 intake
"treatment": "treatment", # needs_more_info=False → 去 treatment
},
)
_route_after_diagnosis 函数 (clinical_pipeline.py:22-30):
def _route_after_diagnosis(state: ClinicalState) -> str:
if state.needs_more_info: # Diagnosis Agent 设置的标志
return "intake" # → 循环回去补充信息
return "treatment" # → 正常流程继续
这是 Diagnosis ↔ Intake 循环 的实现:当 needs_more_info=True 时,Graph 会回到 Intake 重新收集信息。
第 4 步:编译 (compile)
return workflow.compile(checkpointer=MemorySaver())
MemorySaver():内置内存持久化,支持通过thread_id恢复状态- 编译后生成
CompiledStateGraph实例,调用invoke()执行
2.3 状态流转 (State Flow)
┌─────────────────────────────────────────────────────────────────────┐
│ ClinicalState 流转 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ raw_input (患者主诉) │
│ │ │
│ ▼ │
│ ┌─ IntakeAgent ──────────────────────────────────────────────────┐ │
│ │ intake_agent() │ │
│ │ 读取: raw_input │ │
│ │ 写入: patient_info, current_agent │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─ DiagnosisAgent ──────────────────────────────────────────────┐ │
│ │ diagnosis_agent() │ │
│ │ 读取: patient_info │ │
│ │ 写入: diagnosis, needs_more_info, current_agent │ │
│ │ │ │
│ │ ┌─ needs_more_info=True? ──────────────────────────────┐ │ │
│ │ │ ↓ 是 │ │ │
│ │ │ 回到 IntakeAgent (循环) │ │ │
│ │ └──────────────────────────────────────────────────────────┘ │ │
│ │ ↓ 否 │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─ TreatmentAgent ─────────────────────────────────────────────┐ │
│ │ treatment_agent() │ │
│ │ 读取: patient_info, diagnosis │ │
│ │ 写入: treatment_plan, current_agent │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─ CodingAgent ────────────────────────────────────────────────┐ │
│ │ coding_agent() │ │
│ │ 读取: diagnosis, treatment_plan │ │
│ │ 写入: coding_result, current_agent │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─ AuditAgent ─────────────────────────────────────────────────┐ │
│ │ audit_agent() │ │
│ │ 读取: patient_info, diagnosis, treatment_plan, coding_result │
│ │ 写入: audit_result, current_agent │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ [END] │
│ │
└─────────────────────────────────────────────────────────────────────┘
2.4 每个 Agent 的内部逻辑 (以 IntakeAgent 为例)
def intake_agent(state) -> dict:
# 1. 读取输入
raw = state.raw_input
# 2. 调用 LLM(DashScope 阿里云)
llm = ChatOpenAI(
model=settings.openai_model, # "qwen-plus"
api_key=settings.openai_api_key,
base_url=settings.openai_base_url,
temperature=0.1,
)
messages = [
SystemMessage(content=INTAKE_SYSTEM_PROMPT), # 结构化提取指令
HumanMessage(content=f"Patient narrative:\n\n{raw}"),
]
response = llm.invoke(messages) # 3. LLM 推理
content = response.content.strip()
# 4. 解析 JSON 输出
patient_data = json.loads(content)
# 5. 返回要更新的状态字段
return {
"patient_info": patient_data, # ← 写入 state.patient_info
"current_agent": "intake", # ← 标记当前执行者
}
2.5 API 调用链
当你调用 POST /api/v1/clinical/analyze:
FastAPI routes.py
↓
pipeline = get_pipeline() # 获取编译好的图
↓
result = pipeline.invoke(
{"raw_input": req.patient_description},
config={"configurable": {"thread_id": req.thread_id}},
)
↓
返回: {
patient_info: {...},
diagnosis: {...},
treatment_plan: {...},
coding_result: {...},
audit_result: {...},
errors: []
}
三、5 个 Agent 职责速查表
| Agent | 输入 | 输出 | 核心能力 |
|---|---|---|---|
| Intake | raw_input |
patient_info |
文本→结构化(FHIR格式) |
| Diagnosis | patient_info |
diagnosis, needs_more_info |
差异化诊断 + 置信度 |
| Treatment | patient_info, diagnosis |
treatment_plan |
药物相互作用检查(DDI) |
| Coding | diagnosis, treatment_plan |
coding_result |
ICD-10 + DRGs 编码 |
| Audit | 所有字段 | audit_result |
HIPAA 合规 + PHI脱敏 |
四、调试建议
设置断点的关键位置
| 文件:行号 | 目的 |
|---|---|
| intake_agent.py:98 | llm.invoke() — 看 LLM 输入输出 |
| diagnosis_agent.py:97 | 同上 |
| clinical_pipeline.py:22-30 | _route_after_diagnosis() — 看条件路由逻辑 |
| routes.py:75 | pipeline.invoke() — 看整体入口 |
快速验证命令
# 启动服务
cd /home/zxb/work/medical-multi-agent-system/python && source .venv/bin/activate && uvicorn src.api.main:app --reload --port 8000
# 发送测试请求
curl -X POST http://localhost:8000/api/v1/clinical/analyze \
-H "Content-Type: application/json" \
-d '{"patient_description": "45-year-old male with fever for 3 days"}'更多推荐



所有评论(0)