news 2026/9/15 18:29:11

MiniCPM4-Survey 综述论文自动生成实战:Plan-Retrieve-Write 多智能体框架的部署、推理与源码解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MiniCPM4-Survey 综述论文自动生成实战:Plan-Retrieve-Write 多智能体框架的部署、推理与源码解析

MiniCPM4-Survey 综述论文自动生成实战:Plan-Retrieve-Write 多智能体框架的部署、推理与源码解析

【免费下载链接】MiniCPMMiniCPM5: SOTA on-device LLMs, small yet powerful.项目地址: https://gitcode.com/GitHub_Trending/mi/MiniCPM

本篇技术指南以开源仓库中的 demo/minicpm4/SurveyGeneration/README-en.md 为骨架,围绕 MiniCPM4-Survey——一个基于 MiniCPM4-8B 构建的、能够自主生成可信长篇综述论文(Survey)的智能体模型——系统讲解其「规划—检索—写作」三阶段生成框架的完整落地路径:从模型与数据集下载、检索库构建,到 vLLM 推理、FAISS 检索服务与前端交互的启动流程,并深入源码解析多轮 Agent 对话的提示词协议、结构化输出解析与引用管理实现。读完本文,你将能够在本地完整运行一套「输入一个研究主题 → 自动输出带引用的 Markdown 综述论文」的端到端管线,并理解其训练阶段的数据构造与奖励设计原理。

一、MiniCPM4-Survey 是什么

MiniCPM4-Survey 是由 THUNLP、中国人民大学与 ModelBest 联合开发并开源的综述论文生成智能体,构建于 80 亿参数的 MiniCPM4 基座之上。它接收用户的查询(Query)作为输入,通过多轮 Agent 交互自主完成一篇带引用、结构完整、内容可信的长篇综述论文。其核心技术特色集中在四个方面,与 demo/minicpm4/SurveyGeneration 目录中的实现一一对应:

  • Plan-Retrieve-Write 综述生成框架:多智能体生成框架,包含三个核心阶段——规划(定义综述整体结构)、检索(生成合适的检索关键词)、写作(综合检索到的信息生成章节级连贯内容);
  • 高质量数据集构建:收集并处理大量专家撰写的综述论文以构造高质量训练集,同时收集海量研究论文构建检索数据库;
  • 多方面奖励设计:从结构(structure)、内容(content)、引用(citations)三个维度设计奖励函数,用于强化学习训练阶段评估综述质量;
  • 多步强化学习训练策略:提出 Context Manager 在促进高效推理的同时保留关键信息,并构造并行环境(Parallel Environment)维持高效的强化学习训练循环。

从仓库目录结构看,demo/minicpm4/SurveyGeneration/src 下包含三组核心代码:preprocess/(数据预处理与检索库构建)、retriever/(FAISS 检索服务)、generation/(vLLM 推理与多轮状态管理);scripts/提供无前端与带前端两种启动方式;frontend/则是一个基于 Vite + React 的演示界面。

二、准备工作:模型下载与运行环境

2.1 下载模型权重

需要准备两个模型:

  1. MiniCPM4-Survey:生成模型本体,放置在model/MiniCPM4-Survey目录;
  2. MiniCPM-Embedding-Light:官方推荐的 Embedding 模型,用于将查询与论文文本编码为向量,放置在model/MiniCPM-Embedding-Light目录。

需要注意的是,从 src/retriever/retriever.py 与 src/preprocess/build_index.py 的源码可见,Embedding 模型默认以openbmb/MiniCPM-Embedding-Light的远程标识加载,并以flash_attention_2注意力实现、torch.float16精度部署在 CUDA 上,因此需要具备 NVIDIA GPU 环境

2.2 安装依赖

项目依赖清单见 demo/minicpm4/SurveyGeneration/requirements.txt,核心组件包括:

依赖用途
openaiOpenAI 风格 API 调用
vllm高吞吐 LLM 推理引擎(生成模型)
jsonlines逐行读写论文 JSONL 数据
faiss-cpu向量索引(注释中提示可替换为faiss-gpu
fastapi/uvicorn检索服务与推理服务 API 框架
yarlaiohttp 依赖的 URL 解析库

三、检索库构建:从 ArXiv 原始数据到 FAISS 索引

综述生成依赖一个本地论文检索库。官方流程是从 Kaggle 下载 Cornell University 的 ArXiv 论文数据集,然后依次执行数据清洗与索引构建两步。

3.1 下载并解压论文数据

curl -L -o ~/Downloads/arxiv.zip\ https://www.kaggle.com/api/v1/datasets/download/Cornell-University/arxiv unzip ~/Downloads/arxiv.zip -d . mkdir data

解压后会得到arxiv-metadata-oai-snapshot.json这类原始元数据快照文件。

3.2 数据预处理(data_process.py)

执行:

python ./src/preprocess/data_process.py

查看 src/preprocess/data_process.py 的实现,它逐行读取./data/arxiv-metadata-oai-snapshot.json,将每篇论文转换为统一结构并写入./data/arxiv.jsonl

new_item = { 'bibkey': f"arxivid{item['id']}", 'text': f"Title: {item['title']}\nAbstract: {item['abstract']}\nAuthors: {item['authors']}", }

这里的关键设计是bibkey:每篇论文以arxivid+ ArXiv ID 作为全局唯一标识(例如arxivid1234.5678)。后续生成的综述正文中,模型以\cite{arxivid...}的形式引用文献,检索服务也以 bibkey 作为论文主键返回文本,因此 bibkey 是贯穿「检索 → 写作 → 引用渲染」全链路的核心键。

3.3 构建 FAISS 索引(build_index.py)

执行:

mkdir index python ./src/preprocess/build_index.py

src/preprocess/build_index.py 完成以下工作:

  1. 读取./data/arxiv.jsonl,取出全部bibkeytext
  2. 用 MiniCPM-Embedding-Light 的encode_corpus接口对每篇论文文本编码,得到稠密向量(max_length=1024);
  3. 创建内积索引faiss.IndexFlatIP,通过IndexIDMap将整型 ID 与向量绑定;
  4. str_int_ids映射(字符串 bibkey ↔ 整型 ID)写入./index/str_int_ids_abstract.csv
  5. 将索引写入./index/index_abstract.faiss

索引构建全程在 GPU 上完成(faiss.index_cpu_to_all_gpus),最终落盘为 CPU 索引文件供检索服务加载。

四、启动检索服务与模型推理

4.1 启动检索服务(retriever.py)

python ./src/retriever.py

src/retriever/retriever.py 是一个 FastAPI 服务(默认端口 8400),其启动时完成:

  • 加载 MiniCPM-Embedding-Light 到 GPU;
  • 读取./index/index_abstract.faiss分片复制到全部 GPUfaiss.index_cpu_to_all_gpus,开启sharduseFloat16);
  • 加载./data/arxiv.jsonl构建paper_dict(bibkey → 文本)以及index_dict(整型 ID → 字符串 bibkey)。

它对外暴露两个核心接口:

  • POST /search_text_batch):接收模型输出的tool_calls列表与topk,根据工具名分发——search_engine调用检索,finalize直接标记任务结束;
  • POST /queries:批量查询接口(QueryRequest)。

检索路径call_search_engine的实现要点:将工具参数中的 query 列表经model.encode_querymax_length=512)编码,对每个 query 在 FAISS 中取 topk 候选,随后使用RRF(Reciprocal Rank Fusion)融合多路结果——对每个候选按1/(rank+1)累加得分并排序,最终返回前topk篇论文的 bibkey 与完整文本(截断到 8192 token)。返回的每篇论文文本格式为:

bibkey: arxividXXXX.XXXXX Title: ... Abstract: ... Authors: ...

4.2 无前端推理(run.sh)

python ./src/retriever.py # 终端 1:检索服务 bash ./scripts/run.sh # 终端 2:生成服务

查看 scripts/run.sh 的内容,它实际调用:

python ./src/generation/run.py \ --model_path "openbmb/MiniCPM4-Survey" \ --query "Enter your instruction here, example: Please design a survey that assesses the performance of language processing systems on unseen data to measure their robustness in natural language processing tasks." \ --output_file "test.md"

即调用 src/generation/run.py,其命令行参数包括:

参数默认值说明
--model_path必填生成模型路径或 Hugging Face 模型标识
--query必填综述主题指令
--output_file必填输出 Markdown 文件路径
--retriver_urlhttp://localhost:8400检索服务地址
--portNone若指定则以 Web 服务模式启动(供前端调用)

4.3 带前端推理(run_with_frontend.sh)

若希望获得可视化交互界面,执行:

python ./src/retriever.py bash ./scripts/run_with_frontend.sh cd frontend/minicpm4-survey npm install npm run dev

其中 scripts/run_with_frontend.sh 在run.py基础上追加了--port 8001,使生成服务以 FastAPI 模式启动。随后在浏览器访问http://localhost:5173即可使用前端界面(前端为 Vite + React 应用,源码位于 demo/minicpm4/SurveyGeneration/frontend/minicpm4-survey/src)。

前端模式下的实时推送机制:从 run.py 可见,生成服务暴露WebSocket /ws端点,维护active_connections集合;在多轮生成过程中,每完成一步章节更新,就将当前综述的 Markdown、本轮搜索关键词、当前/下一步思考、以及检索论文摘要通过post_to_frontend推送到前端,实现「边生成边展示」的流式体验。前端还可通过POST /generate_survey接口提交查询并触发完整生成流程。

五、Plan-Retrieve-Write 框架源码剖析

5.1 多轮 Agent 循环:rollout_with_env

生成的核心逻辑在 run.py 的rollout_with_env中,其流程为:

  1. vLLM 引擎初始化OriginalvLLMRollout加载模型,采样参数为temperature=0.7, top_p=0.8, repetition_penalty=1.05, top_k=20, max_tokens=2748gpu_memory_utilization=0.95
  2. 状态管理BufferManager_V2为每个查询维护state.current_survey(结构化综述)、trajectory(多轮轨迹)与history_messages
  3. 循环直至 max_turnsbuild_prompt_for_generator构造提示词 → vLLM 生成响应 →parse_generator_response解析结构化输出 → 将 tool_call 发送给检索服务获取反馈 →update_trajectory更新综述状态与轨迹;前两步(step <= 2)检索时topk设为 20,之后使用默认值;
  4. 结束汇总:将轨迹中的current_survey转换为 Markdown 文本并写入--output_file指定的文件。

5.2 Agent 对话协议:提示词与输出格式

系统提示词定义在 src/generation/prompts.py 中。模型每一轮需要按固定格式输出两部分:

(1) Current Update(更新当前综述)

<think> 思考如何根据检索信息完成当前计划 </think> <answer> {"update": "section-1/subsction-1", "content": "段落内容,用\cite{}标注引用"} </answer>

update字段支持titleabstractintroductionsection-1section-1/subsection-1(可到 subsubsection 三级)、conclusion等位置;若认为信息不足可输出{}跳过本轮更新。

(2) Next Plan(下一步行动),通过search_enginefinalize两个工具驱动检索循环:

<think> 下一步需要更新哪部分、需要查询什么信息 </think> <tool_call> {"name": "search_engine", "arguments": {"query": ["keyword-1", "keyword-2"]}} </tool_call>

首轮用户提示词(USER_PROMPT_v0_0424_BUFFER)强制模型先检索;后续轮次(USER_PROMPT_0415_BUFFER)则注入当前综述摘要、上一轮思考与工具调用、以及检索到的论文摘要,驱动模型迭代写作。

5.3 结构化解析与格式校验

src/generation/buffer.py 中的parse_generator_response负责从原始响应中正则提取<think><answer><tool_call>三块内容,并做严格的 JSON 与语义校验:

  • <answer>中的update位置须合法(parse_update_pos解析三级章节路径);
  • update == "plan",则content必须是结构化的规划字典,必须包含abstractintroductionconclusionsectionstitle五个键,每个 section 须含plantitle,并明确禁止章节名为 "Methodology"(处于开发中状态);
  • <tool_call>的工具名只能是search_enginefinalize,且search_enginequery必须是字符串数组;
  • 响应中不允许出现中文字符(通过正则[\u4e00-\u9fa5]检测),否则判定解析失败。

只有同时包含合法answertool_call且无中文时,true才为真;解析失败会在下一轮通过_build_user_prompt_force_correct强制模型修正到第一个未完成章节。

5.4 综述状态更新与规划校验

SurveyManager.update_current_survey(buffer.py)根据update路径将内容写入对应章节:

  • plan:仅在current_survey为空时初始化整个结构;
  • abstract/conclusion:直接写入字符串;
  • introduction:包装为{"content": ...}
  • section-i/section-i/subsection-j/ 三级路径:逐级定位并更新目标章节的content,索引越界返回False

当模型调用finalize时,_check_finalize会逐章节检查是否所有部分都已写入内容;若有未完成章节则强制继续(buffer.py),避免模型过早收尾。

5.5 引用管理与参考文献渲染

模型写作时以\cite{arxivid...}输出引用,run.py 中的json_to_markdown在最终输出阶段完成:

  1. 从轨迹中收集所有论文摘要,提取 bibkey 与标题,构造arxivid → arXiv 链接的映射;
  2. 用正则\\cite\{(.+?)\}扫描全文,将\cite{bibkey1,bibkey2}替换为[1,2]形式的顺序编号;
  3. 在文末追加## References章节,按编号列出每篇引用论文的标题与链接,且自动剔除#1这类占位引用。

match_reference(buffer.py)则负责在轨迹层面统计模型实际引用过的 bibkey 集合(并支持\nocite反向剔除),这是训练阶段计算引用相关奖励(Citation Reward)与 Fact Score 的数据基础。

六、性能评测:可信度与内容质量

原文档给出的综述生成系统对比评测如下(依据 README-en.md 中的性能表,其中 "G2FT" 指 Gemini-2.0-Flash-Thinking,"WTR1-7B" 指 Webthinker-R1-7B):

MethodRelevanceCoverageDepthNoveltyAvg.Fact Score
Naive RAG (driven by G2FT)3.252.953.352.603.0443.68
AutoSurvey (driven by G2FT)3.103.253.153.153.1646.56
Webthinker (driven by WTR1-7B)3.303.002.752.502.89--
Webthinker (driven by QwQ-32B)3.403.303.302.503.13--
OpenAI Deep Research (driven by GPT-4o)3.503.953.553.003.50--
MiniCPM4-Survey3.453.703.853.003.5068.73
w/oRL3.553.353.302.253.1150.24

注:由于 Webthinker 不具备引用功能、OpenAI Deep Research 导出结果时不提供引用,故省略二者的 Fact Score 评估;详细评测信息见官方技术报告。

值得关注的解读维度:

  • Depth(深度)上 MiniCPM4-Survey 得分最高(3.85),Avg 与 OpenAI Deep Research(GPT-4o 驱动)并列 3.50;
  • Fact Score(事实性)达到 68.73,显著高于 Naive RAG 与 AutoSurvey,印证了「规划—检索—写作」框架与引用强化对事实可信度的贡献;
  • 对比w/o RL(去掉强化学习)的一行可以看到:加入多步 RL 后 Coverage、Depth、Novelty、Avg 与 Fact Score 全面上升,直接验证了文档所述「多方面奖励 + 多步 RL 训练策略」的有效性。

七、训练视角:数据集、奖励与多步 RL

虽然仓库未附带训练脚本,但架构图(assets/main.png)与 README 说明了训练阶段的三个关键设计,可在本地复现推理之前先理解其来龙去脉:

  1. 监督微调数据收集:以专家撰写的综述论文与论文库为基础,通过 Citation Match(引文匹配)与 Rule Filter(规则过滤)对齐引用与段落,再由 LLM Rewrite & Synthesize 生成用于 SFT 的「指令—段落」对;
  2. 多方面奖励:奖励函数由结构(structure)、内容(content)、引用(citations)三个维度的子奖励构成,训练阶段的update_all_scores/update_all_format_scores(buffer.py)正是为这种奖励回传预留的接口——前者写最终质量得分,后者写格式得分;
  3. 两阶段强化学习:先做章节级 RL(Section-level RL,对单个章节内容打分),再做综述级 RL(Survey-level RL,对整体结构与质量打分);推理代码中的BufferManager的轨迹数据结构(含scoredonecurrent_surveytrajectory等字段,见 buffer.py)即为强化学习 rollout 数据的标准格式,Context Manager 与并行环境则是保证长程推理信息不丢失与训练吞吐的关键组件。

八、常见问题与调优建议

  • 端口冲突:检索服务默认监听 8400(retriever.py--port参数),生成服务默认以--retriver_url http://localhost:8400连接,改端口时二者需同步修改;
  • GPU 显存:检索服务将 FAISS 索引分片到所有 GPU,生成服务设置gpu_memory_utilization=0.95,二者同时运行时注意显存分配;FAISS 依赖可选用faiss-gpu以获得更好性能;
  • 生成效果调参:采样参数集中在OriginalvLLMRollout.__init__(run.py),可调整max_tokens(默认 2748,控制单轮生成长度)、temperaturetop_p(控制探索程度)以及repetition_penalty(控制重复);
  • 检索质量topk默认 10,前两步为 20,检索结果由 RRF 融合多关键词命中,若综述覆盖度不足可增大 topk 或让模型输出更多关键词;
  • 引用完整性问题:输出时若出现 "Warning: bibkey not found",说明模型中引用了未检索到摘要的文献,可在json_to_markdown前的轨迹中核对检索日志。

九、小结

MiniCPM4-Survey 将「规划—检索—写作」的智能体范式与 8B 量级的端侧模型结合,配合结构化的 Agent 输出协议、严格的解析与校验、以及基于 FAISS + Embedding 的本地检索库,在推理侧只需两个 Python 服务即可端到端产出带引用的长综述。其仓库实现同时保留了完整的 rollout 数据结构与奖励回传接口,使得同一套代码既能驱动推理演示,也能服务于后续的强化学习训练研究。读者可按本文步骤,从 Kaggle 数据出发,依次构建索引、启动检索服务、运行生成脚本,最终在http://localhost:5173(前端模式)或test.md(命令行模式)中获得自己的第一篇自动生成综述。

【免费下载链接】MiniCPMMiniCPM5: SOTA on-device LLMs, small yet powerful.项目地址: https://gitcode.com/GitHub_Trending/mi/MiniCPM

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 18:26:27

如何用 PDFPatcher 无损提取 PDF 图片并自定义输出文件命名掩码?

如何用 PDFPatcher 无损提取 PDF 图片并自定义输出文件命名掩码&#xff1f; 【免费下载链接】PDFPatcher PDF补丁丁——PDF工具箱&#xff0c;可以编辑书签、剪裁旋转页面、解除限制、提取或合并文档&#xff0c;探查文档结构&#xff0c;提取图片、转成图片等等 项目地址: …

作者头像 李华
网站建设 2026/9/15 18:25:46

Matlab频谱与Bode图绘制:从FFT到频响验证的完整指南

简介&#xff1a;面向信号处理、通信工程与控制系统领域的初学者及工程师&#xff0c;提供一套实用的MATLAB频谱分析与Bode图绘制解决方案&#xff0c;专门解决两大高频需求&#xff1a;一是利用pwelch函数完成功率谱密度估计&#xff0c;涵盖数据读取、滤波去噪、窗函数选择与…

作者头像 李华