PaperLab 架构
August 15, 2026 · View on GitHub
PaperLab 是 DeepSeek Harness 的一个论文修改工作流插件生态:一个 Web 工作台(React + FastAPI)+ 一个 dsh bundle 插件(TypeScript)。两者通过「共享项目目录 + 内嵌 HTTP 端点 + 文件结果」解耦。
闭环数据流
┌─────────────────────────────── Web 工作台 (8210) ───────────────────────────────┐
│ │
│ main.tex ──latexmk/pandoc──▶ preview.html(注入 data-pid) │
│ ▲ │ │
│ │ 用户点击段落 → 批注 │
│ │ ▼ │
│ │ annotations.json │
│ │ │ │
│ ┌────┴────────────────────────────┴──────────────────────────────────────┐ │
│ │ FastAPI POST /api/projects/{id}/revisions │ │
│ │ 1. git snapshot(checkpoint 提交) │ │
│ │ 2. 写 .paperlab/revision-request.json │ │
│ │ 3. 调插件 HTTP 端点,失败则 503 │ │
│ └───────────────────────────────────────┬────────────────────────────────┘ │
└──────────────────────────────────────────┼───────────────────────────────────────┘
│ POST http://127.0.0.1:3923/api/revisions
▼
┌────────────────────────────── dsh(DeepSeek Harness)─────────────────────────────┐
│ dsh-paperlab 插件(bundle:cordis.patch.yml → name/inject/apply) │
│ │
│ 1. 内嵌 HTTP server 受理请求,校验项目目录、单飞防重入 │
│ 2. ctx.agentDefaultModel.currentSelection() 取用户配置的模型 │
│ 3. ctx.agents.create({ sessionId, meta.cwd = 项目目录, agentOptions }) │
│ 4. agent.followup(修订 prompt) → agent.whenIdle() → 检查 turn/end 是否报错 │
│ │
│ agent 可见的专用工具(ctx.tools.register + defineTool): │
│ paperlab_read_state 读全部 .tex/.bib + 批注 + 编译状态 │
│ paperlab_apply_edits 唯一匹配的文本编辑(防越界、防工作区文件) │
│ paperlab_compile_check 运行 latexCommand,返回日志尾部 │
│ paperlab_finish_revision git commit + 标记批注已解决 + 写结果文件 │
│ │
│ systemPrompt.section('paperlab-workflow', order=150):注入修订流程与硬性规则 │
└───────────────────────────────────────┬───────────────────────────────────────────┘
│ 写回
▼
.paperlab/revision-result.json(revisionId / diff 基线 / 错误)
│
┌───────────────────────────────────────┴───────────────────────────────────────────┐
│ 前端每 2.5s 轮询 GET /revisions/latest: │
│ done + result → 重新编译预览、批注重锚定、展示 git diff │
└───────────────────────────────────────────────────────────────────────────────────┘
三个关键设计
1. 段落锚定(tex ↔ 预览 ↔ 批注)
- 编译后 HTML 中每个块级元素(
p/h1-h6/li/caption/...)注入稳定data-pid。 - 批注保存
pid + excerpt,不依赖绝对行号。 - 每次重编译后段落重新编号,后端用
difflib.SequenceMatcher按摘录相似度(≥0.55)重新锚定,保证 AI 修改后批注不丢。
2. 插件化执行器(dsh bundle)
- 按官方规范打包:仓库根
package.json的dsh.bundle.patch指向根目录cordis.patch.yml,构建产物提交在根lib/;dsh plugin --profile paperlab add .(或 npm / GitHub 安装)后,dsh --profile paperlab启动。 - 插件是 Cordis 插件(
name/inject/apply(ctx, config)),工具注册随 fiber dispose 自动清理。 - 模型无关:通过
agentDefaultModel.currentSelection()使用用户在 dsh 中配置的任意 provider/model。
3. 以 git 为修订真相源
- 创建项目 / 导入 / 手动编辑 / 编译 / AI 修订都产生提交。
- AI 修订前记录
baseCommit,finish_revision提交后回写headCommit; 工作台 diff 用git diff base head精确展示本轮 AI 改了什么。 - 回退 = 一条
git revert/reset,不需要私有存储格式。
目录与模块
paperlab/
├── server/app/
│ ├── main.py # FastAPI 路由(项目/文件/编译/批注/修订)+ 托管前端
│ ├── project_store.py # projects 目录、git、annotations.json、request/result 文件
│ ├── compile_service.py # latexmk/pandoc/make4ht 降级链 + data-pid 注入 + 重锚定
│ └── dsh_client.py # 调用插件 3923 端点
├── web/src/
│ ├── App.tsx # 状态编排、修订轮询、批注弹窗
│ ├── PreviewPane.tsx # HTML 注入 + 段落点击 + 高亮同步
│ ├── AnnotationSidebar.tsx
│ ├── RevisionPanel.tsx # 触发修订 + 结果显示
│ └── DiffView.tsx # 简单 diff 着色
├── plugin/
│ ├── cordis.patch.yml # bundle 补丁层(insert dsh-paperlab 行 + config)
│ ├── src/index.ts # apply:提示词 section + 工具注册 + HTTP 端点 + agent 生命周期
│ ├── src/tools.ts # 4 个 defineTool
│ ├── src/backend.ts # 文件/git/编译实现
│ ├── src/server.ts # 内嵌 HTTP 服务器
│ └── test/mock-driver.js # 无模型工具单测
└── examples/paper/ # 示例论文模板
安全边界
- 插件只允许编辑项目目录内
.tex/.bib/.sty/.cls/.bst/.bbl,拒绝.git/.paperlab与路径穿越。 paperlab_apply_edits要求find原文唯一匹配,避免歧义误改。- HTTP 端点只绑定
127.0.0.1;项目目录由本机工作台提供,默认单用户场景。 - 每项目同一时刻只允许一轮修订(单飞锁)。
已知限制 / 后续方向
- 预览质量依赖 pandoc/make4ht 对宏包的兼容性;复杂宏包可换用
latexCommand定制。 - 段落重锚定是启发式(文本相似度),大幅改写后个别批注可能落在相邻段落。
- 当前单机单用户;多人协作可把 projects 目录放进共享盘并给后端加锁/鉴权。
- 可扩展:审稿意见 PDF 自动解析成批注、response letter 生成、Codex/Claude Code 适配器。