feat(aia): Implement Protocol Agent MVP with reusable Agent framework

Sprint 1-3 Completed (Backend + Frontend):

Backend (Sprint 1-2):
- Implement 5-layer Agent framework (Query->Planner->Executor->Tools->Reflection)
- Create agent_schema with 6 tables (agent_definitions, stages, prompts, sessions, traces, reflexion_rules)
- Create protocol_schema with 2 tables (protocol_contexts, protocol_generations)
- Implement Protocol Agent core services (Orchestrator, ContextService, PromptBuilder)
- Integrate LLM service adapter (DeepSeek/Qwen/GPT-5/Claude)
- 6 API endpoints with full authentication
- 10/10 API tests passed

Frontend (Sprint 3):
- Add Protocol Agent entry in AgentHub (indigo theme card)
- Implement ProtocolAgentPage with 3-column layout
- Collapsible sidebar (Gemini style, 48px <-> 280px)
- StatePanel with 5 stage cards (scientific_question, pico, study_design, sample_size, endpoints)
- ChatArea with sync button and action cards integration
- 100% prototype design restoration (608 lines CSS)
- Detailed endpoints structure: baseline, exposure, outcomes, confounders

Features:
- 5-stage dialogue flow for research protocol design
- Conversation-driven interaction with sync-to-protocol button
- Real-time context state management
- One-click protocol generation button (UI ready, backend pending)

Database:
- agent_schema: 6 tables for reusable Agent framework
- protocol_schema: 2 tables for Protocol Agent
- Seed data: 1 agent + 5 stages + 9 prompts + 4 reflexion rules

Code Stats:
- Backend: 13 files, 4338 lines
- Frontend: 14 files, 2071 lines
- Total: 27 files, 6409 lines

Status: MVP core functionality completed, pending frontend-backend integration testing

Next: Sprint 4 - One-click protocol generation + Word export
This commit is contained in:
2026-01-24 17:29:24 +08:00
parent 61cdc97eeb
commit 96290d2f76
345 changed files with 13945 additions and 47 deletions

View File

@@ -0,0 +1,163 @@
# **研究方案制定 Agent (Protocol Agent) 统一架构方案 V3.0**
版本: v3.0 (SOP编排与后端配置版)
日期: 2026-01-20
适用范围: 壹证循科技 (AIclinicalresearch)
核心进化: 引入 "Code-as-Skeleton, Data-as-Brain" 理念。将思维链 (CoT) 下沉为后端可配置的 SOP 数据,实现逻辑与代码解耦。
## **1\. 核心设计理念**
我们摒弃传统的“无状态问答”模式,构建一个维护长程记忆、具备反思能力的 **Protocol Agent**
### **1.1 四大核心组件 (The 4 Pillars)**
* 🧠 **大脑 (Brain): Orchestrator 服务**
* 负责 **规划 (Plan)**:决定当前处于哪个阶段,下一步该做什么。
* 负责 **反思 (Reflexion)**:对用户的操作结果进行质量校验(如样本量是否合理)。
* **升级点**V3 版本中,大脑的思考逻辑(思维链)不再写死在代码里,而是从数据库加载配置。
* 💾 **记忆 (Memory): ProtocolContext 表**
* 利用 Postgres 的 JSONB 存储“活的”方案数据。
* **长程记忆**:不仅记住聊天记录,更记住结构化的 PICO、样本量 N 值、观察指标等关键状态,突破 LLM Token 限制。
* 📚 **知识 (Knowledge): 自建 EKB (Postgres-Only)**
* 提供 **混合检索 (Hybrid Search)** 能力。
* **结构化检索**:利用 SQL 精准筛选(如“找样本量\>500的RCT研究”
* **语义检索**:利用 pgvector 进行向量相似度匹配。
* 🛠️ **手脚 (Hands): Deep Link Action**
* 通过 **Action Card** 调用的现有 Web 工具(如样本量计算器、数据清洗工具)。
* 实现“对话无法完成的复杂操作,跳转到专业工具完成,再把结果同步回来”的闭环。
### **1.2 总体架构拓扑 (V3)**
引入了全新的 **LLM Ops 控制层**,支持运营人员在后台动态调整 Agent 的思考逻辑。
graph TD
User\[用户 (React UI)\] \<--\> Entry\[单一入口: Protocol Agent\]
subgraph "前端交互 (Interaction)"
Chat\[流式对话\]
StatePanel\[实时状态看板\]
DeepLink\[Action Card\]
end
Entry \--\> Chat & StatePanel
subgraph "后端引擎 (Orchestrator Engine)"
Loader\[配置加载器\]
Executor\[SOP 执行引擎\]
Reflector\[Reflexion 卫士\]
Tracer\[全链路追踪\]
end
Chat \<--\> Executor
subgraph "大脑配置中心 (LLM Ops)"
DB\_Prompt\[(Prompt & CoT 表)\]
DB\_Trace\[(Trace 日志表)\]
AdminUI\[运营管理后台\]
end
AdminUI \--配置 SOP--\> DB\_Prompt
DB\_Prompt \--加载--\> Loader
Loader \--注入--\> Executor
Executor \--写入日志--\> Tracer
Tracer \--可视化--\> AdminUI
subgraph "记忆与知识 (Memory & Knowledge)"
DB\_Ctx\[(Protocol Context)\]
DB\_EKB\[(Self-built RAG)\]
end
Executor \<--\> DB\_Ctx & DB\_EKB
## **2\. 核心机制:后端配置化思维链 (Backend CoT)**
### **2.1 什么是“配置化 CoT”**
我们将 AI 的思考过程拆解为标准作业程序 (SOP),存储为 JSON 数组。这意味着您可以在后台增加一个检查步骤,而无需修改代码。
**数据库配置示例 (JSON):**
\[
{
"step": 1,
"key": "completeness\_check",
"desc": "检查 PICO 完整性",
"instruction": "检查用户输入是否包含 P, I, C, O 四个要素。如果缺失,标记为 MISSING。"
},
{
"step": 2,
"key": "methodology\_match",
"desc": "方法学匹配",
"instruction": "根据研究目的推荐设计类型RCT/队列)。"
},
{
"step": 3,
"key": "response\_generation",
"desc": "生成回复",
"instruction": "综合以上分析,给出建议。如果 PICO 缺失,请追问。"
}
\]
### **2.2 运行时表现 (Runtime Behavior)**
Orchestrator 会将上述 JSON 动态编译为 System Prompt。AI 的输出将包含显式的 **XML 思考标签**
\<completeness\_check\>
用户提供了 P 和 I但缺失 C (对照组) 和 O (结局)。
\</completeness\_check\>
\<methodology\_match\>
因缺失关键信息,暂无法确定设计类型,倾向于 RCT。
\</methodology\_match\>
\<response\_generation\>
您好,为了帮您设计方案,我还需要了解:您的对照组是什么?主要结局指标是什么?
\</response\_generation\>
**前端展示:** 前端解析 \<completeness\_check\> 标签,将其放入可折叠的 **"深度思考"** 组件中,让用户看到 AI 的逻辑。
## **3\. 业务流程编排**
### **3.1 完整交互闭环**
1. **User**: 输入 "我要做阿司匹林的研究"。
2. **Orchestrator**:
* 加载当前阶段 (SCIENTIFIC\_QUESTION) 的 Prompt 和 CoT 配置。
* 执行 LLM 生成。
3. **Reflexion (隐式)**:
* Orchestrator 后台运行微型 LLM 任务,尝试从对话中提取 PICO。
* 如果提取成功,更新 ProtocolContext。
4. **State Panel**: 前端通过 SSE 收到更新,右侧面板自动点亮 "P" 和 "I" 字段。
5. **Plan**:
* Orchestrator 判断当前阶段已完成 (PICO 齐全)。
* **主动推送**:生成 Action Card "建议进入下一步:选题评价"。
### **3.2 深度链接与反思 (Deep Link & Reflexion Loop)**
当涉及到工具调用(如样本量计算)时:
1. **Action**: AI 生成 Action Card (Deep Link)。
2. **Execute**: 用户点击跳转 \-\> 工具页计算 \-\> 点击“同步”。
3. **Reflexion Guard (后端强制校验)**:
* 数据回写到 DB 时,触发后端校验函数 reflexionGuard()。
* **规则配置化**(N \< 10 OR N \> 10000\) \-\> 报警。
* **反馈**如果校验失败AI 主动发送消息:“⚠️ 样本量异常,请检查参数。”
## **4\. 可观测性与调试 (Observability)**
为了解决 "Prompt 难调" 的问题V3 引入了 **Trace 机制**
* **Trace ID**: 每次对话生成一个唯一 ID。
* **Step Recording**: 记录 Router 决策、Prompt 组装结果、CoT 输出、工具返回。
* **Replay**: 在 Admin 后台,可以一键重放某个 Trace修改 Prompt 后重新运行,对比效果。
## **5\. 实施路线图 (Roadmap)**
1. **Week 1: 数据层升级**
* 修改 prompt\_templates 表结构,增加 chain\_config。
* 建立 agent\_traces 表。
2. **Week 2: 引擎升级**
* 重构 Orchestrator实现动态 CoT 组装逻辑。
* 实现 XML 标签解析器。
3. **Week 3: 前端适配**
* 升级 Chat 组件,支持渲染 XML 思考过程。
* 完善右侧 State Panel 的实时同步。

View File

@@ -0,0 +1,116 @@
# **Protocol Agent 后端配置架构设计 (V3.0 核心思路)**
设计目标: 将硬编码的业务逻辑转化为可运营的配置数据。
核心范式: 全局继承 \+ 阶段重写 \+ 组件化逻辑
## **1\. 配置层级概览 (The Configuration Hierarchy)**
我们不再把 Prompt 看作一个长字符串,而是一个 **“动态组装对象”**。
graph TD
Global\[全局配置 (Global Config)\] \--\> Stage\[阶段配置 (Stage Config)\]
subgraph "Level 1: 全局设定"
Global \--\> BasePrompt\[人设: 资深医学专家\]
Global \--\> ContextDef\[记忆结构: PICO/N值\]
Global \--\> GlobalTools\[通用工具: EKB检索\]
end
subgraph "Level 2: 阶段设定 (覆盖 7 个模块)"
Stage \--\> TaskPrompt\[任务指令: 算样本量\]
Stage \--\> CoT\[思维链 SOP\]
Stage \--\> Reflexion\[反思卫士规则\]
Stage \--\> StageTools\[专用工具: 计算器\]
end
## **2\. 详细配置清单 (后端都有哪些需要配置的?)**
### **2.1 Level 1: 全局配置 (Global Configuration)**
这是 Agent 的“底色”,在所有阶段都会生效。
| 配置项 | 说明 | 示例值 |
| :---- | :---- | :---- |
| **Agent Name** | 智能体名称 | 研究方案制定助手 (Protocol Agent) |
| **Base System Prompt** | **总体 Prompt** | "你是一个严谨的临床研究方法学专家。你的核心目标是辅助用户产出高质量的 Protocol。你必须依据循证医学证据说话..." |
| **Tone of Voice** | 语气风格 | 专业、客观、循循善诱(不要过于热情,保持学术严谨性) |
| **Global Knowledge** | 全局知识库挂载 | 关联 ekb\_schema (自建知识库),允许检索所有 Guideline 类型文档。 |
| **Memory Structure** | 记忆结构定义 | 定义 ProtocolContext 的 JSON Schema告诉 AI 它能记住哪些字段,如 PICO。 |
### **2.2 Level 2: 阶段配置 (Stage Configuration)**
这是 7 个具体模块的配置区。用户处于哪个阶段Orchestrator 就加载哪份配置**覆盖**进 System Prompt。
| 配置项 | 说明 | 示例值 (以样本量计算为例) |
| :---- | :---- | :---- |
| **Stage ID** | 阶段标识 | SAMPLE\_SIZE\_CALC |
| **Stage Trigger** | 进入条件 (Router) | 当用户 PICO 完整 且 研究类型为 RCT 时。 |
| **Stage Instruction** | **阶段任务指令** | "当前任务是计算样本量。请根据用户提供的 Alpha/Power 参数,推荐合适的计算公式。" |
| **Specific Tools** | 专用工具绑定 | 绑定 tools/st/sample-size (Action Card)。 |
| **Output Schema** | 结构化提取目标 | 定义需要从对话中提取哪些字段存入 DB如 n\_value, alpha。 |
### **2.3 Level 3: 逻辑与风控配置 (Logic & Reflexion)**
这是您特别关心的 **“思维链”** 和 **“反思卫士”**。
#### **A. 思维链 (CoT) 配置**
我们不再把思考过程写在 Prompt 文本里,而是配置为 **SOP 步骤列表**
* **配置方式**:一个有序数组。
* **配置内容**
1. **Step 1 \[Check\]**: 检查必要参数Alpha, Power是否齐全。
2. **Step 2 \[Match\]**: 匹配研究设计(是两样本均数比较,还是率的比较?)。
3. **Step 3 \[Recall\]**: 回忆/检索类似研究的 Effect Size 作为参考。
4. **Step 4 \[Action\]**: 决定是追问用户,还是生成 Action Card。
#### **B. 反思卫士 (Reflexion Guard) 配置**
这是 V3 的核心升级。我们需要配置 **“什么样的情况是错误的”**。
可以分为两类配置:
1. **Prompt-based Reflexion (软校验)**:
* 配置一段 Prompt 让 AI 自查:“请检查用户计算出的 N 值是否过小(\<20如果是请给出伦理预警。”
2. **Rule-based Reflexion (硬校验 \- 高级)**:
* 配置 JSON 规则(后端解析执行):
{
"rules": \[
{ "field": "sample\_size.n", "operator": "\<", "value": 10, "msg": "样本量过小" },
{ "field": "sample\_size.power", "operator": "\<", "value": 0.8, "msg": "效能不足" }
\]
}
## **3\. 系统运行时的组装逻辑**
当用户发来一条消息时,后端 Orchestrator 是这样工作的:
1. **加载全局**:取 Global.BasePrompt。
2. **定位阶段**:根据当前 Context.stage (比如样本量),取 Stage.TaskPrompt。
3. **注入 SOP**:取 Stage.CoT编译成 XML 格式的思考指令。
* Step 1: \<check\>...\</check\>
* Step 2: \<match\>...\</match\>
4. **挂载反思**:取 Stage.Reflexion如果是 Prompt 类型的反思,追加到最后。
5. **最终合成**
\[Global Persona\] ...
\[Context Data\] ...
\[Stage Instruction\] ...
\[CoT Steps (SOP)\] ...
\[Reflexion Instructions\] ...
## **4\. 总结:设计建议**
**您现在的思路非常清晰:**
1. **全局控制 (Overall Prompt)** 是必须的,它是 Agent 的“灵魂”保证了无论在哪个阶段AI 说话的方式都是一致的。
2. **分阶段配置** 是“肉体”,负责具体的干活技能。
3. **思维链 & 反思** 是“神经系统”,负责控制思考的深度和质量。
下一步建议:
我将在下一个回复中,为您设计 "后端配置中心" 的 UI 原型。
这个原型将不再关注调试对话框,而是关注 "如何像搭积木一样配置上述的三层结构"。
它应该包含:
* **全局设置页**:配置 Agent 人设。
* **流程编排页**一个左侧导航7个阶段右侧配置Prompt \+ CoT \+ Reflexion的布局。
* **SOP 编辑器**:专门用来拖拽/编辑思维链步骤的区域。

View File

@@ -0,0 +1,244 @@
# **研究方案制定 Agent 技术实现手册 V3.0**
版本: v3.0
关联文档: Protocol\_Agent\_Architecture\_Design\_V3.md
核心内容: 数据库 Schema、核心服务代码、API 协议。
## **1\. 数据库设计 (Prisma Schema)**
### **1.1 记忆层 (Memory Layer)**
存储“活的”方案数据,实现长程记忆。
// aia\_schema.prisma
model ProtocolContext {
id String @id @default(uuid())
conversationId String @unique @map("conversation\_id")
userId String @map("user\_id")
// 状态机
currentStage String @default("SCIENTIFIC\_QUESTION")
status String @default("IN\_PROGRESS")
// 活的方案数据 (JSONB)
// 包含: scientific\_question, pico, study\_design, outcomes, sample\_size 等
data Json @default("{}")
// V3 新增: 存储上一次的反思结果,避免重复报错
lastReflexion Json? @map("last\_reflexion")
createdAt DateTime @default(now()) @map("created\_at")
updatedAt DateTime @updatedAt @map("updated\_at")
@@table("protocol\_contexts")
@@schema("aia\_schema")
}
### **1.2 配置层 (Configuration Layer)**
这是 V3 的核心,支持后端配置 CoT。
// capability\_schema.prisma
model PromptTemplate {
id String @id @default(uuid())
code String @unique // e.g., AIA\_SAMPLE\_SIZE
version Int @default(1)
// 基础人设
content String @db.Text
// V3 新增: 思维链配置 (JSONB)
// 存储 ChainStep\[\] 数组
chainConfig Json? @map("chain\_config")
// V3 新增: 路由规则配置 (JSONB, 可选)
// 用于定义何时切出该阶段
routerConfig Json? @map("router\_config")
isActive Boolean @default(true)
updatedAt DateTime @updatedAt
@@table("prompt\_templates")
@@schema("capability\_schema")
}
model AgentTrace {
id String @id @default(uuid())
conversationId String @map("conversation\_id")
stage String
// 记录完整上下文
inputPayload Json @map("input\_payload")
outputPayload Json @map("output\_payload")
// 耗时与消耗
latencyMs Int @map("latency\_ms")
tokens Int @default(0)
createdAt DateTime @default(now())
@@table("agent\_traces")
@@schema("capability\_schema")
}
## **2\. 核心服务代码 (Orchestrator Engine)**
### **2.1 动态 CoT 组装器 (promptBuilder.ts)**
负责将 DB 中的 SOP 配置编译成 System Prompt。
import { prisma } from '@/common/db';
interface ChainStep {
key: string;
desc: string;
instruction: string;
}
export async function buildDynamicSystemPrompt(stage: string, contextData: any) {
// 1\. 加载配置
const template \= await prisma.promptTemplate.findUnique({ where: { code: stage } });
if (\!template) throw new Error(\`Prompt not found: ${stage}\`);
const chainSteps \= template.chainConfig as ChainStep\[\] || \[\];
// 2\. 组装基础 Prompt (Persona)
let systemPrompt \= \`${template.content}\\n\\n\`;
// 3\. 注入当前上下文 (Memory)
systemPrompt \+= \`=== 当前方案状态 (Context) \===\\n${JSON.stringify(contextData, null, 2)}\\n\\n\`;
// 4\. 注入思维链 SOP (V3 核心)
if (chainSteps.length \> 0\) {
systemPrompt \+= \`=== 思考步骤 (SOP) \===\\n\`;
systemPrompt \+= \`请严格按照以下步骤进行思考,并使用 XML 标签包裹每一步的内容:\\n\`;
chainSteps.forEach((step, idx) \=\> {
systemPrompt \+= \`${idx \+ 1}. \<${step.key}\>: ${step.instruction}\\n\`;
});
systemPrompt \+= \`最后,在 \<response\> 标签中输出给用户的回复。\\n\`;
}
return systemPrompt;
}
### **2.2 编排器主逻辑 (ProtocolOrchestrator.ts)**
协调 Brain, Memory, Knowledge 和 Hands。
export class ProtocolOrchestrator {
async handleMessage(userId: string, conversationId: string, content: string) {
// 1\. 获取上下文 (Memory)
let ctx \= await prisma.protocolContext.findUnique({ where: { conversationId } });
// 2\. \[Reflexion Guard\] 检查数据变更
// 如果之前状态是 WAITING\_USER 且数据变了,说明工具执行回来了 (Hands 回调)
if (ctx.status \=== 'WAITING\_USER\_ACTION' && await this.checkDataChanged(ctx)) {
const validation \= await this.runReflexionCheck(ctx);
if (\!validation.pass) {
return this.streamResponse(\`⚠️ \*\*校验未通过\*\*: ${validation.reason}\`);
}
// 校验通过,重置状态
await this.updateStatus(ctx.id, 'IN\_PROGRESS');
}
// 3\. \[Knowledge RAG\] 混合检索 (自建 EKB)
// 仅在需要知识的阶段调用
const ragContext \= await knowledgeService.search(content, ctx.currentStage);
// 4\. \[Prompt Build\] 动态组装 (Brain)
const systemPrompt \= await buildDynamicSystemPrompt(ctx.currentStage, ctx.data);
// 5\. \[Execution\] 流式生成
const traceId \= await traceService.startTrace(conversationId, 'GENERATE');
return streamingService.streamGenerate({
systemPrompt,
userMessage: content \+ (ragContext ? \`\\n\\n参考资料:\\n${ragContext}\` : ''),
onFinish: async (output) \=\> {
await traceService.endTrace(traceId, output);
// 异步触发:结构化提取任务 (更新 Memory)
await pgBoss.send('extract-protocol-data', { conversationId, text: output });
}
});
}
}
## **3\. 交互协议 (Deep Link Protocol)**
### **3.1 Action Card Payload (Backend \-\> Frontend)**
Orchestrator 决定需要用户操作时,发送此 JSON。
{
"type": "action\_card",
"data": {
"title": "建议:样本量计算",
"tool\_code": "SAMPLE\_SIZE\_CALC",
"path": "/tools/st/sample-size",
"params": {
"ctx\_id": "uuid-1234", // 关键传递上下文ID让工具知道往哪里回写
"alpha": 0.05,
"power": 0.8
}
}
}
### **3.2 同步回写 API (Tool \-\> Backend)**
工具端(如样本量计算器)计算完成后,调用此接口回写结果。
**POST** /api/v1/aia/protocol/:ctxId/sync
{
"stage": "SAMPLE\_SIZE",
"data": {
"n\_total": 386,
"method": "t-test",
"params": { "alpha": 0.05, "power": 0.8 }
}
}
## **4\. 提取与反思 (Extraction & Reflexion)**
### **4.1 异步提取 Worker**
负责从非结构化对话中“提纯”信息存入 Memory。
// workers/extractionWorker.ts
export async function extractProtocolData(job) {
const { conversationId, text } \= job.data;
// 调用廉价模型 (DeepSeek-Flash) 进行 JSON 提取
const extracted \= await llm.extractJson(text, EXTRACT\_PROMPT);
if (extracted) {
// 智能合并策略 (Deep Merge)
await prisma.protocolContext.update({
where: { conversationId },
data: { data: deepMerge(currentData, extracted) }
});
}
}
### **4.2 反思校验规则 (Reflexion Rules)**
**Brain****Hands** 操作结果的质检逻辑。
function runReflexionCheck(ctx: ProtocolContext) {
const { sample\_size } \= ctx.data;
if (\!sample\_size) return { pass: true };
// 规则 1: 伦理红线
if (sample\_size.n\_total \< 10\)
return { pass: false, reason: "样本量过小 (\<10),无法通过伦理审查" };
// 规则 2: 可行性预警
if (sample\_size.n\_total \> 10000\)
return { pass: false, reason: "样本量过大,请确认经费和周期是否支持" };
return { pass: true };
}