# **技术设计文档 (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 最优解。