Phase 4 \u6da6\u8272\u5c42\u4e0e PDF \u6a21\u677f\u4fee\u590d\uff0c\u63a5\u7740\u4e0a\u4e00\u4e2a commit\u3002 polish.py\uff08\u65b0\u589e\uff09\uff1a - \u548c translate.py \u5bf9\u79f0\uff0c\u6309 H2 section \u5207\u5757 \u2192 \u5faa\u73af\u6da6\u8272 \u2192 \u62fc\u63a5 - \u4f7f\u7528 <<<POLISHED>>>/<<<NOTES>>> \u5206\u9694\u7b26 prompt\uff08\u907f\u5f00 Markdown-in-JSON \u95ee\u9898\uff09 - \u65ad\u70b9\u7eed\u4f20\u3001\u6a21\u578b\u81ea\u8bc4\u6ce8\u8bb0\u843d\u76d8 polish_notes.jsonl - \u5728\u53cc\u9776\u70b9 RNAi \u9879\u76ee\u8dd1\u901a\uff1a60 \u5757\u5168\u6210\u529f\uff0c10.7 \u5206\u949f\uff0c$1.20\uff0c\u5b57\u6570 -0.2% report-template.py\uff08\u5927\u6539\u4e00\u6279 P0 bug\uff09\uff1a - \u5b57\u4f53\u6ce8\u518c\u652f\u6301 fonts/ttf/ \u5b50\u76ee\u5f55\uff08\u89e3\u51b3 OTF PostScript outlines \u4e0d\u517c\u5bb9\uff09 - \u5220\u9664 build_disclaimer \u91cd\u590d\u8c03\u7528\uff08\u514d\u8d23\u58f0\u660e\u4ece Markdown \u8bfb\uff0cmanifest \u4e0d\u518d\u91cd\u590d\uff09 - build_body \u81ea\u52a8\u8df3\u8fc7\u6b63\u6587\u9996\u4e2a H1+\u5c01\u9762\u5143\u4fe1\u606f\u6bb5\uff08\u4e0e\u5c01\u9762\u91cd\u590d\uff09 - \u5360\u4f4d\u7b26 \u201c\u76ee\u5f55\u5c06\u5728\u6700\u7ec8\u6e32\u67d3\u65f6\u81ea\u52a8\u751f\u6210\u201d \u2192 \u81ea\u52a8\u751f\u6210 TOC - \u5360\u4f4d\u7b26 \u201c\u5b8c\u6574\u7f16\u53f7\u53c2\u8003\u6587\u732e\u5217\u8868\u2026\u201d \u2192 \u4ece phase2/sources.jsonl \u81ea\u52a8\u751f\u6210 GB/T 7714 \u683c\u5f0f\u5f15\u6587 - src \u4e0a\u6807\u6b63\u5219\u6269\u5c55\uff1a\u652f\u6301 src_A14 / src_B-18 \u7b49\u5b57\u6bcd+\u6570\u5b57\u7ec4\u5408 ID\uff08\u539f\u53ea\u652f\u6301 src_\d+\uff09 - Unicode \u4e0a/\u4e0b\u6807\u8f6c <super>/<sub>\uff1a10\u2076 \u2192 10<super>6</super>\uff08\u601d\u6e90\u5b57\u4f53\u5b50\u96c6\u4e0d\u542b\u4e0a\u6807\u5b57\u5f62\uff0c\u5426\u5219\u6e32\u67d3\u65b9\u6846\uff09 - \u4e2d\u82f1\u6df7\u6392\u81ea\u52a8\u52a0\u7a7a\u683c\uff08CJK \u2194 [A-Za-z0-9] \u8fb9\u754c\uff09 - \u8868\u683c\u6837\u5f0f\u91cd\u505a\uff1atable-header/table-cell/table-cell-center\uff1b\u5782\u76f4\u5c45\u4e2d\uff1b\u77ed cell\uff08\u7eaf\u6570\u5b57/\u77ed\u6807\u7b7e\uff09\u6c34\u5e73\u5c45\u4e2d\uff1b\u957f cell \u81ea\u52a8 CJK \u6362\u884c - TOC \u672b\u5c3e PageBreak\uff08\u76ee\u5f55\u72ec\u5360\u6574\u9875\uff09 \u5df2\u77e5\u672a\u4fee\u590d\uff1a - Maywavee \u662f LLM \u5728 dr-analyst \u9636\u6bb5\u7f16\u9020\uff0c\u6b63\u786e\u4e3a Mabwell\uff08\u8fc8\u5a01\u751f\u7269\uff09\u3002\u4fe1\u6e90\u4fa7 bug\uff0c\u9700\u5728\u540e\u7eed build_glossary.py \u4e2d\u505a\u4e8b\u5b9e\u6838\u67e5\u3002 - \u6b63\u6587 101 \u4e2a src_id\u3001sources.jsonl \u53ea\u670947 \u4e2a\u3001\u4ea4\u96c6 39 \u4e2a\u2014\u2014\u662f v0.4 \u9057\u7559\u7684\u6ce8\u5165 bug\uff0cbuild_references \u73b0\u5728\u4f1a\u5217\u51fa\u7f3a\u5931\u7684 id \u4f9b\u4eba\u5de5\u6838\u5bf9 - \u53cd\u9a73\u8bc1\u636e\u6bb5\u683c\u5f0f\u4e0d\u7edf\u4e00\u662f dr-analyst/skill \u89c4\u8303\u95ee\u9898\uff0c\u4e0b\u4e00\u6279\u6539 skill Co-authored-by: User <human>
Deep Research 系统
生物医药行业的 AI 驱动深度研究流水线。基于 OpenCode 多 agent 协作,以麦肯锡/德勤式方法论产出专业级研究报告(PDF + DOCX)。
当前状态:MVP(路径 2 — 最小可用先行),仅实现 Phase 1 能力。
详见 PLAN.md 了解完整方案与迭代路径。
快速开始
项目在 macOS 与 Debian/Ubuntu 上均通用。Python 包管理用 uv(Rust 写的 Python 包管理器,比 pip 快 10-100 倍,Astral 出品)。
1. 一键初始化(推荐)
bash scripts/setup.sh
这个脚本会自动:
- 检查并安装 uv(没有会交互询问,走官方
curl -LsSf https://astral.sh/uv/install.sh脚本) - 调用
uv sync按pyproject.toml创建.venv/并装所有依赖(ReportLab、matplotlib、biopython 等) - uv 会自动管理 Python 版本(>=3.10),不依赖系统 Python
- 检查并提示缺失的系统二进制(pandoc、opencode)
为什么选 uv 而不是 pip:
- macOS Homebrew Python、Debian 12+ 默认 PEP 668 保护,
pip install到系统会被拒 - uv 把 venv + 版本管理 + 依赖解析一次搞定,不需要手动
python -m venv+source activate+pip install uv sync10-30 秒装完一整个科学计算栈(pip 要 2-5 分钟)- 有
uv.lock锁定精确版本,mac 和 debian 装出来的环境完全一致
2. 安装系统二进制(setup.sh 不装这些)
# macOS
brew install pandoc
curl -fsSL https://opencode.ai/install | bash
# Debian/Ubuntu
sudo apt update && sudo apt install -y pandoc curl
curl -fsSL https://opencode.ai/install | bash
uv 会帮你装 Python 本身,不需要再装
python3-venv/python3-pip。
3. 配置密钥
cp secrets.env.example secrets.env
# 编辑 secrets.env,填入:
# - ZENMUX_API_KEY(必填,格式 sk-ai-v1-xxx)
# - TAVILY_API_KEY / BRAVE_API_KEY / EXA_API_KEY
# - NCBI_API_KEY(可选,PubMed 高频查询时用)
4. 下载中文字体
bash .opencode/templates/fonts/download-fonts.sh
下载思源宋体 + 思源黑体 + 霞鹜文楷(SIL OFL 许可,约 140MB)。
5. 验证 zenmux 端点与 cache(强烈推荐)
source scripts/activate.sh # 一键激活 venv + 加载 secrets
bash scripts/verify-zenmux.sh # 3 步自检
verify-zenmux.sh 会:
- 测 OpenAI 兼容端点(Gemini 3.1 Pro Preview)
- 测 Anthropic 兼容端点(Claude Haiku 4.5)
- 测 Claude prompt cache 两次调用命中(Opus 4.7 cache 读取仅 0.5 USD/M tokens)
若第 3 步 cache_read_input_tokens 始终为 0,参见 AGENTS.md §6.5 诊断步骤。
6. 日常使用
cd ~/Documents/Projects/deep_research
source scripts/activate.sh # 激活 venv + 载入 secrets
opencode # 启动 TUI
退出 venv:deactivate
跑单个 Python 脚本(不用先激活):
uv run python .opencode/templates/report-template.py --input ... --output ...
加新依赖:
uv add <package> # 自动更新 pyproject.toml 和 uv.lock
同步到最新锁定版本(新 clone 或切分支后):
uv sync
如果你用 direnv,可在项目根目录建 .envrc:
source scripts/activate.sh
这样 cd 进项目目录会自动激活,cd 出去会自动卸载。
MVP 可用命令
| 命令 | 功能 | 状态 |
|---|---|---|
/dr-init <主题> |
初始化新研究,启动访谈 | ✅ MVP |
/dr-frame [slug] |
Phase 1:生成 8-15 章研究框架 | ✅ MVP |
/dr-research |
Phase 2:深度研究(并行) | ⏳ 下一阶段 |
/dr-review |
Phase 3:总编审校 | ⏳ 下一阶段 |
/dr-finalize |
Phase 4:成稿 PDF+DOCX | ⏳ 下一阶段 |
/dr-status |
查看进度 | ⏳ 下一阶段 |
典型 MVP 流程
1. /dr-init GLP-1 减重药物市场
→ dr-plan 向你提 6-8 个访谈问题(研究类型、受众、时间范围等)
→ 你回答后,生成 projects/glp1-obesity-market-2026/manifest.json
2. /dr-frame
→ dr-plan 调用 skill:search-strategy
→ 委派 3-4 个 dr-searcher(Haiku,轻量)并行初扫
→ 生成 8-15 章框架到 phase1/framework.md
→ 暂停等你确认
3. 你审核框架,或提修改意见,或直接确认
→ 确认后,manifest.phase1.approved = true
4. (后续)/dr-research 触发 Phase 2 深研 — 目前未实现
项目结构
deep_research/
├── PLAN.md # 完整方案(中断续接从此读起)
├── AGENTS.md # 研究方法论与规则(OpenCode 自动加载)
├── README.md # 本文件
├── secrets.env.example # 密钥模板
├── secrets.env # 你的密钥(gitignore)
│
├── .opencode/
│ ├── opencode.json # MCP 配置 + 权限
│ ├── agents/ # Agent 定义
│ │ ├── dr-plan.md # [MVP] 框架规划师 Opus 0.7
│ │ └── dr-pm.md # [MVP] 项目经理 Sonnet 0.2
│ ├── skills/ # 可复用技能
│ │ ├── search-strategy/ # [MVP] 检索策略总纲
│ │ ├── source-quality/ # [MVP] 信源评级
│ │ ├── length-budget/ # [MVP] 字数预算
│ │ └── pdf-reportlab/ # [MVP] PDF 模板使用
│ ├── commands/
│ │ ├── dr-init.md # [MVP] /dr-init
│ │ └── dr-frame.md # [MVP] /dr-frame
│ └── templates/
│ ├── report-template.py # [MVP] ReportLab PDF 生成器
│ └── fonts/
│ ├── download-fonts.sh
│ └── README.md
│
├── projects/ # 每个研究一个子目录
│ └── <slug>/
│ ├── manifest.json
│ ├── phase1/
│ ├── phase2/
│ ├── phase3/
│ └── phase4/
│
└── archive/ # 完成项目归档
关键设计要点
1. 防止"多 agent 变单模型跑"
OpenCode 的常见陷阱:AI 在主会话里装样子地"委派"子 agent,实际还是主模型在跑。本项目通过 3 道保险避免:
- 命令
subtask: true— 强制走 Task 工具起子会话 - Agent 强绑
model— 每个 subagent 锁死具体模型 permission.task白名单 — 精确限定调用关系
验证方法:TUI 里 <Leader>+Right 切入子会话,能看到真实在跑的模型名。
2. 信源分级(Tier 1-4 + 黑名单)
详见 AGENTS.md §4 与 skills/source-quality/SKILL.md。
- Tier 1:PubMed、顶刊、FDA/NMPA 监管、ClinicalTrials、专利
- Tier 2:权威咨询、系统综述、行业协会
- Tier 3:预印本、券商研报、会议摘要(需 Tier 1-2 支撑)
- Tier 4:通用搜索(仅做发现入口,不做证据)
- 黑名单:自媒体、撤稿论文、软文
3. 字数硬性要求
| 类型 | 最小字数 |
|---|---|
| 综述 | 10,000 |
| 研究 | 30,000 |
| 投资 | 20,000 |
| 管理 | 15,000 |
Phase 1 分配章节配额,Phase 2 自检,不足返工。见 skills/length-budget/SKILL.md。
4. 中文 PDF 无坑
- 字体:思源宋 + 思源黑 + 霞鹜文楷(全 SIL OFL,可商用嵌入)
- 样式:集中在
build_styles(),所有字号行距单点维护 - 引擎:ReportLab(纯 Python,30,000 字 3-5 秒出稿)
- 图表:matplotlib 预渲染 300 DPI PNG 嵌入
5. zenmux 双 provider(Claude cache 关键)
Deep Research 大量使用相同的长 system prompt + skill 内容连续调用 Claude,如果 prompt cache 没生效,Opus/Sonnet 成本会翻 5-10 倍。所以本项目:
- Claude 系列 →
zenmux-anthropic/claude-opus-4.7(走https://zenmux.ai/api/anthropic,@ai-sdk/anthropic原生支持cache_control) - 非 Claude 系列 →
zenmux/google/gemini-3.1-pro-preview等(走https://zenmux.ai/api/v1,隐式缓存自动生效)
Opus 4.7 cache 读取价格 0.5 USD/M tokens(对比输入 25 USD/M,节省 98%)。
验证 cache 是否生效:
- 在 https://zenmux.ai/settings/logs 打开 API Call Logging
- 运行
/dr-frame让 dr-plan 连续调用 2 次 - 第 2 次的
cache_read_input_tokens字段应 > 0 - 若始终为 0,检查 agent 的
model:是否以zenmux-anthropic/开头(详见AGENTS.md§6.5)
已知待办
用户侧
在 zenmux 后台确认模型 slug,更新(已在 v0.2 完成,使用双 provider 架构)AGENTS.md§6 映射表- 填写
secrets.env - 运行
download-fonts.sh下载字体 - 用一个小主题(如"5000 字 PD-1 综述")跑通 MVP 流水线
系统侧(下一阶段)
- dr-chief-editor / dr-searcher / dr-analyst / dr-verifier / dr-polisher / dr-reporter 6 个 subagent
/dr-research/dr-review/dr-finalize/dr-status4 个命令- 生物医药专业信源 skill:PubMed / ClinicalTrials / openFDA / 专利 / 金融
- citation-manager / evidence-table / mckinsey-method / docx-pandoc / report-template 5 个辅助 skill
- Pandoc reference-doc 模板(中文 DOCX)
排错
字体下载失败
# 检查网络访问 GitHub
curl -I https://github.com
# 用镜像手动下载(见 .opencode/templates/fonts/README.md)
MCP Server 启动失败
# 检查 npx 可用
which npx
# 验证 MCP server 可独立运行
npx -y tavily-mcp@latest
subagent 没被真正调度
- 检查 agent frontmatter 的
mode字段是否为subagent - 检查命令 frontmatter 是否有
subtask: true - 检查主 agent 的
permission.task是否允许目标 subagent - 在 TUI 用
<Leader>+Right看是否有独立子会话
ReportLab PDF 中文乱码
# 确认字体已注册(venv 里)
source scripts/activate.sh
ls .opencode/templates/fonts/*.otf | wc -l # 应为 6+
# 手动测试
python .opencode/templates/report-template.py --help
uv 安装后找不到
uv 官方脚本把 uv 装到 ~/.local/bin/。若终端里 which uv 找不到:
export PATH="$HOME/.local/bin:$PATH"
# 永久生效:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc # macOS zsh
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc # debian bash
Python 依赖安装报 externally-managed-environment
不要用系统 pip!改用 uv(本项目标准方案):
bash scripts/setup.sh # uv sync 会自建 .venv 并装依赖
uv sync 很慢 / 下载超时
国内网络下,可用镜像加速:
export UV_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple
# 或
export UV_INDEX_URL=https://mirrors.aliyun.com/pypi/simple
uv sync
每次开终端都要手动 source
用 source scripts/activate.sh 一次搞定。或装 direnv:
# macOS
brew install direnv
# Debian
sudo apt install direnv
# 都装完后在项目根目录
echo 'source scripts/activate.sh' > .envrc
direnv allow
之后 cd 进项目目录就会自动激活,不用再想。
参考链接
- OpenCode 文档:https://opencode.ai/docs
- Agent 配置:https://opencode.ai/docs/agents
- Skill 配置:https://opencode.ai/docs/skills
- MCP Servers:https://opencode.ai/docs/mcp-servers
- ReportLab 文档:https://docs.reportlab.com
- 思源字体:https://github.com/adobe-fonts
- 霞鹜文楷:https://github.com/lxgw/LxgwWenKai
变更记录
- v0.1 (2026-04-20) — MVP 路径 2 完成:dr-plan + dr-pm 两主 agent、4 个核心 skill、2 个命令、ReportLab 模板基础版、字体下载脚本
- v0.2 (2026-04-20) — 双 provider 架构(zenmux-anthropic + zenmux),解决 Claude prompt cache 生效问题
- v0.3 (2026-04-20) — 修正 v0.2 模型名(回到 Opus 4.7 / Sonnet 4.6 / Gemini 3.1 Pro / GPT-5.4 Pro 等真实 slug);改 venv + requirements.txt 跨平台方案(macOS + Debian);新增
scripts/setup.sh、scripts/activate.sh
见 PLAN.md §12 了解完整变更历史。