论文摘要任务的多代理系统(多代理+矢量存储+OCR+MCP)
该存储库实现了构建多代理系统的技术挑战,该系统:
- 接收论文(本地PDF、URL或文本)。
- 将论文分为三个科学领域之一。
- 提取包含字段的JSON 确切地 匹配提示(包括 *错字* 在
artcle). - 用葡萄牙语撰写批判性评论,强调优势、局限性和对有效性的威胁。
该系统由以下部分组成:
- A. 向量存储 ChromaDB中有9篇论文(3个区域×每个区域3个PDF)。
- 一 MCP服务器 暴露对该矢量存储的访问(
search_articles,get_article_content). - A. 多代理管道 在LangGraph(分类器→ 提取器→ 审稿人)。
- 可选的 OCR支持 当PDF没有嵌入文本时,通过文档。
- 自动化测试 用于矢量存储和集成管道。
- Makefile, Dockerfile,以及 docker编写 以简化设置和执行。
______________________________________________________________________
1.高层架构
汇总流程:
- 矢量数据库摄取
- 按以下方式组织的PDF pdf_database// (例如。, economy, med, tech). - 每个PDF都被拆分为 *块* (chunk_size=1000, overlap=200). - 使用生成的嵌入 sentence-transformers/all-MiniLM-L6-v2. - 所有内容都被编入Chroma系列,名为 articles 在...之下 chroma_db/.
- MCP服务器(
src/mcp_server/server.py)
- 从读取配置 configuration/base.yaml. - 打开现有的色度索引。 - 通过MCP显示两个工具: - search_articles(query: str, top_k: int) → 列表 {id, title, area, score}. - get_article_content(article_id: str) → {id, title, area, content}.
- 多代理系统(
src/multi_agent_system)
- 已实施 LangGraph.
- 主要节点:
- 分类器_节点\ 将纸张分类到一个区域。\ 使用:
- 纸质文本(截断为4000个字符)。 - 通过MCP检索上下文(search_articles 带有初始片段)。
- 提取器节点\ 读取论文(带有安全截断),并用模式填充JSON:
{
"what problem does the artcle propose to solve?": "",
"step by step on how to solve it": ["", "", ""],
"conclusion": ""
}钥匙在 相同的 提示,包括 artcle.
- 审阅者_节点\ 使用论文文本中提取的JSON+部分生成葡萄牙语评论(Markdown)。
- 该图为:\ start → classifier → extractor → reviewer → END.
- 用户输入(
scripts/run_agents.py+src/pipeline/pipeline_runner.py)
- 接受: - 本地路径 .pdf, .txt,或 .md. - 指向PDF的URL。 - 将输入标准化并保存到 samples/input_article_N.ext. - 运行多代理管道(run_pipeline). - 生成: - samples/review_N.md 随着审查。 - samples/output_N.json 和 {area, extraction, review_markdown}.
______________________________________________________________________
2.目录结构
概述:
.
├── chroma_db/ # Where the persistent ChromaDB vector index is stored
├── configuration/
│ └── base.yaml # Central configuration file (paths, vector DB, MCP, LLM, etc.)
├── pdf_database/ # Local PDF base used as reference for the vector store
│ ├── economy/ # 3 economy papers
│ ├── med/ # 3 medical papers
│ └── tech/ # 3 technology papers
├── samples/ # Outputs generated when running the pipeline
│ ├── input_article_N.pdf # Normalized inputs (PDF/URL/MD/TXT)
│ ├── output_N.json # Structured output (area + extracted JSON + review)
│ └── review_N.md # Critical review written by the agent
├── src/
│ ├── mcp_server/
│ │ └── server.py # MCP server exposing tools backed by the vector store
│ ├── multi_agent_system/
│ │ ├── classifier_agent.py # Agent that classifies the paper's area
│ │ ├── extractor_agent.py # Agent that generates the JSON required by the challenge
│ │ ├── reviewer_agent.py # Agent that writes the critical review
│ │ ├── graph.py # LangGraph graph connecting the three agents
│ │ └── mcp_vector_client.py # HTTP client that talks to the MCP server
│ ├── pdf_parser/
│ │ └── pdf_parser.py # PDF reader (PyPDF + Docling OCR fallback when needed)
│ ├── pipeline/
│ │ └── pipeline_runner.py # Orchestrates the full execution flow
│ └── vector_database/
│ ├── vector_database.py # Vector store implementation (Chroma + embeddings)
│ └── ingestion_runner.py # Handles ingestion of the 9 PDFs and index creation
├── scripts/
│ ├── database_ingestion.py # Script to rebuild the vector database
│ └── run_agents.py # CLI script to run the pipeline on a paper
├── tests/ # Automated test suite
│ ├── test_vector_database.py
│ └── test_graph_pipeline.py
├── mcp.json # MCP manifest (for external MCP clients)
├── Makefile # Main commands (setup, index, tests, agents, mcp)
├── Dockerfile # Project Docker image
├── docker-compose.yml # Docker Compose orchestration
├── requirements.txt # Python dependencies
└── pytest.ini # Pytest configuration______________________________________________________________________
3.要求
3.1.主要依赖关系
执行旨在运行 Docker容器内部。在主机上,您只需要:
- 码头工人
- Docker Compose
- 环境变量或
.env文件包含:
GROQ_API_KEY=(可选)如果您在配置了GPU和CUDA的计算机上运行,PyTorch和 sentence-transformers 将在容器内自动使用它。
3.2.环境变量
在项目根目录下,创建一个 .env 与:
echo "GROQ_API_KEY=YOUR_TOKEN_HERE" > .envdocker-compose.yml 已配置为加载此 .env 放入容器中。
______________________________________________________________________
4.使用Docker和Docker编写运行
所有依赖项安装、向量索引创建和管道执行都会发生 在…内 集装箱。
4.1.塑造形象
在项目根节点:
docker compose build4.2.输入容器
要打开容器内的外壳,请执行以下操作:
docker compose run --rm summary-app bash你会在 /app 在容器内,代码通过卷安装。
______________________________________________________________________
5.建立病媒库(吸收9篇论文)
仍然 集装箱内,运行:
make index这 index 目标:
- 清洁
chroma_db/文件夹(如果存在)。 - 通过调用来重建完整的向量索引
scripts.database_ingestion.
内部:
- 阅读
configuration/base.yaml. - 解决
pdf_database/和chroma_db/. - 创建一个
VectorDatabase实例包含:
- embedding_model="sentence-transformers/all-MiniLM-L6-v2" - chunk_size=1000 - chunk_overlap=200
- 迭代下的每个子文件夹
pdf_database/:
- 每个PDF都会被读取、文本提取、分块和索引。
- 将嵌入和元数据持久化到Chroma中(存储在
/app/chroma_db,其被安装到主机)。
______________________________________________________________________
6.OCR和PDF文本提取
这 PdfTextExtractor 班级(src/pdf_parser/pdf_parser.py)实施:
- 使用PyPDF进行提取
- 用途 pypdf.PdfReader 和 page.extract_text() 逐页。 - 如果它可以提取文本,则返回该内容。
- 通过Docling进行OCR回退(可选)
- 如果 无文本 与PyPDF一起找到 enable_ocr=True,它尝试OCR。 - 用途 docling.document_converter.DocumentConverter().convert(...). - 呼叫 export_to_text(). - 如果仍然没有文本,它会提高 ValueError.
在管道中,默认情况下启用OCR .pdf 文件夹。
______________________________________________________________________
7.多代理管道(LangGraph)
图表存在于 src/multi_agent_system/graph.py.组件:
- 分类器代理(
classifier_agent.py)
- 通过列出下的子文件夹来发现区域 pdf_database/ (例如。, economy, med, tech). - 将纸张文本截断为 max_article_chars (4000个字符)。 - 使用MCP客户端(MCPVectorStoreClient)拨打电话 search_articles 带有初始片段(mcp_query_chars,800个字符)。 - 从向量存储点击中构建文本上下文。 - 致电Groq LLM: - 在中配置的系统提示 MultiAgentConfig. - 包含截断的纸张文本+类似纸张列表的人工消息。 - 将输出规范化为已知区域(精确匹配、子字符串、同义词如“econ”)。
- 提取剂(
extractor_agent.py)
- 接收 article_text (以及可选 area).
- 将文本截断为 max_article_chars (6000).
- 指示LLM返回 仅 JSON。
- 用途 _extract_json_from_response 支持:
- 原始JSON。 - json ... 用栅栏围起来的街区。
- 用途 _normalize_extraction 以确保:
{
"what problem does the artcle propose to solve?": "string",
"step by step on how to solve it": ["string", "..."],
"conclusion": "string"
}- 审核代理(
reviewer_agent.py)
- 接收 area, extraction,以及 article_text. - 连载 extraction 转换为JSON字符串。 - 将纸张截断为~4000个字符,以提供可选上下文。 - 生成葡萄牙语评论,重点关注: - 新颖性/贡献。 - 方法/实验设计。 - 结果的有效性。 - 对有效性和可重复性的威胁。
- 图表(
graph.py)
- 国家: {"article_text", "area", "extraction", "review"}. - 订单: - start → classifier → extractor → reviewer → END. - 公共职能: - run_pipeline(article_text: str) -> Dict[str, Any].
______________________________________________________________________
8.MCP服务器
在 src/mcp_server/server.py:
- 阅读
configuration/base.yaml:
- 配置 pdf_root, chroma_path. - 配置 embedding_model, collection_name, chunk_size, chunk_overlap. - 配置 mcp.name, mcp.transport.
- 实例化
VectorDatabase使用这些设置。 - 创建一个
FastMCP服务器与json_response=True. - 外露工具:
@mcp.tool()
def search_articles(query: str, top_k: int = 5) -> List[Dict[str, Any]]:
...@mcp.tool()
def get_article_content(article_id: str) -> Dict[str, Any]:
...8.1.MCP清单(mcp.json)
mcp.json 定义:
- 服务器名称、标签、版本和描述。
- 如何通过STDIO启动它:
{
"servers": [
{
"name": "stdio",
"transport": "stdio",
"command": "python",
"args": ["-m", "src.mcp_server.server"],
"env": {
"PYTHONPATH": "."
}
}
],
"tools": [
{ "name": "search_articles", ... },
{ "name": "get_article_content", ... }
]
}外部MCP客户端(如ChatGPT或IDE)使用它来发现如何与容器内的服务器通信。
8.2.内部MCP客户端(MCPVectorStoreClient)
src/multi_agent_system/mcp_vector_client.py:
- 用途
mcp.ClientSession+stdio_client将MCP服务器作为子进程启动:
- 默认命令: python -m src.mcp_server.server 2>/dev/null.
- 公共方法:
- search_articles(query: str, top_k: int). - get_article_content(article_id: str).
换句话说,内部代理无法访问 VectorDatabase 直接;一切都通过MCP工具。
______________________________________________________________________
9.管道执行CLI(使用下面解释的Makefile)
src/pipeline/pipeline_runner.py:
ArticleSampleManager:
- 阅读 samples/output_N.json 以发现下一个索引。 - 将本地文件或下载URL复制到 samples/input_article_N.ext. - 计算路径 review_N.md 和 output_N.json.
ArticlePipelineRunner:
- 解析来源→ 规范输入→ 阅读文本。 - 呼叫 run_pipeline(article_text). - 保存 review_N.md 和 output_N.json. - 返回执行元数据。
______________________________________________________________________
10.自动化测试
10.1.运行测试(容器内)
随着 GROQ_API_KEY 在环境中可用(通过 .env):
make test这 test 目标:
- 重建矢量数据库(
scripts.database_ingestion). - 跑
pytest.
10.2.测试
tests/test_vector_database.py:
- 测试组块, search_articles,以及 get_article_content.
tests/test_graph_pipeline.py:
- 图的端到端集成(run_pipeline)在PDF上。 - 跳过如果 GROQ_API_KEY 未设置。
______________________________________________________________________
11.生成文件
可用的主要目标 集装箱内:
make helpmake index\
清洁 chroma_db/ 文件夹并从中重建完整的矢量索引 pdf_database/.
make test\
重建索引并运行 pytest.
make agent SOURCE=...\
在纸张(本地文件或URL)上运行多代理管道。\ 示例:
make agent SOURCE="samples/input_article_1.pdf"
make agent SOURCE="https://example.com/paper.pdf"make mcp\
在容器内的后台启动MCP服务器,将PID写入 .mcp_server.pid。这仅在您想将外部MCP客户端(如ChatGPT)连接到容器内运行的服务器时有用。
make stop-mcp\
停止通过启动的MCP服务器 make mcp.
______________________________________________________________________
12.Docker和Docker组合
Docker流程概述:
- 塑造形象 (在主机上):
docker compose build- 输入容器 (在主机上):
docker compose run --rm summary-app bash- 集装箱内部 (in
/app):
# 1) Build the vector index in chroma_db/
make index
# 2) Run the pipeline on an example paper
make agent SOURCE="samples/input_article_1.pdf"
# 3) Run tests
make test
# 4) Start MCP server in the background for external clients
make mcp
# ... use it from an external MCP client ...
make stop-mcp这 /app/chroma_db, /app/samples,以及 /app/pdf_database 文件夹作为主机卷装载,因此容器内生成的工件显示在本地项目树中。
______________________________________________________________________
13.快速总结
- 创建
.env使用密钥(在主机上):
echo "GROQ_API_KEY=YOUR_TOKEN_HERE" > .env- 构建Docker镜像(在主机上):
docker compose build- 输入容器:
docker compose run --rm summary-app bash- 在容器内部,构建索引:
make index- 在示例上运行服务器和管道:
make mcp
make agent SOURCE="samples/input_article_1.pdf"- 检查输出(来自主机或容器):
- samples/output_N.json - samples/review_N.md
______________________________________________________________________
14.详细配置(base.yaml)--参数说明
以下是对 每个配置字段的作用 和 为什么选择它 在这个系统内。
mcp block:MCP服务器参数
mcp:
name: "ArticleVectorStore"
transport: "http"
host: "0.0.0.0"
port: 8000
base_url: "http://127.0.0.1:8000"✦ name: "ArticleVectorStore"
MCP服务器的逻辑名称。\ 仅用于外部MCP客户端的识别。\ 我们选择这个名字是因为服务器只公开一个矢量存储的论文。
✦ transport: "http"
定义MCP作为 HTTP服务器,不是STDIO。\ 这允许多代理系统使用正常的HTTP请求与MCP通信——更简单、更可预测、更容易调试。
✦ host: "0.0.0.0"
使服务器监听容器内的所有网络接口。\ 这是必需的,这样即使在单独的进程中运行,多代理系统也可以到达MCP。
✦ port: 8000
项目FastAPI/uvicorn服务器的默认端口。
✦ base_url: "http://127.0.0.1:8000"
MCP客户端使用的URL(MCPVectorStoreClient)发送请求。\ 即使服务器绑定到 0.0.0.0,客户端连接到 127.0.0.1 从容器内。
paths 块:主要路径
paths:
pdf_root: pdf_database
chroma_path: chroma_db✦ pdf_root
包含用于构建矢量存储的9个PDF的目录。\ 我们选择了 / 结构,因为分类器通过列出子文件夹自动发现区域。
✦ chroma_path
ChromaDB保存其持久矢量数据库的目录。\ 保持简单,从项目根开始,通过以下方式简化版本控制和清理 make index.
vector_db 块:向量存储参数
vector_db:
embedding_model: sentence-transformers/all-MiniLM-L6-v2
collection_name: articles
chunk_size: 1000
chunk_overlap: 200✦ embedding_model: all-MiniLM-L6-v2
一种快速、轻便的模型,被广泛推荐用于 语义相似度.\ 动机:
- 比大型型号轻得多
- 强大的嵌入功能,可缩短技术文本
- 低延迟,是多代理管道的理想选择
✦ collection_name: articles
ChromaDB集合名称。\ 我们保持 articles 因为存储的内容完全是科学论文。
✦ chunk_size: 1000
每个PDF被分割成最多1000个字符的块。\ 此尺寸平衡:
- 每个块有足够的上下文
- 矢量搜索的良好粒度
- 更快的嵌入生成
✦ chunk_overlap: 200
块之间有20%的重叠。\ 选择它是为了防止跨块边界的上下文丢失,这对较长的PDF尤为重要。
multi_agent block:LLM代理配置
multi_agent:
llm:
provider: groq
model: openai/gpt-oss-120b
temperature: 0.0✦ provider: groq
我们使用 格罗克 以实现极低的延迟,减少整体管道响应时间。
✦ model: openai/gpt-oss-120b
Groq加速的OSS模型,具有以下强大的平衡:
- 成本
- 速度
- 推理能力
根据经验,它为分类器、提取器和审阅者产生了最一致的结果。
✦ temperature: 0.0
完全确定的行为。\ 关键在于:
- 自动化测试稳定
- 无结构变化的JSON提取
- 分类不会在运行中波动
代理提示
分类器提示
专注于选择 正好一个 这三个领域。\ 它可以访问以下输出 search_articles(),鼓励使用真实的矢量存储上下文。
提取器提示
强制LLM返回 仅 JSON包含:
- 与提示相同的按键
- 严格格式
- 自信的循序渐进的解决方案
这 artcle 拼写错误被保留以遵循官方提示。
审阅者提示
在中生成完整的批判性评论 巴西葡萄牙语,有八个强制性部分。\ 它还引导模型识别纸张何时“超出区域”,与分类器行为相匹配。
主要依赖关系和基本原理
groq
低延迟LLM提供程序→ 减少了管道响应时间。
chromadb
简单高效的矢量存储,直接使用Python API。
句子变换器
语义搜索的高质量嵌入。
pypdf
第一阶段文本提取——快速且无本地依赖。
文档
现代OCR被用作没有嵌入文本的PDF的后备方案。
easyocr
Docling在某些场景中内部使用的互补依赖关系。
兰格拉夫
构建一个确定性和可重复的代理管道。
朗肯码头
Groq司机简化LLM呼叫。
fastapi+uvicorn
MCP服务器通过HTTP的轻量级基础设施。
皮丹提克
对所有MCP请求/响应进行严格验证。
测试
矢量存储和多代理管道的自动化测试。
