# **技术设计文档 (TDD):ASL \- 智能文献检索 (Deep Research) MVP 版** **文档版本:** v4.4-Tech (MVP 自然语言确认版) **核心架构:** LLM Requirement Expansion (需求扩写) \+ Postgres-Only (pg-boss) \+ Unifuncs Async API ## **🏗️ 1\. 系统数据流向 (Data Flow)** MVP 版本的架构最大程度降低了状态维护的成本,充分利用 Unifuncs 原生支持自然语言查询的能力。 1. Client 发送原始简短自然语言 \-\> Node.js 调用 DeepSeek-V3 \-\> 返回**结构化、扩写后的自然语言检索需求(Search Requirements)**(非布尔检索式)。 2. Client 展示该检索需求(普通文本/Markdown),允许用户直接进行文字修改与补充 \-\> 用户点击执行,发送修改后的 Confirmed Requirement \-\> Node.js 创建 pg-boss 任务。 3. Worker 启动 \-\> 将用户确认的自然语言需求直接作为 content 传给 Unifuncs 创建任务 \-\> 每 5 秒轮询一次 Unifuncs \-\> 增量日志写入 PostgreSQL。 4. Client 每 3 秒轮询 Node.js 获取日志 \-\> 渲染 Terminal \-\> 任务完成,渲染结果。 ## **🗄️ 2\. 数据库设计 (Prisma)** 极简表结构,去掉了复杂的澄清记录,只保留原始问题和最终执行的自然语言需求。 model AslResearchTask { id String @id @default(uuid()) user\_id String // Step 1 & 2 original\_query String @db.Text target\_sources Json // 选中的数据源,如 \["pubmed.ncbi.nlm.nih.gov"\] filters Json // 高级过滤条件 confirmed\_requirement String? @db.Text // 核心字段:用户复核并修改后的自然语言检索需求 // Step 3 status String // 'draft', 'pending', 'running', 'completed', 'failed' unifuncs\_task\_id String? // 外部API的ID execution\_logs Json? // 终端日志 \[{type: 'log', text: '...'}, ...\] // Step 4 result\_list Json? synthesis\_report String? @db.Text created\_at DateTime @default(now()) updated\_at DateTime @updatedAt } ## **🔌 3\. 核心 API 契约** ### **3.1 检索需求扩写接口 (同步, 无状态)** * **POST /api/v1/asl/research/generate-requirement** * **处理:** 拦截用户简短输入,拼装 System Prompt,调用系统内置 LLMFactory(DeepSeek-V3)。 * *System Prompt 示例:* “你是一个医学检索辅助专家。请将用户简短的研究意图,扩写并梳理成一份条理清晰的自然语言检索需求说明。内容包括:1. 核心检索主题;2. 建议包含的专业关键词(中英文);3. 目标人群及干预措施限定;4. 文献类型建议(如 RCT)。输出纯文本,方便用户二次编辑。” * *同时:* 创建数据库记录(状态为 draft)。 * **返回:** { taskId: "uuid", generatedRequirement: "研究主题:他汀类药物...\\n目标人群:...\\n检索要求:..." } ### **3.2 任务启动接口 (进入异步队列)** * **PUT /api/v1/asl/research/tasks/:id/execute** * **请求体:** { confirmedRequirement: string } * **处理:** 1\. 更新 AslResearchTask 的 confirmed\_requirement 字段。 2\. jobQueue.createJob('deep-research-worker', { taskId: id }) 3\. 更新状态为 pending。 * **返回:** { success: true } ### **3.3 任务状态与日志轮询接口** * **GET /api/v1/asl/research/tasks/:id** * **返回:** 包含 status, execution\_logs, 以及(若完成)synthesis\_report 和 result\_list。 ## **⚙️ 4\. 后台 Worker 逻辑 (Unifuncs 集成)** 使用平台现有的 pg-boss 机制。 // backend/src/modules/asl/workers/DeepResearchWorker.ts export async function processDeepResearch(job: Job) { const taskId \= job.data.taskId; const task \= await prisma.aslResearchTask.findUnique({ where: { id: taskId } }); // 1\. 发起 Unifuncs 创建任务请求 const unifuncsPayload \= { model: "s2", // 💡 核心变更:直接将用户确认的、详细的自然语言需求传给 Unifuncs,由 Unifuncs 自己去理解和拆解检索词 messages: \[{ role: "user", content: \`请根据以下详细检索需求执行深度研究:\\n${task.confirmed\_requirement}\` }\], introduction: "你是一名资深的循证医学研究员。请严格遵循用户的检索需求,在指定数据库中执行详尽的深度检索。", max\_depth: 25, domain\_scope: task.target\_sources, // 强制输出格式以分离报告与文献JSON output\_prompt: \` \ \[撰写综合报告\] \ \ \[输出严格的文献JSON数组\] \ \`, reference\_style: "link" }; const createRes \= await unifuncsClient.createTask(unifuncsPayload); const unifuncsId \= createRes.data.task\_id; await prisma.aslResearchTask.update({ where: { id: taskId }, data: { unifuncs\_task\_id: unifuncsId, status: 'running' } }); // 2\. 轮询 Unifuncs 状态 (防无限死循环,设置最大重试次数) let isCompleted \= false; let maxRetries \= 120; // 假设每5秒查一次,最多查10分钟 while (\!isCompleted && maxRetries \> 0\) { await sleep(5000); const queryRes \= await unifuncsClient.queryTask(unifuncsId); // 解析增量日志 reasoning\_content const logs \= parseReasoningToLogs(queryRes.data.result?.reasoning\_content); // 更新数据库日志 (覆盖或追加) await prisma.aslResearchTask.update({ where: { id: taskId }, data: { execution\_logs: logs } }); if (queryRes.data.status \=== 'completed') { isCompleted \= true; // 解析提取 \ 和 \ const report \= extractReport(queryRes.data.result.content); const list \= extractJsonList(queryRes.data.result.content); await prisma.aslResearchTask.update({ where: { id: taskId }, data: { status: 'completed', synthesis\_report: report, result\_list: list } }); } maxRetries--; } } ## **🛡️ 5\. 技术优势** 1. **零学习成本**:去除了对医生来说晦涩难懂的“布尔逻辑检索式”,整个确认过程完全采用大白话(自然语言),用户审查和修改都极其自然。 2. **充分发挥 API 威力**:将“拆解关键词、发起搜索、阅读网页”的复杂动作全部下放给专业的 Unifuncs 引擎,本系统架构只做轻量级的“需求扩写”和“流式日志透传”,代码稳定性极高。 3. **极速上线**:前端页面仅需一个大文本框渲染扩写后的要求,没有任何复杂的 UI 组件开销,是名副其实的 MVP 最优解。