一个面向私有、高质量论文集合的可复现、证据可追溯研究 Agent 工程。
项目重点不是让模型自由拼接论文结论,而是把论文发现、双语混合检索、最小事实编译、 引用验证、跨轮状态恢复和高风险工具审批收敛到可测试的确定性边界。当前已经形成从冻结语料、 图文检索和记忆,到主 Agent 自适应编排、受控执行子图、事实级证据台账、可恢复事件流与 私有研究界面的本地闭环。
- 可信检索与引用:围绕 80 篇、2,286 页英文论文形成 6,252 个检索块和 806 张图表语义,融合中文 BM25 / BGE 与英文科研检索式,经路内和跨语言 RRF、CrossEncoder 重排后生成回答;引用必须命中本轮真实 chunk 白名单。
- 事实级证据编译:多论文比较由代码确定性解析目标与维度,模型只提出受契约约束的最小事实需求;每个“论文 × 维度”网格单元独立检索、编译和提交,失败单元可精确重试,最终答案再由已验证事实确定性渲染,不让答案模型重新改写证据关系。
- 自适应三图编排:跨轮次主 Agent 先恢复上下文,再以保守分类器选择无模型快路或完整规划;清晰的单一论文任务可直接物化,复杂或模糊任务继续走完整规划。固定证据图与动态工具图只执行受控任务,不修改主目标与计划。
- 受控 Agent Runtime:LangGraph ReAct 工作流覆盖规划、工具执行、证据充分性反思、提前终止和有限重规划;18 项扩展研究工具全部受严格 Schema、总时长、调用次数、重复调用和信任等级约束,不注册任意 Shell、Python 或文件系统能力。
- 状态、安全与审批:SQLite Checkpoint 恢复 thread;笔记、报告和长期记忆写入使用与工具名、参数哈希绑定的一次性审批令牌,避免旧确认复用到新参数。
- 并行混合研究:前端提交问题、附件和明确的
rag_mode(disabled/preferred/required);preferred遇到“本地论文 + 外部核验”意图时,确定性建立同组local_rag与dynamic_tools两个只读证据任务并同时启动。两支汇合后由大模型使用自身知识、推理和两类证据综合回答,不创建第三个direct_chat分支,也不会因启用 RAG 或外部检索而关闭模型原有知识。 - 隐私可观测性:可恢复产品事件流按游标持久化阶段、任务、工具、路由和安全原因码,支持刷新续传、历史回放、暂停、继续与取消;事件账本和安全遥测均不记录问题、证据正文或 Provider 原始载荷。
- 本机资源调度:面向 16 逻辑线程的单用户工作站采用单进程共享索引、六路比较检索和有界本地模型线程池;远端模型 I/O 与本地检索分层限流,避免用多 worker 重复加载模型。最近一次全量工程门禁为 999 项测试、171 个子测试全部通过。
- 冻结语料论文级数据契约
- 语料清单校验器
- 全 2286 页确定性结构化解析与元素 ID
- 可追溯语义片段与稳定 chunk ID
- 基线 A:纯向量检索
- 30 条单审阅者银标诊断查询
- 基线 B:BM25 + 向量混合检索
- 基线 C:混合检索 + 重排模型
- 分层、预算受控且可引用的 RAG 上下文组装
- 图片信息契约、806 张图表裁剪与图文混合检索链路
- 806 张图表的视觉模型摘要与图文混合索引重建
- 中文问题到英文科研检索式的双路在线检索编排
- 私人研究模式下的结构化回答生成与严格引用验证
- 24 小时、按 session 隔离的本地短期记忆与多轮追问上下文
- 框架无关的只读论文搜索与证据读取工具
- LangChain 工具适配与受控 LangGraph ReAct 研究工作流
- 可选启用、带 SQLite State Checkpoint 的受控多步研究 Agent Runtime
- 证据充分性反思、提前终止、重复查询防护与有界重新规划
- 不保存问题、查询和证据正文的 Agent 节点、工具、耗时与 Runtime 拦截日志
- 多论文比较最小事实契约、确定性证据投影与逐单元事务式重试
- 精确金标块、同论文替代块和语义事实三级证据血缘归因
- 20 题开发集与 10 题封存集的完整多论文比较端到端评测
- 主 Agent 自适应快路与复杂任务完整规划分流
- 六路并发比较检索、事实级 Compiler 与确定性答案渲染
- 非比较研究的独立检索两步批次与批后评估(默认单步,启用须通过质量门禁;见执行规则)
- 可刷新续传、历史回放和运行控制的持久化事件流
- 可选、默认关闭且受静态准入控制的 MCP 只读工具接入
- 本地 RAG 与外部学术检索的计划级分组、真实并行执行和原子汇合
- 外部学术 Provider 就绪状态、只读双白名单和部分失败降级
详细安排见RAG 检索基线实施计划。
在代码版本 0d32441 上,固定 Top 4 的五题 v2 门禁取得 5/5 成功;15/15 条强制事实全部完成
检索、水化、Compiler 可见、编译、确定性答案输入、表达和正确引用链路,30/30 个请求单元通过,
最终失败单元为 0。五题真实主 Agent 运行中,两题命中确定性快路,三题因复杂或模糊而保守进入
完整规划;快路的主路由加任务物化 p50 约 15 ms,加上下文水化后的主编排前奏 p50 约 63 ms。
这是一组固定五题开发门禁,不能外推为全量生产分布结论;v2 金标也仍待人工双审与仲裁。
较早的 30 题全量快照位于代码版本 66810d5,取得 27/30 成功、0 超时和 99.1% 的已表达事实
引用正确率。最新自适应编排、事实链路、模型裁判方差和回滚边界见
主 Agent 自适应编排与比较规划维度修复复测,
旧全量口径见多论文比较最小证据编译器 v2 评测摘要。
生产启动首先进入跨轮次主 Agent 主体图(paper_research_main_v1),不是先
进入某个执行子图。主图先恢复最近历史、滚动摘要、活动目标、会话任务计划、
远距会话召回与长期记忆,再解释本轮变化、对齐目标和规划任务;长期记忆最多
召回 5 条并受 5,000 字符预算约束,读取失败时降级为空而不阻断请求。只有完成这些
步骤后,才按能力把受控任务派发给普通聊天、本地论文、动态工具、附件问答或
文件编辑执行器。本地论文研究图与动态工具图都是 child executor(子执行器),
不能自行修改主目标、任务计划或会话版本。
当用户同时要求本地论文依据与最新外部核验时,主图将两个任务标记为同一个
parallel_group_id,通过结构化并发同时派发并在批次边界汇合。并行分支只负责获取证据;
大模型仍负责问题理解、规划、概念背景、推论和最终综合。模型自身背景知识不会被伪装成引用,
本地引用只来自本轮通过白名单校验的论文 chunk,时效性结论只有在外部学术分支成功时才标记为
已核验。
浏览器只使用以下统一接口:
POST /paper-research/api/agent/runs:提交带稳定request_id、message、rag_mode和附件 ID 的请求,返回统一 NDJSON 事件流。GET /paper-research/api/agent/runs/{request_id}:断流后查询终态或等待状态。GET /paper-research/api/agent/runs/{request_id}/events?after_event_id=N:从持久化游标 继续读取运行事件;刷新页面不会重新提交原问题或重复执行工具。POST /paper-research/api/agent/runs/{request_id}/approval:批准或拒绝原写任务, 只恢复暂停的 child,不重新解释、对齐目标或规划。POST /paper-research/api/agent/runs/{request_id}/control:请求暂停、继续或取消运行; 浏览器只通过这一显式控制入口改变运行状态。
同一 request_id 重试会返回持久化结果和 run_reused,不会新增 turn 或重复副作用。
旧 /ask、/chat/stream、/tools/run 与 /tools/approval 在 primary 模式只作为
兼容代理保留,浏览器不得调用;legacy 模式则可在紧急回滚时恢复旧实现。
生产命令 scripts/serve_web.py 默认使用 PRA_MAIN_AGENT_MODE=primary。显式配置
PRA_MAIN_AGENT_MODE=legacy 并重启即可回滚;已废弃的
PRA_MAIN_AGENT_ENABLED 只为旧部署读取兼容,不应继续写入新环境文件。
主 Agent 使用 main-agent-stream-v2 事件协议。事件在主图和子执行器运行期间实时发布,
先写入独立的 SQLite 产品事件账本,再通知当前浏览器;慢客户端或网络中断可按同一 run 内
单调递增的 event_id 补齐。浏览器只在本地保存 request_id、conversation_id 和
last_event_id 三个续传字段,不缓存问题、回答事件、工具结果或论文证据。历史会话也从同一
账本恢复,因此实时视图、刷新续传和历史回放使用相同的对话节点。
回答事件会明确标注 delivery mode(交付模式):
provider_live:直接转发模型提供方的实时文本增量。validated_replay:本地 RAG 或结构化回答完成引用验证后再分块输出,不宣称是模型首 token。event_only:本轮只有状态、工具或交互事件,没有回答文本增量。
产品事件只允许公开阶段名、任务标题、工具名、状态、计数、耗时、固定原因码和安全附件 ID。 原始问题、system prompt(系统提示词)、隐藏 chain-of-thought(思维链)、工具参数、Provider 原始载荷、论文正文与召回正文均不会进入事件账本或 DOM;原有安全遥测库继续独立存在,前端 不会直接读取它。
界面把研究过程放回当前对话:思考摘要、计划、工具、检索、回答和本轮统计按稳定节点原位更新, 完成节点默认折叠;“详情”抽屉默认关闭。桌面会话导航可收起,移动端改为遮罩抽屉。附件和 RAG 模式保留在紧凑输入区;等待工具审批时,输入区会切换为“拒绝/允许”,处理后恢复原输入框。 运行中的暂停、继续、取消以及暂停后的计划编辑均按当前状态显示,不再依赖常驻右栏。
原始 PDF、生成索引、运行数据库和密钥不进入 Git。仓库通过环境变量引用本地冻结语料:
Copy-Item .env.example .env
$env:PRA_CORPUS_DIR = 'D:\path\to\research_collection'当前冻结版本:
llm-eval-reliability-v1.0.0-2026-07-26
80 篇论文:核心集 60,挑战集 20
$env:PYTHONPATH = 'src'
python -m unittest discover -s tests -v
python scripts/validate_corpus.py --corpus-dir D:\path\to\research_collection
python scripts/parse_corpus.py --corpus-dir D:\path\to\research_collection
# 以下 BUILD_DIR 替换为本地最新解析产物目录
python scripts/build_chunks.py `
--elements "$env:BUILD_DIR\elements.jsonl" `
--sections "$env:BUILD_DIR\sections.jsonl"
python scripts/build_retrieval_index.py `
--chunks data/processed/chunks/chunks.jsonl
python scripts/search.py "How is hallucination evaluated?" `
--variant C --chunks data/processed/chunks/chunks.jsonl
python scripts/evaluate_retrieval.py `
--chunks data/processed/chunks/chunks.jsonlPDF 解析默认启用 OCR(光学字符识别)降级:普通数字版页面继续使用 pdfplumber,仅当
页面含栅格图像且原生文本少于 24 个字符,或原生页面提取失败时,才渲染该页并调用
Tesseract。OCR 文字会标记为 generated,同时记录引擎、语言模型和版本;扫描页需要 OCR
但运行时不可用时会明确记为失败,不会静默作为空白页进入索引。
先安装摄取依赖和 Tesseract 5,并安装 eng、chi_sim 语言包:
python -m pip install -e ".[ingestion]"
# Windows 示例;也可通过 PRA_TESSERACT_CMD 指向已有 tesseract.exe
winget install --id UB-Mannheim.TesseractOCRLinux 可安装 tesseract-ocr tesseract-ocr-eng tesseract-ocr-chi-sim。相关参数见
.env.example;只有明确不处理扫描件时才将 PRA_OCR_ENABLED 设为 false。
持续知识库更新使用以下命令;它会检查冻结清单,仅解析新增 PDF,将旧产物原样合并到新的
不可变构建,重新生成 chunk 与向量索引,并且只在全部成功后原子切换
data/processed/current_knowledge_base.json。已存在的来源哈希、页面/元素/chunk ID 和父构建
都不会被改写;删除既有来源、为既有来源重分配 corpus_id、或更改解析/OCR 配置都会被拒绝。
新增文件仍须先经过现有冻结清单校验,并在清单中提供未使用的 corpus_id、内容哈希和版权
元数据;更新器不从文件名猜测论文身份,避免破坏可追溯性。
python scripts/update_knowledge_base.py `
--corpus-dir D:\path\to\research_collection
# 持续轮询冻结清单;生产服务在下一次重启时读取已切换的完整构建。
python scripts/update_knowledge_base.py `
--corpus-dir D:\path\to\research_collection `
--watch-interval-seconds 60证据有两层置信度:原生 PDF 文本为 high;OCR 结果为 low。默认检索只使用高置信度
证据;若确需使用 OCR,调用方必须显式设置 include_low_confidence=True,且该层级会随检索
命中、上下文和引用元数据一同保留,供回答策略或人工复核使用。
中文生产查询使用独立的双路入口,不改变原有 A/B/C 基线,也不需要重新分块或生成向量:
$env:DASHSCOPE_API_KEY = '<本机 Key>'
$env:PRA_CORPUS_DIR = 'D:\path\to\research_collection'
python scripts/search.py "哪些方法能降低 RAG 在 TruthfulQA 上的幻觉?" `
--bilingual `
--chunks data/processed/chunks/chunks.jsonl完整问答可以用一条命令串起查询改写、双路检索、上下文组装、回答生成和引用验证:
python scripts/rag.py "哪些方法能降低 RAG 在 TruthfulQA 上的幻觉?" `
--chunks data/processed/chunks/chunks.jsonl `
--corpus-dir "$env:PRA_CORPUS_DIR" `
--output data/runtime/example-answer.json连续追问需要显式复用同一个安全 session_id;不传该参数时仍是完全无状态的单轮问答:
python scripts/rag.py "BEIR 基准包含哪些检索任务?" `
--session-id beir-review-01 `
--chunks data/processed/chunks/chunks.jsonl `
--corpus-dir "$env:PRA_CORPUS_DIR"
python scripts/rag.py "它和 MTEB 有什么区别?" `
--session-id beir-review-01 `
--chunks data/processed/chunks/chunks.jsonl `
--corpus-dir "$env:PRA_CORPUS_DIR"系统里的“记忆/上下文”不是四套同义数据库:最近消息窗口用于保持当前对话连贯, 远距会话召回用于找回较早轮次,下面的短期 RAG 记忆用于 24 小时内的追问改写, 长期记忆则保存经明确意图和审批确认的偏好、项目背景或已确认结论。Conversation Store 中的滚动摘要、目标和任务计划属于主 Agent 工作区状态,也会参与水合,但不是长期记忆。
短期记忆不是整份模型上下文。它只在本地 SQLite 中保存最近问题、通过引用验证的
claims.text、来源 chunk ID 和版权分类;不会保存论文证据正文、旧的 [E1] 标签、完整
回答、模型请求或原始响应。默认 24 小时过期、每个 session 最多 20 轮,每次最多选 6 轮
且不超过 1200 个保守估算 Token。配置见 configs/memory/short-term-v1.json。
Web 研究台另由编排层维护统一的 Conversation Store:普通聊天、本地 RAG、附件、外部学术研究
和动态工具共享同一 conversation ID。每轮无条件准备最近窗口、主题 Episode 与远距用户问题
候选,再由一次结构化 Turn Interpreter 同时判断历史依赖、生成独立问题并规划研究能力;规则
只校验真实 turn ID、会话隔离、能力开关和低置信度澄清。只有独立问题进入中英文论文查询改写。
“自动使用本地论文知识库”表示由来源意图选择本地论文,并可与动态研究组合;“仅依据本地论文回答”
则禁止外部研究。显式模式与“使用/不要使用知识库、联网”等语言要求冲突时,请求在执行前返回
可操作的 422,不会静默覆盖。检查器显示最近窗口、远距候选、采用 turn ID/相关度、能力计划和实际检索路径。
清空会话会同时清除共享账本及其 Episode 索引。
模型上下文是每次调用临时重新组装的快照:可信 system 规则、筛选后的低信任记忆、当前 问题、本轮新检索证据和输出约束。记忆只帮助解析“它、上述方法、前者”等指代,不能充当 事实证据;当前回答仍必须引用本轮重新检索到的论文 chunk。memory-aware 查询的改写缓存和 查询审计明文也被限制为最多 1 天,并在读取或打开数据库时物理清理过期记录。
收到查询后,中文 BM25 + BGE 召回会与 Qwen 英文科研检索式改写并行启动;中英文
各自先做一次路内 RRF,再做跨语言 RRF,最后只使用英文改写查询执行一次英文
Reranker。改写总截止时间默认 2 秒,超时、网络错误、限流或无效 JSON 均返回中文混合
召回结果,不经过英文 Reranker;没有配置 Key 时同样安全降级。配置见
configs/retrieval/bilingual-qwen-v1.json。
改写缓存和查询审计分别保存在 data/runtime/query-rewrite-v2.sqlite3 与
data/runtime/query-audit-v1.sqlite3,不与索引元数据共库。成功改写 90 天内直接命中,
365 天内只在 API 失败时作为过期缓存降级;审计中的中英文查询明文保留 30 天,之后仅
保留查询哈希、模型/提示词版本、各阶段排名、分数和延迟。审计不写证据正文、图注、
figure_json、绝对路径、请求/响应体或密钥。
查询改写请求只包含固定改写提示词和当前用户问题,不上传论文正文、图片摘要或命中证据。
传入 --corpus-dir(或设置 PRA_CORPUS_DIR)后,结果会附带命中论文的
storage_class。双路结果若没有加载版权映射,可以在本地查看排名,但后续上下文组装会
拒绝继续,避免把 internal_research_only 边界默认为可公开。
首版研究工具位于 paper_research_agent.agent。ResearchToolService 提供框架无关的
search_corpus 和 get_evidence:前者只返回排名、稳定 ID、页码、哈希和版权分类,后者
只按显式 chunk ID 从本地不可变语料读取正文。搜索结果会再次经过现有血缘适配器校验;
检索元数据与源 chunk 不一致、版权映射缺失或请求越界时关闭失败。
安装 agent 可选依赖后,build_langchain_tools 将这两个方法包装为固定名称和 Pydantic
参数契约的 LangChain 工具;build_research_graph 通过这些工具执行受控
plan -> reason -> execute_tools -> assess_evidence -> reason/finalize 循环。Planner 最多产生
6 个只读检索子问题;结构化 Evidence Reasoner 可在证据充分时提前结束,或在证据不足时
提出一条新的本地检索,但不能扩展工具白名单。Graph 同时限制每步证据数、总工具调用次数、
重规划次数和重复查询,并按 chunk ID 去重。
ResearchAgentRuntime 负责总超时、session_id -> thread_id 映射,并重新核对终态中的动作
序列、工具计数、重规划计数、终止原因,以及正文、哈希、页码和版权分类。通过后,证据才会进入现有
assemble_context -> answer_context、引用白名单和回答验证器。SQLite Checkpoint 只保存在
data/runtime/,其中可能包含研究 State 和内部证据正文,禁止提交或公开。
python -m pip install -e ".[retrieval,web,agent]"
$env:PRA_RESEARCH_AGENT_ENABLED = 'true'
$env:PRA_RESEARCH_AGENT_MAX_STEPS = '4'
$env:PRA_RESEARCH_AGENT_EVIDENCE_PER_STEP = '3'
$env:PRA_RESEARCH_AGENT_MAX_TOOL_CALLS = '12'
$env:PRA_RESEARCH_AGENT_TIMEOUT_SECONDS = '90'
# 可选:让目录、表格、图片和公式工具读取当前解析产物
$env:PRA_SECTIONS_PATH = 'data/processed/<current-build>/sections.jsonl'
$env:PRA_ELEMENTS_PATH = 'data/processed/<current-build>/elements.jsonl'默认不开启 Agent,原单次 RAG 路径保持不变。完整 Agent 架构由一层主编排图和两条执行子图
组成:主图统一维护跨轮次目标、任务计划和路由;固定证据子图只用
search_corpus / get_evidence 形成可验证引用;动态工具子图才允许模型在固定 18 项扩展工具中
逐步选择。两条执行子图都不是自由工具 Agent;Shell、任意 Python 和任意网络/文件能力均未注册,
写工具必须经过 Runtime 审批。
Agent 启用后,结构化事件默认写入与 State Checkpoint 同目录的
data/runtime/agent-events-v1.sqlite3。每次运行生成独立 run_id,覆盖运行开始/完成/失败、
每个 Graph 节点开始/完成/失败、工具调用开始/完成/失败、总超时、工具白名单/预算拦截和
终态输出拒绝。事件只保存组件名、状态、耗时、数量、预算、错误类型、固定原因码,以及问题、
查询、步骤和 thread 的 SHA-256 指纹;不保存 API Key、问题正文、查询正文、chunk ID、证据
正文、Provider 请求/响应或自由文本异常消息。日志写入采用 best-effort,SQLite 暂时不可写
不会改变研究结果或放宽 fail-closed 安全策略。
可按一次运行查看安全轨迹:
SELECT event_id, event_type, component, name, status, duration_ms, reason_code
FROM agent_events
WHERE run_id = '<run_id>'
ORDER BY event_id;生产 Agent Runtime 现在除核心 search_corpus / get_evidence 外,还注册 18 项严格 Schema
工具。核心可引用证据循环仍用原两工具关闭失败;扩展工具通过
ResearchAgentRuntime.execute_tool 或完整 LangChain registry 调用,结果不会绕过现有引用验证。
- 本地证据:
get_adjacent_chunks、get_paper_metadata、trace_evidence_source、get_paper_outline - 学术网络:
search_scholarly_sources、resolve_paper_identifier、get_citation_graph、check_paper_status - 非文本理解:
extract_table、inspect_figure、extract_equation - 计算核验:
calculate、analyze_experiment_data、verify_claim、check_reproducibility - 成果管理:
save_research_note、export_research_report、manage_long_term_memory
多论文比较不属于动态工具。主路由会把带有多个本地论文 ID 的学术比较交给固定研究图;规划器将
每篇论文与比较维度拆成独立步骤,search_corpus 用对应 corpus_id 同时约束 BM25 和向量召回。
证据编译模型只返回最小事实、片段 ID、事实需求 ID 和限定词;本地代码再校验论文范围、事实需求、
必要限定词和覆盖状态,确定性生成事实 ID 与最终台账。单元失败时只重试失败 requirement,已提交
单元继续保留;连续编译失败以独立 compiler_failed 状态终止,不回退为空台账或证据不足。
最终回答上下文不再携带原始证据正文,而是按计划 requirement 顺序投影经过验证的事实台账与引用。
当前编译器可见性严格隔离不同论文,但同一论文内的证据仍可被该论文的多个维度复用;这是后续按
缺失事实自适应水化并收紧到同维度范围的明确优化项。普通单篇问答仍保持原有全局检索 rank 顺序。
升级前若有尚未完成、下一步仍指向 compare_papers 的动态 Graph checkpoint,应新建任务重新执行;
该旧工具名已从严格目录移除,恢复时会按未知工具关闭失败。
工具目录为每项能力固定风险级别、默认超时和最大结果数。本地读取直接执行;学术网络只向
Crossref、arXiv 或 Semantic Scholar 发送当前检索式/论文标识符,不发送本地 chunk 或论文正文;
计算器只解释算术 AST,实验分析只支持最多 1000 行、20 列和固定统计白名单。
长期记忆会在主 Agent 解释本轮请求前由现有 manage_long_term_memory(search) 只读召回,
解释器只能从实际召回 ID 中选择。被选中的记忆可进入普通聊天、本地 RAG 或动态工具三条
执行路径;本地 RAG 将其装配为独立的低信任 JSON 层,记忆 ID 永远不会进入 citation(引用)
集合,confirmed_conclusion 仍须由本轮论文证据重新核验。水合观测只记录各阶段耗时、数量、
最终字符数和保守 Token 估算,不记录问题、记忆正文、记忆 ID 或 Provider 原始载荷。
长期记忆新增、更新、删除必须使用与工具名、参数哈希绑定的 5 分钟一次性审批令牌;搜索和
列举是只读操作,无需审批。记录按作用域隔离,支持内容去重、版本替代、软删除和可选过期;
所有文件和 SQLite 只写入 data/runtime/,默认拒绝路径逃逸与静默覆盖。
动态工具 Graph 会先执行只读记忆召回,再进入
recall_memory -> route -> execute -> route/propose_memory/finalize;记忆写入路径为
propose_memory -> execute(仅生成请求) -> interrupt -> 用户批准/拒绝 -> execute/finalize。只有
用户明确表达“记住、更新记忆、忘记”等意图时才会生成结构化候选,普通问答不会自动写入。
模型只负责
返回结构化 ToolDecision,Runtime 再校验工具名、参数 Schema、风险策略、超时、重复调用和
初始计划、重复调用、连续无新证据、工具次数与总时长预算。观察结果额外标注四类信任等级:citation_evidence、research_context、
computed_result、side_effect,长期记忆始终属于低信任 research_context,只有第一类可作为
论文事实的引用候选;确认结论还必须绑定当前语料中真实存在的不可变 chunk ID。
Owner Web API 提供 POST /paper-research/api/tools/run 与
POST /paper-research/api/tools/approval。两者都要求登录 Cookie 和允许的 Origin;待审批响应
只返回工具名、用途、参数 SHA-256 与过期时间,不返回完整参数、正文、一次性令牌或内部审批 ID。
登录后的 GET /paper-research/api/memories 只投影当前有效记录的内容、类型、来源 ID、版本和
生命周期字段;页面可查看记忆,修改和删除仍需通过动态工具审批。
路由冒烟基线位于 evaluation/datasets/tool-routing-v1.jsonl,覆盖本地读取、网络读取、受限计算
和三类写入审批场景。
result = await runtime.execute_tool("calculate", {"expression": "(2 + 3) * 4"})
pending = await runtime.execute_tool(
"save_research_note",
{"title": "结论", "content": "已确认的研究结论"},
)
token = runtime.approve_tool_request(pending.summary["approval_request_id"])
saved = await runtime.execute_tool(
"save_research_note",
{"title": "结论", "content": "已确认的研究结论", "approval_token": token},
)图片语义入库分为三个阶段。裁剪阶段不调用视觉模型,也不会上传图片:
python scripts/crop_figures.py `
--elements "$env:BUILD_DIR\elements.jsonl" `
--corpus-dir "$env:PRA_CORPUS_DIR" `
--output data/processed/figure-semantics-v1视觉摘要支持百炼实时 API 和 z-ai 命令行。百炼接入使用创建 API Key 时一并显示的
业务空间专属 API Host;密钥只通过环境变量读取,不能写入命令、日志或仓库:
$env:DASHSCOPE_API_KEY = '<本机新建或重置后的 Key>'
$env:DASHSCOPE_BASE_URL = 'https://dashscope.aliyuncs.com/compatible-mode/v1'
python scripts/summarize_figures.py `
--provider dashscope `
--candidates data/processed/figure-semantics-v1/figure_candidates.jsonl `
--model-id qwen3.7-plus `
--model-id qwen3.7-plus-2026-05-26 `
--workers 4多个 --model-id 按顺序使用。仅当平台明确返回
AllocationQuota.FreeTierOnly 时才切换下一个模型;普通网络错误、限流和无效 JSON
会在当前模型重试。若允许免费额度用尽后按量付费,应在百炼控制台关闭“免费额度用完
即停”,平台会自动按“免费额度 → 资源包 → 节省计划 → 按量付费”扣减,此时通常无需
配置第二个模型。命令结束会输出各模型的实际输入、输出和总 Token;每成功一张即原子
更新 figures.jsonl,重跑可断点续传。--workers 4 会并发处理 4 张图片;若限流频繁,
可改为 --workers 2,程序会遵循 Retry-After 并指数退避。
未配置 DASHSCOPE_BASE_URL 时默认使用上面的北京共享端点;若能从控制台取得业务空间
专属 API Host,仍优先使用专属端点。JSON 模式默认不设置输出 Token 硬上限,避免在
JSON 对象中途截断;摘要长度由提示词约束。
也可以使用原有 z-ai 命令行;model-id 必须填写实际视觉模型及版本,不能用占位名称:
python scripts/summarize_figures.py `
--provider zai-cli `
--candidates data/processed/figure-semantics-v1/figure_candidates.jsonl `
--model-id "<实际视觉模型及版本>"生成 figures.jsonl 后,将图片摘要作为“一图一块”合并进文本块,再重建本地索引:
python scripts/build_chunks.py `
--elements "$env:BUILD_DIR\elements.jsonl" `
--sections "$env:BUILD_DIR\sections.jsonl" `
--figures data/processed/figure-semantics-v1/figures.jsonl
python scripts/build_retrieval_index.py `
--chunks data/processed/chunks/chunks.jsonl图片向量文本只包含图名、图片类型、原始图注、视觉摘要和关键发现。坐标、相对路径、 置信度、模型与提示词版本作为检索元数据保存,不参与语义相似度计算。当前实际状态和 全量审计结果见图片语义入库状态。
检索运行结果可以在调用大模型前组装为安全的上下文预览:
python scripts/assemble_context.py `
--run data/evaluations/example-retrieval-run.json `
--chunks data/processed/chunks/chunks.jsonl `
--token-budget 8192 --output-reserve 1200 `
--output data/runtime/example-context.json组装顺序固定为可信系统规则、必要对话历史、低信任短期记忆、低信任长期记忆、当前用户问题与 任务状态、检索证据。历史、记忆、任务状态和论文正文均属于低信任数据;记忆与证据分别使用 canonical JSON 封装,不能覆盖系统规则或触发工具。预算计算覆盖最终消息模板并预留输出 空间;如果空间冲突,先丢弃最旧记忆,至少保护可容纳的最高排名新证据。
scripts/answer.py 是调试生成边界的低层入口;它可以把已经组装好的上下文送入私人研究
回答模块:
python scripts/answer.py `
--context data/runtime/example-context.json `
--output data/runtime/example-answer.json回答模型固定为 qwen3.7-plus-2026-05-26,使用 temperature=0.1、top_p=0.7、
max_tokens=1200 并关闭思考。模型只返回结构化 claims + citation_ids;本地验证器依据
AssembledContext.citations 白名单校验引用并追加 [E1] 标记,未知引用、截断输出或非法
JSON 均关闭失败。没有可用证据时在本地直接返回“证据不足”,不调用 API。
private_research 是当前唯一回答输出模式。它允许将已经加载版权分类的少量命中片段发送
给百炼,但不会上传整篇 PDF,也不会把上下文、证据正文、模型原始响应或答案正文写入审计
库。data/runtime/answer-audit-v1.sqlite3 只保存模型、Token、延迟、引用/chunk ID、版权分类
和答案哈希。最终回答 JSON 只包含中文答案、结构化 claims、最小引用元数据和调用统计;不
提供公开导出模式。v1 审计只记录已验证回答和本地证据不足结果;Provider 超时、非法 JSON
或引用校验失败不会写库,也不会伪装成“证据不足”。
paper_research_agent.web 将现有 RAG 包装为常驻 FastAPI 服务:启动时只加载一次
6,252 个 chunks、BM25、FAISS、BGE 和 Reranker,后续问题复用同一运行时。本机只运行
一个 Uvicorn worker(工作进程),让所有请求共享索引和模型;同一会话的问答保持串行,
不同会话默认最多并发两个完整问答,容量由 PRA_WEB_MAX_INFLIGHT_RUNS(范围 1–16)控制。
容量耗尽时新请求快速返回繁忙响应,不建立无界队列;设为 1 可回退为全局串行。
论文比较的单次检索阶段最多并发六路。服务只监听 127.0.0.1:8092,不依赖 Nginx 或公网域名。
前端会话历史采用按需加载:登录后先返回最多 50 个会话的标题和更新时间,不携带历史消息;
随后只为当前会话加载最近 24 条消息。存在更早内容时由“加载更早消息”每次追加 24 条,避免
首屏一次解析全部会话、回答和 Agent 结果。这里优化的是界面历史记录的传输与渲染,不是主
Agent 的上下文水合(Context Hydration)。scripts/smoke_web_runtime.py --summary-only 可执行
不输出回答正文的真实运行时冒烟,并分别记录冷启动、请求和总耗时。
因为完整索引包含 30 篇 internal_research_only 论文,首页项目卡可以公开,但真实问答、
引用摘录、英文改写、短期记忆和上下文检查器全部要求站长登录。登录后由服务端生成不可猜测
的 conversation ID,并通过 HttpOnly + SameSite=Strict 签名 Cookie 绑定;本机 HTTP
运行时关闭 Secure,如果将来改为 HTTPS 再重新启用。浏览器不能自选 session ID,也不会
保存站长密码。POST 请求还会校验精确同源 Origin。
安装 Web 依赖后,以环境变量提供私有路径与凭据并启动:
python -m pip install -e ".[retrieval,web]"
$env:PRA_MAIN_AGENT_MODE = 'primary'
python scripts/serve_web.py --host 127.0.0.1 --port 8092启动日志必须显示 主 Agent Web 启动模式:primary。若统一入口在本机调试时出现数据撕裂、
重复副作用、引用丢失或持续提交拒绝,可切到兼容模式并重启同一服务:
$env:PRA_MAIN_AGENT_MODE = 'legacy'
python scripts/serve_web.py --host 127.0.0.1 --port 8092切换兼容模式不会删除主 Agent checkpoint、Conversation Store(会话存储)或事件库,也不要
手工修改本机 SQLite 状态。问题修复后复用原数据验证,再显式切回 primary。
混合并行研究还有独立的严格回滚开关。它默认开启且只接受大小写不敏感的 true / false;
1、yes、空白值或其他字符串都会令启动失败。需要回滚时设为 false,混合请求会在两个子执行器启动前以
parallel_hybrid_disabled 关闭失败,不会退回顺序执行或静默二选一;纯单任务不受影响。
$env:PRA_PARALLEL_HYBRID_RESEARCH_ENABLED = 'false'
python scripts/serve_web.py --host 127.0.0.1 --port 8092本机登录使用 .env 中的 PRA_WEB_USER、PRA_WEB_PASSWORD,并单独设置至少 32 字节的
PRA_WEB_SESSION_SECRET。这些变量、DashScope Key、论文派生数据、模型缓存与运行数据库
均不得进入 Git。
研究台返回安全字段白名单:中文回答与 claims、引用编号、论文标题、官方链接、页码、版权
分类、短摘录,以及改写状态、入选证据/记忆数量和 Token 预算。它不会返回 PDF 路径、图片
路径、完整 figure JSON、系统提示词、Provider 原始响应或未选中证据全文。部署模板见
deploy/,推荐问题见 configs/web/recommended-questions-v1.json。
search_scholarly_sources、resolve_paper_identifier、get_citation_graph 和
check_paper_status 保持稳定的公开工具契约,内部通过有序 Provider(提供方)注册表执行。
默认模式为 offline:不创建 HTTP 客户端、不读取论文 API Key,四个工具统一返回
provider_not_configured,不会用测试假数据冒充真实论文。
$env:PRA_SCHOLARLY_MODE = 'offline'
python scripts/serve_web.py单元测试通过依赖注入使用确定性 Fixture Provider(测试假提供方),可覆盖成功、无结果、
限流、超时和多提供方降级;该实现只存在于测试代码,不能进入生产 Registry(注册表)。
真实接入必须显式设置 PRA_SCHOLARLY_MODE=live。无 Key 时使用免申请的 Crossref 和 arXiv;
配置 SEMANTIC_SCHOLAR_API_KEY 时优先使用既有 Semantic Scholar,失败后再尝试免 Key 来源。
工具参数可选 source=auto|crossref|arxiv|semantic_scholar,默认 auto 返回第一个成功来源;
明确选择来源时不跨库降级。OpenAlex 未接入。
$env:PRA_SCHOLARLY_MODE = 'live'
$env:PRA_PARALLEL_HYBRID_RESEARCH_ENABLED = 'true'
python scripts/serve_web.py --host 127.0.0.1 --port 8092在页面问答中可以输入“在 arXiv 检索 attention transformer 相关论文,列出标题与链接”或 “通过 Crossref 解析 DOI 10.1038/nature14539”。入口沿用当前 Agent 问答,无需新按钮。 标题解析只给出候选;Crossref 摘要可能缺失,参考文献仅反映已登记数据,不支持完整反向引用图。 出版更新核查只返回登记的更新元数据,不能保证论文未撤稿。arXiv 只支持搜索和 ID 解析, 年份筛选采用投稿日期。PDF 链接只作为书目信息返回,不自动下载或入库。
每个提供方使用有界内存缓存(5 分钟、最多 128 项、总响应不超过 8 MB),重启即清空;
Crossref 请求至少间隔 1 秒,arXiv 至少 3 秒。并发相同请求合并为一次 HTTP 请求,
限流后短期暂停该提供方,不自动重试。每次 HTTP 请求超时为 10 秒,响应上限 2 MB;
固定官方 HTTPS 地址,不跟随重定向,也不继承系统代理环境变量。
可以运行 python scripts/smoke_public_scholarly.py 做公开书目联网验收,输出仅含状态、数量与耗时。
回答下方的“外部学术 API 来源”卡片由后台工具实际返回结果生成,显示 Crossref/arXiv/ Semantic Scholar、实时 API 查询或缓存命中、查询时间、返回数量、公开标识符和官方链接。 卡片随会话历史恢复,刷新不重新查询;旧回答没有来源记录时不会伪造卡片。 只保存有界书目投影,不保存检索参数、摘要或原始响应。卡片说明工具返回了哪些书目, 不等同于本地全文事实验证,也不保证回答中的每句话都已被外部文献支持。
意图判定沿用现有解释模型,输出普通解释、本地、外部或混合信息需求;例如“给我几篇 RAG 的代表文献和链接”无需使用“联网”口令,也能进入学术检索。明确的问候与概念解释保留快捷 路径,其余请求进入现有语义规划。高置信纯外部需求只查外部书目,混合需求才同时启动本地与 外部分支;数据库偏好传递给工具路由。模型不能越过禁止联网、required 模式、只读白名单、 审批或引用校验。模型失败/低置信度采用既有降级,不新增独立分类模型或自动下载权限。
这里的“外部”是受控学术元数据与引用关系检索,不是通用网页搜索。并行学术分支同时受
network_read 风险白名单和四个固定工具名白名单约束,不能调用写工具、本地文件工具、计算
工具或任意 MCP 网络工具;越权请求在 Provider 调用前拒绝,也不会创建审批。
所有学术网络结果仍是低信任 research_context,不能直接成为论文引用;外部论文必须经过
许可核验、受控导入、冻结、解析和本地索引后,才能进入 citation_evidence 证据链。
Provider 离线、超时或请求失败时,本地分支和大模型综合仍可继续,结果会标记为降级并明确说明
“外部学术核验未完成”;两类证据都失败时仅返回无引用的模型背景说明,并标记
model_background_only,不会把时效性事实表述为已核验。
MCP(Model Context Protocol,模型上下文协议)只作为现有 Dynamic Tools 子图的工具 provider(提供方),不新增子图,也不进入固定 Local RAG 证据闭环。默认安装和默认运行均 关闭 MCP;安装可选依赖后,由管理员静态配置文件决定准入的 Server 与工具:
python -m pip install -e ".[agent,mcp]"
$env:PRA_MCP_ENABLED = 'true'
$env:PRA_MCP_CONFIG_PATH = 'D:\secure-config\mcp-servers.json'
python scripts/serve_web.py示例见 deploy/mcp-servers.example.json。示例不含真实路径或密钥;生产配置必须把 Zotero
命令指向本项目固定 Python 环境,把 GitHub 命令指向已审查且固定版本的官方二进制。
GitHub PAT 只通过 GITHUB_PERSONAL_ACCESS_TOKEN 继承,禁止写入 JSON、日志或 Git。
所有 MCP 结果都是低信任 research_context,不能直接成为论文引用。Server 离线时应用
继续启动,相关工具不进入当次不可变 Registry snapshot(注册快照);安全事件只记录
Server ID、ready/degraded、工具数和 reason code。紧急关闭无需迁移或删除状态:
$env:PRA_MCP_ENABLED = 'false'
python scripts/serve_web.py完整安装、升级审查、隐私、监控与回滚步骤见 MCP 工具接入与运维。
论文研究回答可使用固定版本 ragas==0.4.3 评估入选上下文精确率/召回率、回答忠实度、
回答相关性和逐 claim 引用忠实度。评分会按 chunk_id 水化实际入选的完整证据块,并仅在内存中处理真实问题、回答和证据正文;结果文件只保存
案例 ID、数字分数、耗时和安全异常类型。安装、准备检查、小规模冒烟和裁判校准步骤见
Ragas 论文研究 Agent 评测运行手册。
主 Agent 支持暂停、继续、取消、跳过步骤、调整目标和任务顺序、只重试失败步骤,以及单任务时间、调用次数和费用预算。所有编辑都保留已完成步骤及其产物;完整状态机、API 和恢复不变量见 可中断可编辑计划执行。
- 每个结论最终绑定
paper_id / element_id / page / evidence_span。 - 所有实验记录语料、解析器、chunk、embedding 和检索配置版本。
- 先评测检索,再引入生成与 Agent。
- 索引可重建,数据导入幂等。
- 受限论文只用于本地研究,不能由仓库重新分发。
- 冻结清单中的选题理由、挑战提示和问题创意不得进入索引。
全量文本解析已覆盖 2286/2286 页,并通过跨记录完整性审计和 14 篇、42 页
视觉抽检。806 个图注对应区域已裁剪并由 qwen3.7-plus 生成结构化视觉摘要;当前统一
索引包含 5,446 个正文块和 806 个图片语义块,共 6,252 个 384 维向量。图片采用“视觉
模型转语义文本,再由文本 Embedding 入库”的方案,并非直接对图片像素生成向量。
基础检索评测仍包含开发期单审阅者银标集;论文级候选发现已经补充人工金标基线,多论文比较则 使用 20 题开发集和 10 题封存集执行完整生产链路评测。当前端到端样本仍只有 30 题,生成模型与 模型 Judge(裁判)同源,也尚未进行多次随机重复和第二审阅者盲审,因此这些结果用于内部归因和 版本比较,不应外推为跨语料、跨领域的泛化能力。 模型、正文、片段和索引只保存在本地忽略目录,发布要求见 检索基线发布门禁。