Agent设计模式与工程化
输入 (Input Schema)file_path(string, required): PDF 的绝对路径。(bool, default=True): 是否开启光学字符识别(针对扫描件)。(bool, default=True): 是否进行复杂的表格恢复。输出 (Output)content: 经过清理的 Markdown 文本,包含图片占位符。metadata: 包含页数、标题提取、表格坐标
智能论文研究助手:开发文档规划路线图
| 阶段 | 核心主题 | 涵盖内容 |
|---|---|---|
| Phase 1 | 项目全局图谱 (Blueprinting) | 系统使命、核心架构图、技术栈选型理由、LangGraph 状态机逻辑。 |
| Phase 2 | 工程目录结构与核心模块 | 目录树详解、src/core 基础类设计、数据 Schema 定义。 |
| Phase 3 | MCP 协议与特种兵服务 | 跨进程调用逻辑、自定义 MCP Server(Parser, Vision, Arxiv)的实现细节。 |
| Phase 4 | 双层记忆层:RAG 与图谱 | 向量库 (ChromaDB) 检索策略、知识图谱 (Neo4j) 演化逻辑、GraphRAG 搜索。 |
| Phase 5 | 交互界面、部署与运维优化 | Streamlit 仪表盘设计、自动化任务调度、成本与 Token 优化策略。 |
第一阶段:项目全局图谱 (Phase 1: Project Overview & Architecture)
完成最关键的第一部分:定义系统的边界与核心逻辑。
1.1 系统使命 (System Mission)
Smart Scholar Agent 旨在解决学术研究中的“信息过载”与“知识碎片化”问题。它不仅仅是一个阅读器,而是一个端到端的知识生产引擎,能自动将 PDF 转化为结构化知识、视觉洞察、对比表格以及动态演化的知识图谱。
1.2 核心架构设计
系统采用“中心化大脑 + 分布式特种兵”的设计理念。
- 大脑 (The Brain):基于 LangGraph,利用状态机(State Machine)控制论文处理的每一个生命周期。
- 通信协议 (The Nerve):采用 MCP (Model Context Protocol),实现跨语言、跨进程的工具调用(如 Python 调用的专用解析服务)。
- 记忆 (The Memory):结合 RAG (向量检索) 与 Knowledge Graph (知识图谱),实现局部细节与全局脉络的统一。
1.3 核心技术栈 (The Tech Stack)
| 维度 | 技术选型 | 理由 |
|---|---|---|
| 工作流框架 | LangGraph | 支持有状态的多轮迭代,处理循环任务(如递归纠错)极佳。 |
| 通信协议 | Model Context Protocol (MCP) | 标准化 LLM 与外部服务的连接,实现真正意义上的“插件化”。 |
| 文档解析 | Docling (IBM) | 高精度 PDF 布局分析,完美处理表格、公式和多栏布局。 |
| 视觉理解 | GPT-4o Vision / Qwen-VL | 解读论文中的实验曲线图、架构流程图。 |
| 数据库 | ChromaDB (Vector) + Neo4j (Graph) | 实现 GraphRAG 检索,既能找细节,也能看趋势。 |
| 用户界面 | Streamlit | 快速原型开发,原生支持异步 Python 流程展示。 |
1.4 状态机逻辑流 (The LangGraph Logic)
这是未来维护时最需要记忆的“执行蓝图”:
- START ➔
parser_node: 触发 MCP 服务,将 PDF 物理转化为 Raw Markdown。 parser_node➔vision_node: 提取图片 ID,发送给视觉 MCP 进行深度解读。vision_node➔cleaner_node: 图文融合阶段,LLM 将视觉报告嵌入 Markdown。cleaner_node➔analyzer_node: 深度思考阶段,生成单篇论文的深度剖析和思维导图。analyzer_node➔graph_extractor_node: 知识沉淀阶段,提取三元组并写入图数据库。graph_extractor_node➔comparer_node: 集群对比阶段,从 RAG 检索相似论文生成对比表。comparer_node➔generator_node: 产出阶段,生成 PPT 和可视化资产。- END
要用 MCP 而不是简单的函数调用(为了解耦服务);要有 cleaner 节点(为了图文对齐)。
第二阶段:工程目录结构与核心模块
2.1 项目目录骨架 (Project Structure)
采用高度解耦的模块化设计,确保每个“特种兵”服务和“大脑”逻辑互不干扰。
smart-scholar-agent/
├── data/ # 本地存储
│ ├── uploads/ # 待处理的原始 PDF
│ ├── cache/ # 临时解析产物与图片
│ └── db/ # ChromaDB 与 Neo4j 本地数据文件
├── src/ # 核心代码
│ ├── agents/ # LangGraph 核心逻辑
│ │ ├── nodes/ # 所有的状态机节点(parser, vision, cleaner, etc.)
│ │ ├── prompts/ # 结构化的 Prompt 模板库
│ │ ├── state.py # 核心状态定义 AgentState
│ │ └── graph.py # 状态机编排与入口
│ ├── mcp_servers/ # 自定义 MCP 服务集群 (独立进程)
│ │ ├── doc_parser/ # 基于 Docling 的解析服务
│ │ ├── vision_service/ # 视觉理解服务
│ │ └── arxiv_monitor/ # Arxiv 追踪服务
│ ├── core/ # 底层基础设施
│ │ ├── mcp_client.py # 通用 MCP 客户端管理类
│ │ └── llm_factory.py # LLM 实例化工厂
│ ├── schema/ # Pydantic 数据契约 (Data Contracts)
│ │ ├── paper.py # 论文结构化模型
│ │ └── analysis.py # 深度分析结果模型
│ ├── tools/ # 产物生成工具 (PPT, Mermaid, etc.)
│ └── ui/ # Streamlit 仪表盘界面
├── output/ # 生成的 PPT、思维导图等最终产物
├── .env # 环境变量 (API Keys, DB Config)
├── requirements.txt # 依赖清单
└── main.py # CLI 启动入口
2.2 顶层接口与核心协议 (State & Interfaces)
系统的核心纽带是 AgentState,它决定了信息如何在节点间流转。
核心状态定义 (src/agents/state.py)
from typing import TypedDict, List, Dict, Any
class AgentState(TypedDict):
# 输入信息
pdf_path: str # 待处理文件路径/URL
# 中间产物
raw_markdown: str # Parser 提取的原始文本
vision_analysis_results: List[Dict[str, Any]] # 视觉节点分析结果
# 结构化结果
structured_content: Dict[str, Any] # Cleaner 整合后的数据 (符合 PaperStructuredData)
analysis: Dict[str, Any] # Analyzer 生成的深度剖析
comparison_data: Dict[str, Any] # Comparer 生成的横向对比
# 最终产物
artifacts: Dict[str, str] # PPT 路径、Mermaid 代码等
# 运行状态
messages: List[str] # 日志与状态消息
current_step: str # 当前执行阶段
2.3 模块功能映射表 (Feature-to-Method Mapping)
为了方便快速定位功能,我们将主要功能与具体方法进行映射:
| 主要功能 | 对应模块/节点 | 核心方法 | 底层逻辑 |
|---|---|---|---|
| PDF 物理解析 | nodes/parser.py |
paper_parser_node |
调用 MCP Server 的 parse_pdf 工具 |
| 视觉图表提取 | nodes/vision_processor.py |
vision_processor_node |
异步并发调用 Vision MCP 分析图片 |
| 图文数据融合 | nodes/cleaner.py |
paper_cleaner_node |
利用 LLM 按照 Schema 聚合文本与视觉分析 |
| 多维度演化分析 | nodes/analyzer.py |
research_analyzer_node |
运行 CoT 提示词生成深度剖析与 Mermaid |
| 多论文横向对比 | nodes/comparer.py |
comparison_node |
基于 ChromaDB 检索并生成 ComparisonTable |
| 知识图谱沉淀 | nodes/graph_extractor.py |
graph_extractor_node |
提取三元组并写入 Neo4j 数据库 |
2.4 快速启动准备 (Deployment & Requirements)
要让这个项目“跑起来”,需要满足以下配置要求:
1. 算力与环境推荐
- 内存:建议 16GB+ (Docling 解析大型 PDF 较吃内存)。
- 算力:可以不用本地 GPU (除非部署本地大模型),主要依赖 API 响应速度。
- 环境:Python 3.10+ (LangGraph 最佳兼容环境)。
2. 外部服务注册
- LLM API:OpenAI (GPT-4o/4o-mini) 或 Anthropic (Claude 3.5 Sonnet)。
- 存储:ChromaDB:默认本地存储(无需注册)。Neo4j:推荐本地安装 Neo4j Desktop,或者使用 Neo4j Aura 云版。
3. 核心依赖清单 (requirements.txt)
# 核心框架
langgraph>=0.0.10
langchain-openai
langchain-anthropic
pydantic>=2.0.0
# 通信与 MCP
mcp>=0.1.0
httpx
# 解析与视觉
docling
python-pptx
pillow
# 存储与检索
chromadb
neo4j
# UI 界面
streamlit
streamlit-agraph
pyvis
2.5 快速启动步骤
-
克隆项目并安装依赖:
pip install -r requirements.txt -
配置
.env文件:OPENAI_API_KEY=sk-xxxx NEO4J_URI=bolt://localhost:7687 NEO4J_PASSWORD= password -
启动 MCP 服务:(在生产环境由 Client 自动启动,测试环境可手动运行服务脚本确认存活)。
-
运行 UI 界面:
streamlit run src/ui/dashboard.py
涵盖了“怎么看”、“在哪看”和“怎么跑”。它让开发者明白:
- 如果要修改 解析逻辑,去
src/mcp_servers/doc_parser。 - 如果要修改 状态流转,去
src/agents/graph.py。 - 如果要修改 前端展示,去
src/ui/dashboard.py。
MCP 不仅仅是一个插件协议,它是屏蔽底层工具复杂性、为大脑(LLM)提供标准感官的核心层。通过 MCP,将解析、视觉、搜索等重量级任务从逻辑主进程中剥离,实现了真正的分布式协同。
第三阶段:MCP 协议与特种兵服务
3.1 MCP 接口底层:JSON-RPC 2.0 与通信协议
MCP 基于 JSON-RPC 2.0 规范。虽然在开发中使用的是 SDK 封装,但理解其底层数据包结构对于调试至关重要。
1. 通信模式
目前采用 Stdio (标准输入输出) 模式。主进程(Client)通过 stdin 向子进程(Server)发送请求,并从其 stdout 获取响应。
2. 标准 JSON-RPC 交互示例
当大脑想要调用工具时,底层发送的消息如下:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "parse_pdf",
"arguments": { "file_path": "/path/to/paper.pdf" }
}
}
3.2 Parser 服务深度剖析:从 Docling 到结构化输出
doc_parser 是系统的数据入口。它不仅是将 PDF 转为文字,而是要保留“文档结构语义”。
1. 输入输出定义
- 输入 (Input Schema):
file_path(string, required): PDF 的绝对路径。ocr_enabled(bool, default=True): 是否开启光学字符识别(针对扫描件)。table_extraction(bool, default=True): 是否进行复杂的表格恢复。
- 输出 (Output):
content: 经过清理的 Markdown 文本,包含图片占位符。metadata: 包含页数、标题提取、表格坐标等。
2. 底层逻辑实现:Docling 转换器
Docling 会生成一个复杂的文档树,通过自定义 ExportFormat 将其标准化:
# src/mcp_servers/doc_parser/logic.py
from docling.datamodel.base_models import InputFormat
from docling.document_converter import DocumentConverter
def process_docling(file_path, ocr=True):
converter = DocumentConverter(
# 超参数设置:
# - pipeline_options: 调整模型权重
# - ocr_options: 指定语言(如 'ch_sim', 'en')
)
result = converter.convert(file_path)
# 核心转换:提取 Markdown 的同时,记录图片锚点
markdown = result.document.export_to_markdown()
# 提取图片并保存到 cache/images 目录,记录 ID 映射
images = extract_images_to_cache(result)
return markdown, images
num_threads: 设置解析线程数。建议设置为 CPU 核心数的 1 / 2 1/2 1/2。density: 图像渲染密度。如果论文图片公式多,建议调高 DPI(如 300 DPI)。
3.3 稳定性保障:超时、重试与异常处理
PDF 解析(尤其是 50 页以上的论文)是非常耗时的任务。我们需要在 MCPClientManager 中实现健壮的保护机制。
1. 超时控制 (Timeout)
利用 asyncio.wait_for 为每一个工具调用设置分级超时:
- 轻量任务 (如 Arxiv 列表): 10s
- 重量任务 (如 PDF 解析、视觉理解): 180s - 300s
2. 指数退避重试 (Exponential Backoff)
使用 tenacity 库对 MCP 连接失败或 OOM(内存溢出)导致的崩溃进行重试:
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
async def safe_mcp_call(client, tool_name, args):
try:
return await client.call_tool(tool_name, args)
except Exception as e:
# 记录日志,触发重试
raise e
3.4 实战:如何自定义一个“联网查找” MCP 服务
如果需要增加一个功能:“根据当前论文题目,去 Google Scholar 或 Tavily 查找其引用量和相关讨论”。
1. 定义 Service (src/mcp_servers/web_search/)
需要集成一个搜索 API(如 Tavily 或 DuckDuckGo)。
@server.list_tools()
async def handle_list_tools():
return [
types.Tool(
name="search_academic_impact",
description="在互联网上搜索论文的影响力、引用及社区讨论。",
inputSchema={
"type": "object",
"properties": {
"query": {"type": "string"},
},
"required": ["query"]
}
)
]
@server.call_tool()
async def handle_call_tool(name, arguments):
# 实现 Tavily API 调用逻辑
# 返回搜寻到的网页摘要和 URL
results = await web_search_api(arguments["query"])
return [types.TextContent(type="text", text=str(results))]
2. 在大脑中注册与调用
在 src/agents/graph.py 中增加一个节点 search_node,并配置相应的 StdioServerParameters 指向新 Python 脚本。
3.5 Phase 3 核心总结表
| 特性 | 实现细节 |
|---|---|
| 通信协议 | JSON-RPC 2.0 over Stdio |
| Parser 输入 | file_path, ocr_enabled, table_format |
| Parser 输出 | 标准 Markdown + 图片 Metadata 映射 |
| 超时策略 | 异步 IO 监控,核心任务 3 分钟超时阈值 |
| 扩展性 | 遵循 list_tools 和 call_tool 接口即可无缝热插拔 |
不要指望外部工具永远立刻返回结果,必须要有超时和重试机制;同时,它定义了如何优雅地给智能体安装“新假肢”(自定义 MCP)。
第四阶段:双层记忆层:RAG 与图谱
在传统的 RAG 系统中,往往只把文本切块存入向量库,这导致了“只见树木,不见森林”的缺陷。 Smart Scholar Agent 采用**“向量+图谱”**的双螺旋记忆架构:
- 向量记忆 (Vector Memory):负责微观层面的模糊匹配(查找具体的方法描述、实验数据)。
- 图谱记忆 (Graph Memory):负责宏观层面的逻辑关联(梳理技术演化脉络、引用关系、学术派系)。
4.1 向量记忆层:高精度的结构化 RAG
要解决的核心问题是**“上下文污染”(Context Pollution)。如果直接将 PDF 全文切块,参考文献、页眉页脚、致谢等噪声会严重干扰检索精度**。
1. 索引策略 (Indexing Strategy)
利用 Phase 2 中生成的 PaperStructuredData 进行语义分块索引,而不是机械的 Token 切分。
- 技术选型:ChromaDB (本地持久化)
- 数据清洗规则:
- 剔除:参考文献列表 (References)、附录 (Appendix) 中的非核心代码、致谢。
- 保留并加权:摘要 (Abstract)、方法 (Methodology)、实验结论 (Conclusion)。
- 元数据增强 (Metadata Injection): 不仅存储文本,必须将结构化字段作为 Metadata 存入,以便后续进行 SQL 级别的精确过滤。
2. 代码实现规范 (src/rag/indexer.py)
def prepare_chunks(paper: PaperStructuredData):
chunks = []
# 策略:以“章节”为单位进行 Chunking,并附带上下文
for section in paper.sections:
# 跳过低价值章节
if section.title.lower() in ["references", "acknowledgments", "bib"]:
continue
# 构造富含语义的文本块:[标题] + 内容
text_content = f"Paper: {paper.title}\nSection: {section.title}\nContent: {section.content}"
chunks.append({
"id": f"{paper.title}_{section.title}_hash",
"text": text_content,
"metadata": {
"paper_title": paper.title,
"year": paper.year,
"authors": ",".join(paper.authors),
"category": "methodology" if "method" in section.title.lower() else "general"
}
})
return chunks
4.2 图谱记忆层:动态演化的学术知识图谱
KG (Knowledge Graph) 是智能体产生“洞察力”的源泉。它不是静态的,而是随着每次新论文的研读而动态生长。
1. 图谱本体设计 (Ontology Schema)
在 Neo4j 中,严格定义节点 (Node) 和关系 (Relation) 的类型,确保图谱的整洁。
- 节点 (Nodes):
(P:Paper): 论文实体 (属性: Title, Year, Abstract_Embedding)(C:Concept): 技术概念 (如: “Transformer”, “LoRA”)(A:Author): 研究者(M:Metric): 评估指标 (如: “Accuracy”, “F1-Score”)
- 关系 (Relationships):
(:Paper)-[:PROPOSES]->(:Concept): 提出某技术(:Paper)-[:IMPROVES]->(:Paper): 改进了某论文 (演化关键!)(:Paper)-[:EVALUATED_ON]->(:Metric): 在某指标上进行了评估(:Author)-[:WROTE]->(:Paper): 著作关系
2. 自动化入库逻辑 (src/database/graph_writer.py)
使用 Cypher 语句的 MERGE 关键字,确保幂等性(重复运行不会产生重复节点)。
# Cypher 模板:写入演化关系
CYPHER_EVOLUTION = """
MERGE (p1:Paper {title: $current_paper})
MERGE (p2:Paper {title: $baseline_paper})
MERGE (p1)-[r:IMPROVES {
reason: $reason,
magnitude: $improvement_value
}]->(p2)
"""
# Cypher 模板:写入技术概念
CYPHER_CONCEPT = """
MERGE (p:Paper {title: $title})
MERGE (c:Concept {name: $concept_name})
MERGE (p)-[:USES]->(c)
"""
4.3 GraphRAG 融合引擎:双路召回机制
这是“全局搜索”功能的底层实现。将向量搜索结果与图谱遍历结果结合,送给 LLM 进行综合推理。
1. 检索流程 (Retrieval Workflow)
当用户提问:“LoRA 技术在过去一年有哪些变体?”
-
路径 A (Vector): 在 ChromaDB 中检索关键词 “LoRA” 相关的段落,找到具体描述 LoRA 变体的文本块。
-
路径 B (Graph): 在 Neo4j 中执行图遍历:
MATCH (c:Concept {name: 'LoRA'})<-[:USES]-(p:Paper) WHERE p.year >= 2024 RETURN p.title, p.summary -
重排序与合成 (Rerank & Synthesis): 将 A 和 B 的结果拼接,Prompt 提示 LLM:“请结合具体的论文细节 (来自 A) 和宏观的论文列表 (来自 B) 回答问题。”
2. 避免幻觉的“锚点机制”
在生成回答时,强制要求 LLM 标注来源。如果信息来自图谱,标注 [KG: 关系]; 如果来自向量库,标注 [Doc: 论文名].
4.4 Phase 4 开发自检清单
为了确保这部分“内功”修炼到位,开发时请重点检查:
- 去重机制:同一篇论文如果重新上传,ChromaDB 和 Neo4j 是否会覆盖旧数据而不是新增副本?(需在入库前检查 Paper Title 或 Hash)。
- 脏数据清洗:LLM 提取的三元组可能包含噪声(如将 “We” 识别为作者),需要在写入 Neo4j 前增加一层规则过滤器。
- 连接池管理:Neo4j 和 ChromaDB 的客户端连接对象建议设为全局单例 (Singleton),避免频繁握手带来的开销。
第五阶段:交互界面、部署与运维优化
5.1 交互界面层:Streamlit 仪表盘架构
UI 不仅仅是一个网页,它是一个实时响应的战术指挥中心 (Tactical Command Center)。
1. 界面状态管理 (Session State Strategy)
Streamlit 的机制是“每次交互重跑整个脚本”,这对于长耗时的论文分析是致命的。必须利用 st.session_state 建立持久化缓存。
- 核心状态变量:
processing_status: 监控 LangGraph 当前运行到哪个节点。current_paper_data: 存储当前正在分析的论文结构化数据。chat_history: 用于 GraphRAG 全局对话的记录。kg_html: 缓存生成的 Pyvis 图谱 HTML,避免每次刷新页面重绘。
2. 异步流适配 (Async Adapter)
Streamlit 原生是同步的,而我们的后端(LangGraph, MCP)是全异步的。
关键实现模式 (src/ui/utils.py):
import asyncio
import streamlit as st
def run_async_task(async_func, *args):
"""在 Streamlit 中安全运行异步任务的通用包装器"""
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
return loop.run_until_complete(async_func(*args))
3. 页面布局设计
- Sidebar: 控制区。PDF 上传组件、Arxiv 自动追踪开关、API Key 配置。
- Main Area (Tabs):
- Tab 1: Deep Dive: Markdown 渲染器(展示图文融合结果) + Mermaid 组件(展示单篇思维导图)。
- Tab 2: Matrix: 使用
st.dataframe展示对比表格,支持排序和 CSV 导出。 - Tab 3: Galaxy: 使用
st.components.v1.html嵌入交互式知识图谱。
- Floating Chat: 位于底部的折叠式对话框,用于全局 GraphRAG 提问。
5.2 部署架构:容器化与服务编排
为了让这个系统能“无人值守”地运行,我们不能依赖简单的 python main.py,必须上 Docker Compose。
1. 容器编排拓扑 (docker-compose.yml)
需要编排 3 个核心容器:
version: '3.8'
services:
# 1. 核心应用容器 (Streamlit + LangGraph + MCP Clients)
app:
build: .
ports:
- "8501:8501" # Streamlit 端口
volumes:
- ./data:/app/data # 挂载本地数据目录,保证数据持久化
- ./output:/app/output
environment:
- NEO4J_URI=bolt://neo4j:7687
depends_on:
- neo4j
# 2. 图数据库容器
neo4j:
image: neo4j:5.15
ports:
- "7474:7474" # Browser 界面
- "7687:7687" # Bolt 协议
environment:
- NEO4J_AUTH=neo4j/your_password
volumes:
- neo4j_data:/data
# 3. (可选) 向量数据库容器 - 如果不使用 ChromaDB 本地文件模式
# chromadb: ...
volumes:
neo4j_data:
2. 本地数据持久化策略
- Vector DB: ChromaDB 默认使用 SQLite,将数据存放在
./data/db/chroma,挂载到容器内即可,无需独立容器。 - Cache: PDF 下载和图片解析结果存放在
./data/cache,避免重启丢失。
5.3 自动化运维:Arxiv 守夜人
为了实现“自动增长”,我们需要在后台运行一个定时任务调度器。
1. 调度实现 (src/agents/scheduler.py)
使用 APScheduler 库,它比 cron 更适合 Python 应用。
from apscheduler.schedulers.background import BackgroundScheduler
from src.agents.batch_processor import autonomous_growth_task
def start_scheduler():
scheduler = BackgroundScheduler()
# 每天凌晨 2 点执行自动追踪
scheduler.add_job(
autonomous_growth_task,
'cron',
hour=2,
args=[['LLM Agents', 'Knowledge Graphs']] # 关注列表
)
scheduler.start()
注意:在 Streamlit 中启动 Scheduler 需要小心避免重复启动(因为 Streamlit 会在每次刷新时重新加载代码)。建议将 Scheduler 放在独立进程或使用文件锁机制。
5.4 性能优化与成本控制 (Ops Optimization)
作为个人开发者,必须精打细算。
1. Token 成本优化策略
- 分级模型路由 (Model Routing):
- 低成本 (GPT-4o-mini): 用于
cleaner(文本清洗)、graph_extractor(实体提取)。 - 高智能 (GPT-4o / Claude 3.5): 仅用于
analyzer(深度剖析) 和comparer(复杂推理)。
- 低成本 (GPT-4o-mini): 用于
- Hash 缓存: 在调用 LLM 前,计算输入内容的 SHA256。如果库里已经有该 Hash 的分析结果,直接返回,0 Token 消耗。
2. 异常熔断机制
Arxiv 可能会因为请求过快封禁 IP,OpenAI 可能会超时。
- Rate Limiter: 在
Arxiv MonitorMCP 中增加time.sleep(3)。 - Circuit Breaker: 如果连续 3 篇论文解析失败,自动暂停自动化任务并发送邮件/日志报警,防止无限重试烧钱。
构建一个 Smart Scholar Agent 这样复杂的系统,其文档的价值甚至不亚于代码本身。它不仅是“说明书”,更是系统的逻辑拓扑图。以上是基于与AI对话交流进行碰撞整理的结果。是一次学习,也是一次尝试。
项目完结清单 (Definition of Done)
至此,开发文档规划全部完成。在正式封版前,请对照以下清单验收:
- 功能闭环:上传 PDF -> 解析 -> 存入图谱 -> 仪表盘可见 -> 可对话搜索。全链路通畅。
- 数据持久化:重启 Docker 容器后,之前的知识图谱和对比表依然存在。
- 异常处理:上传一个损坏的 PDF,系统应弹出错误提示,而不是直接崩溃退出。
- 成本可控:处理一篇标准论文(10页)的 API 成本应控制在可接受范围(如 < $0.5)。
更多推荐



所有评论(0)