Files
AIclinicalresearch/docs/03-业务模块/IIT Manager Agent/06-开发记录/2026-02-26-P0P1-CRA-Agent-V3.0-完整开发记录.md
HaHafeng 7c3cc12b2e feat(iit): Complete CRA Agent V3.0 P1 - ChatOrchestrator with LLM Function Calling
P1 Architecture: Lightweight ReAct (Function Calling loop, max 3 rounds)

Core changes:
- Add ToolDefinition/ToolCall types to LLM adapters (DeepSeek + CloseAI + Claude)
- Replace 6 old tools with 4 semantic tools: read_report, look_up_data, check_quality, search_knowledge
- Create ChatOrchestrator (~160 lines) replacing ChatService (1,442 lines)
- Wire WechatCallbackController to ChatOrchestrator, deprecate ChatService
- Fix nullable content (string | null) across 12+ LLM consumer files

E2E test results: 8/8 scenarios passed (100%)
- QC report query, critical issues, patient data, trend, on-demand QC
- Knowledge base search, project overview, data modification refusal

Net code reduction: ~1,100 lines
Tested: E2E P1 chat test 8/8 passed with DeepSeek API

Made-with: Cursor
2026-02-26 14:27:09 +08:00

9.1 KiB
Raw Blame History

2026-02-26 CRA Agent V3.0 P0 + P1 完整开发记录

开发日期: 2026-02-25 ~ 2026-02-26
开发人员: AI Assistant
版本: V3.0
状态: P0 + P1 全部完成E2E 测试通过


📋 开发概述

本次开发完成了 CRA Agent V3.0 开发计划中的 P0自驱动质控流水线P1对话层 Tool Use 改造) 两个里程碑,实现了从"关键词路由 ChatService"到"LLM 原生 Function Calling ChatOrchestrator"的完整架构升级。


🎯 P0自驱动质控流水线

P0-1REDCap 变量清单导入 + 可视化

改动文件:

文件 改动内容
frontend-v2/src/modules/iit/pages/FieldMetadataPage.tsx 变量清单页面(搜索、分组、表单筛选)
frontend-v2/src/modules/iit/api/iitProjectApi.ts 前端 API变量清单接口
backend/src/modules/admin/iit-projects/iitFieldMetadataController.ts 后端控制器:变量清单 CRUD
backend/src/modules/admin/iit-projects/iitFieldMetadataRoutes.ts 后端路由注册

P0-2规则配置增强

改动文件:

文件 改动内容
frontend-v2/src/modules/iit/pages/RulesPage.tsx 规则管理页面4 类规则、变量关联)
backend/src/modules/admin/iit-projects/iitRulesController.ts 规则 CRUD 控制器
backend/src/modules/admin/iit-projects/iitRuleSuggestionService.ts AI 辅助规则建议LLM 提取)

P0-3定时质控 + 报告生成 + eQuery 闭环

新增数据库表:

  • iit_schema.equery — eQuery 电子疑问单状态机open → responded → ai_reviewing → resolved / reopened
  • iit_schema.critical_events — 重大事件归档SAE、方案偏离
  • iit_schema.projects 新增 cron_enabled / cron_expression

改动文件:

文件 改动内容
backend/src/modules/iit-manager/services/DailyQcOrchestrator.ts 新增 定时质控编排器(质控 → 报告 → eQuery 派发 → 重大事件归档 → 企微推送)
backend/src/modules/admin/iit-projects/iitEqueryService.ts 新增 eQuery 服务CRUD + 状态机 + AI 复核)
backend/src/modules/admin/iit-projects/iitEqueryController.ts 新增 eQuery 控制器
backend/src/modules/admin/iit-projects/iitEqueryRoutes.ts 新增 eQuery 路由
backend/src/modules/iit-manager/index.ts 注册 iit_daily_qc cron + iit_equery_review worker
backend/prisma/schema.prisma 新增 IitEquery + IitCriticalEvent 模型
backend/prisma/migrations/20260226_add_equery_critical_events_cron/migration.sql 手动 SQL 迁移脚本

P0-4统一质控驾驶舱 + AI Stream

改动文件:

文件 改动内容
frontend-v2/src/modules/iit/pages/DashboardPage.tsx 统一驾驶舱(健康分、核心指标、重大事件、趋势图、风险热力图)
frontend-v2/src/modules/iit/pages/AiStreamPage.tsx AI Agent 工作时间线
frontend-v2/src/modules/iit/pages/EQueryPage.tsx 新增 eQuery 管理页面
frontend-v2/src/modules/iit/pages/ReportsPage.tsx 新增"重大事件归档"Tab
backend/src/modules/admin/iit-projects/iitQcCockpitController.ts 新增 timeline / critical-events / trend 接口
backend/src/modules/admin/iit-projects/iitQcCockpitRoutes.ts 新增驾驶舱路由

P0 E2E 测试

  • 测试脚本: backend/tests/e2e-p0-test.ts
  • 结果: 46/46 全部通过
  • 覆盖: 变量清单 → 规则配置 → 报告 → eQuery → 驾驶舱 → Timeline → 重大事件

🎯 P1对话层 Tool Use 改造

P1-Step 1LLM Adapter 扩展 Function Calling

核心改动: 让 LLM 适配器支持原生 Tool Use / Function Calling。

文件 改动内容
backend/src/common/llm/adapters/types.ts 新增 ToolDefinitionToolCall 类型;Message.role 增加 'tool'LLMOptions 增加 tools/tool_choiceLLMResponse.content 改为 string | null,新增 toolCalls
backend/src/common/llm/adapters/DeepSeekAdapter.ts chat() 支持 tools/tool_choice 参数,解析 tool_calls
backend/src/common/llm/adapters/CloseAIAdapter.ts OpenAI 路径支持 function callingClaude 路径转换为 Anthropic tool_use 格式

级联修复(content: string | null 引起): 12+ 个文件添加 ?? '' null 安全处理。

P1-Step 2ToolsService 重构6 旧 → 4 新)

删除的工具(~300 行):

  • read_clinical_data / run_quality_check / batch_quality_check / get_project_info / count_records / search_protocol

新增的工具(~200 行):

工具名 描述 数据源
read_report 质控报告查阅80% 的问题用这个回答) QcReportService
look_up_data 原始临床数据查询 RedcapAdapter
check_quality 即时质控检查(单条/全量) HardRuleEngine / SkillRunner
search_knowledge 知识库检索 pgvector RAG

P1-Step 3ChatOrchestrator 创建

新文件: backend/src/modules/iit-manager/services/ChatOrchestrator.ts~160 行)

核心架构: 轻量 ReAct带循环的 Function Callingmax 3 轮)

用户提问 → system prompt + history + tools → LLM
  ├── LLM 返回 tool_calls → 并行执行工具 → 追加结果 → 下一轮 LLM
  ├── LLM 返回 tool_calls → ... → 下一轮(最多 3 轮)
  └── LLM 返回 stop / 达到上限 → 返回文本回答

System Prompt 核心指令:

  • 优先使用 read_report80%
  • 所有回答必须基于工具结果,不得伪造数据
  • 中文回复,简洁 ≤200 字
  • 拒绝数据修改请求

P1-Step 4入口接线 + ChatService 废弃

文件 改动内容
backend/src/modules/iit-manager/controllers/WechatCallbackController.ts ChatServiceChatOrchestrator(懒初始化)
backend/src/modules/iit-manager/services/index.ts 导出改为 ChatOrchestrator
backend/src/modules/iit-manager/services/ChatService.ts 重命名为 ChatService.deprecated.ts

P1 E2E 测试

  • 测试脚本: backend/tests/e2e-p1-chat-test.ts
  • 结果: 8/8 全部通过100%
  • 平均响应时间: 5,676ms
场景 输入 工具调用 结果
1. 质控报告 "最新质控报告怎么样" read_report(summary) 返回通过率、问题数
2. 严重违规 "有几条严重违规" 利用上下文记忆直接回答 "69条严重问题"
3. 患者数据 "003 的数据" look_up_data → 失败 → read_report 降级 多轮 ReAct
4. 趋势查询 "通过率比上周好了吗" read_report(trend) 趋势分析
5. 即时质控 "帮我检查一下 005" check_quality(005) 优雅降级
6. 知识库 "入排标准是什么" search_knowledge 精确返回纳入/排除标准
7. 项目概览 "项目整体怎么样" read_report(summary) 汇总项目状况
8. 拒绝修改 "帮我修改 003 的数据" 无工具调用 礼貌拒绝

📊 代码变更统计

指标 数值
P0 新增文件 ~15 个
P1 新增文件 2 个ChatOrchestrator + E2E test
P1 删除代码 ~1,742 行ChatService 1,442 + 旧工具 300
P1 新增代码 ~655 行types 40 + adapters 30 + 新工具 200 + Orchestrator 160 + tests 155 + wiring 10 + null fixes 60
P1 净减少 ~1,100 行
E2E 测试 P0: 46/46 + P1: 8/8 = 54/54100%

🏗️ 架构变化总结

旧架构V2.x ChatService

用户消息 → 10 个正则意图路由 → 9 个硬编码处理方法 → LLM 格式化文本 → 回复
  • 1,442 行代码102 行正则匹配
  • LLM 只是"文本格式化器"
  • 不支持多工具组合

新架构V3.0 ChatOrchestrator

用户消息 → system prompt + 4 tools → LLM 自主选择 → 工具执行 → LLM 总结max 3 轮)
  • ~160 行代码
  • LLM 是"决策者"(自主选择工具、组合调用)
  • 支持多轮推理和自动降级

🔑 关键设计决策

  1. 轻量 ReAct vs 完整 QPER:选择轻量 ReActmax 3 轮 FC loop因为 CRA 场景工具空间有限4 个)、数据预计算、延迟要求低
  2. 报告优先策略read_report 覆盖 80% 问题,避免冗余 REDCap 查询
  3. content: string | null:适配 LLM Function Calling 标准tool_calls 时 content 可为 null
  4. ChatService 保留不删:重命名为 .deprecated.ts,作为参考保留
  5. 数据库手动迁移:为避免 Prisma db push 的数据丢失风险,采用手动 SQL + 迁移文件方式

⚠️ 已知限制

  1. REDCap 本地实例未启动时,look_up_datacheck_quality 会优雅降级
  2. 会话记忆为内存存储SessionMemory重启后丢失
  3. 单项目模式(活跃项目自动解析),暂不支持多项目切换
  4. 平均响应 ~5.7s(含 2 次 DeepSeek API 调用),可通过缓存优化