Back to home

Wechsels

dsh-zotero-wiki

DeepSeekHarness × Zotero 插件:自动同步文献库,MinerU 解析 PDF,DeepSeek 全文阅读生成结构化笔记,编译成可检索的 Obsidian LLM Wiki。

Stars
2
Language
TypeScript
Created
Aug 14, 2026
Updated
Aug 15, 2026

Introduction

dsh-zotero-wiki

中文 | English

DeepSeekHarness(dsh)× Zotero 插件:自动同步 Zotero 文献库,用 MinerU 解析 PDF、用 DeepSeek 阅读全文,把文献编译成可检索的 Obsidian Wiki,并让 Agent 在回答时附带可追溯的文献引用。


项目定位(范围)

是什么:一个 Node/Cordis 风格的 dsh 插件 + 独立 CLI。它把你的 Zotero 文献库变成一座持续更新的 Obsidian 知识库,并暴露原生工具供 Agent 检索。

完整链路

Zotero(本地库 / Web API)
  └─ sync:增量同步元数据 → .zotero-sync/sync.db(SQLite 状态库)
      └─ parse:MinerU 官方平台解析 PDF → raw/ 源文件 + DeepSeek 全文笔记 → wiki/ 单篇页
          └─ compile:主题综述、索引、交叉链接、归档标记
              └─ query:Agent 通过 query_zotero_wiki 检索,回答附 [Zotero key, §章节] 引用

明确不做(保持轻量):向量数据库、自动聚类、多用户服务端、定时后台服务、Web UI、Zotero 注释(高亮/批注)同步、引用页码提取。


特性

能力说明
双源同步本地 zotero.sqlite(临时副本只读打开,不干扰 Zotero 进程)或 Zotero Web API(version 游标增量)
交互式范围全部 / 指定 Collection(含子级)/ 标签过滤,选择结果持久化,启动时静默复用
PDF 智能解析MinerU 官方开放平台(上传→轮询→Zip),解析产物落为 raw/ bundle(Markdown + images/),原始 PDF 不落盘
DeepSeek 全文笔记deepseek-chat 全文直读(100K token 上限、尾部截断),产出中文结构化笔记(摘要/方法/结论/创新点/局限/关键引用)
优雅降级无 PDF 或解析失败 → 基于标题+摘要生成简版笔记;后续补 PDF 自动升级全文笔记
配额与并发单轮解析上限 MAX_PARSE_PER_SYNC(默认 50),并发 3,失败记库、下轮可重跑
Wiki 编译主题综述(LLM 增量改写)、index/authors/years 索引、See Also 交叉链接、归档标记(不删页)、追加式 log
Agent 查询minisearch 内存全文检索 + 中文 bigram 分词,返回片段与 [key, §章节] 章节级引用;无命中明确告知,不编造

当前状态与路线图

里程碑内容状态
M1Zotero 双源读取与增量同步✅ 已落地并通过真实库验收
M2MinerU 解析 + DeepSeek 笔记生成✅ 已落地并通过真实环境验收(7 篇全文笔记 + 37 篇摘要降级,0 失败)
M3主题归类与 Wiki 生成✅ 已落地并通过真实环境验收(deepseek-v4-flash 综述生成 + 幂等二跑)
M4dsh 插件集成与查询工具✅ 已落地并通过 dsh 真机联调
M5测试、打包、文档完善进行中

路线图中(不阻塞使用):向量检索增强、Zotero 注释同步、引用页码提取、术语表、定时同步。问题与建议请提 Issues


架构

┌────────────────────┐      ┌─────────────────────────────────────────┐
│  Zotero 桌面端      │ ───▶ │ dsh-zotero-wiki                          │
│  / Zotero Web API  │      │                                          │
└────────────────────┘      │  sync 引擎 ──▶ SQLite 状态库             │
                            │  parse 管道 ─▶ MinerU + DeepSeek        │
┌────────────────────┐      │  compile 器 ─▶ 综述/索引/链接/归档       │
│ MinerU 官方平台     │ ◀──▶ │  query 索引 ─▶ minisearch + bigram      │
│ DeepSeek API       │      │                                          │
└────────────────────┘      │  dsh 工具:query / sync / parse          │
                            └────────────────┬────────────────────────┘
                                             ▼
                            ┌─────────────────────────────────────────┐
                            │ Obsidian Vault                           │
                            │  raw/(解析源文件) wiki/(笔记与索引)   │
                            │  references/(模板) .zotero-sync/(状态)│
                            └─────────────────────────────────────────┘

生成的 Vault 结构:

<Vault>/
├── raw/<topic>/YYYY-MM-DD-<slug>/     # MinerU 产物(Markdown + images/,只读)
├── references/                        # 模板(首次 parse 自动写入)
├── wiki/
│   ├── index.md / authors.md / years.md / log.md
│   └── <topic>/
│       ├── _index.md                  # 主题综述(LLM 生成)
│       └── <article>.md               # 单篇笔记(frontmatter + 章节化正文)
└── .zotero-sync/sync.db               # 同步游标、条目、处理状态(不入 git)

安装

环境要求

  • Node.js ≥ 22.19(使用内置 node:sqlite
  • Zotero 本地库或 Web API Key
  • (parse 阶段)MinerU Token(mineru.net API 管理页申请)与 DeepSeek API Key

从源码安装(MVP 阶段推荐)

git clone https://github.com/Wechsels/dsh-zotero-wiki.git && cd dsh-zotero-wiki
npm install
cp .env.example .env     # 然后按需编辑,见下方配置
npm run build

注册为 dsh 插件(本地路径安装)

npx -y @deepseek-ai/dsh plugin --profile web add file:/path/to/dsh-zotero-wiki

插件加载后:dsh 启动时自动静默增量同步并重建查询索引;聊天中即可调用三个原生工具。


配置

所有配置在插件目录下的 .env(参见 .env.example):

必填默认说明
ZOTERO_MODElocallocal / web
ZOTERO_DATA_DIRlocal 可选自动探测zotero.sqlitestorage/ 的目录
ZOTERO_API_KEY / ZOTERO_USER_ID / ZOTERO_GROUP_IDweb 必填Web API 凭据(Group 优先于 User)
OBSIDIAN_VAULT_PATHVault 根目录
SYNC_SCOPE_JSON交互选择持久化同步范围,如 {"mode":"all","collectionKeys":[],"tags":[]}
MINERU_TOKENparse 必填MinerU 官方平台 Token
MINERU_MODEL_VERSIONpipeline可选 vlm(质量更高)
MINERU_TIMEOUT_MS1200000单文件解析超时
DEEPSEEK_API_KEYparse/综述必填DeepSeek API Key
DEEPSEEK_MODELdeepseek-chat全文笔记生成模型
REVIEW_MODELdeepseek-v4-flash主题综述生成模型(compile)
NOTE_TOKEN_LIMIT100000每篇全文截断上限(按字符保守估算)
MAX_PARSE_PER_SYNC50单轮最多上传解析篇数(保护 MinerU 免费额度)
PARSE_CONCURRENCY3解析并发上限
REVIEW_REGEN_THRESHOLD5综述累计新增 N 篇后全量重生成
REVIEW_NOTE_CHARS2000综述生成时每篇笔记送入 LLM 的字数上限

用法

CLI(完整能力,首次配置入口)

node dist/cli.js sync                  # 增量同步;首次弹交互选择范围并持久化
node dist/cli.js sync --interactive    # 重新选择同步范围

node dist/cli.js parse --dry-run       # 预览待解析候选与配额占用
node dist/cli.js parse                 # MinerU 解析 + DeepSeek 笔记生成

node dist/cli.js compile               # 综述/索引/交叉链接/归档标记
node dist/cli.js compile --no-review   # 跳过 LLM 综述(无需 DEEPSEEK_API_KEY)

dsh 原生工具(Agent 侧)

工具说明
query_zotero_wiki(query, topic?, max_results?)检索 Wiki,返回片段、元数据与 [Zotero key, §章节] 引用;无命中返回"当前 Wiki 中没有找到相关文献"
sync_zotero_wiki()手动增量同步并重建索引
parse_zotero_wiki()手动执行解析与笔记生成(受配额限制)并重建索引

典型对话:"帮我总结荧光材料方向这几年的进展" → Agent 调用 query_zotero_wiki → 基于命中片段与引用编制回答。

同步行为约定

  • 启动自动同步按上次持久化的范围静默执行;交互选择只在首次或手动 --interactive 时出现
  • 已有页面更新/扩充,新文献新增,log.md 追加;永不物理删除页面——Zotero 中删除的条目在 Wiki 中标记 status: archived,恢复后自动复原
  • 未归入任何 Collection 的文献跳过,待用户在 Zotero 中分类后下轮处理
  • 一篇文献属于多个 Collection:raw/ 只存一份(首个 Collection),每个主题的 wiki/ 各生成一份笔记页

开发

npm run typecheck   # tsc --noEmit
npm test            # vitest(18 个测试文件 / 82 个用例)
npm run build       # vite → dist/cli.js + dist/plugin.js
npm run dev         # 监听构建
src/
├── cli.ts          # CLI(sync / parse / compile)
├── plugin.ts       # dsh 集成层(工具注册 + 启动 sync,依赖注入可测)
├── config.ts       # .env 加载与回写
├── sources/        # Zotero 双源(local sqlite / Web API)
├── sync/           # 同步引擎与 scope 过滤
├── parse/          # MinerU 客户端、Zip 解包、单篇 pipeline
├── llm/            # DeepSeek 客户端、prompts、截断
├── compile/        # 综述、索引、See Also、归档、日志
├── query/          # minisearch 索引、bigram 分词、检索
├── wiki/           # topic 映射、笔记写盘、frontmatter、模板
└── state/          # SQLite 状态库
dsh/index.js        # 插件薄壳 → dist/plugin.js

设计文档:deepseek-zotero-plugin方案.md(总体方案)与 M1/M2/M3/M4-实现计划.md(各里程碑实现计划)。


常见问题

Q:启动时提示 "SYNC_SCOPE_JSON 未配置"? 在终端运行一次 node dist/cli.js sync 完成交互式范围选择;dsh 运行环境无交互终端,首次配置必须走 CLI。

Q:本地模式提示找不到 Zotero 数据目录?.env 显式设置 ZOTERO_DATA_DIR 指向含 zotero.sqlite 的目录(如 D:\ZoteroLibrary)。

Q:parse 很慢 / 部分篇目一直是 pending? MinerU 免费额度为每日 2000 页高优先级,超出后排队降速;调小 MAX_PARSE_PER_SYNC 分多轮执行即可。

Q:中文查询效果不理想? 当前为 bigram 分词的关键词检索(零原生依赖);可尝试更具体的关键词或加 topic 过滤。向量检索增强在路线图中。

Q:npx @deepseek-ai/dsh 报 'dsh' 不是内部或外部命令? npx 在部分 Windows 环境下无法生成可执行 shim。改用本地 dsh 源码仓的 CLI 入口即可:node <dsh 仓库>/apps/cli/lib/bin.js plugin --profile web add file:/path/to/dsh-zotero-wiki

Q:dsh 启动报 Cannot find module .../dist/plugin.js? 本地 file: 安装时 pnpm 打包会遵守 .gitignore;确保 package.jsonfiles 字段显式包含 dist(本仓库已配置)。

Q:能在 Obsidian 里手动编辑笔记吗? 可以。只有 ## See Also 章节、索引页(index/authors/years)与归档提示块会被自动重写,其余内容不受影响。

许可证 / License

MIT



dsh-zotero-wiki

中文 | English

A DeepSeekHarness (dsh) plugin for Zotero: automatically syncs your Zotero library, parses PDFs with MinerU, reads full texts with DeepSeek, compiles everything into a searchable Obsidian wiki, and lets your agent answer questions with traceable literature citations.


Positioning & Scope

What it is: a Node/Cordis-style dsh plugin plus a standalone CLI that turns your Zotero library into a continuously updated Obsidian knowledge base, exposing native tools for agent retrieval.

Full pipeline:

Zotero (local DB / Web API)
  └─ sync: incremental metadata sync → .zotero-sync/sync.db (SQLite state)
      └─ parse: MinerU PDF parsing → raw/ bundles + DeepSeek full-text notes → wiki/ pages
          └─ compile: topic reviews, indexes, cross-links, archive marks
              └─ query: agents search via query_zotero_wiki, answers cite [Zotero key, §section]

Explicitly out of scope (kept lightweight): vector databases, automatic clustering, multi-user server, scheduled background services, Web UI, Zotero annotation/highlight sync, page-number citations.


Features

FeatureDescription
Dual-source syncLocal zotero.sqlite (read-only temp copy, never blocks Zotero) or Zotero Web API (version-cursor incremental)
Interactive scopeAll / specific Collections (incl. children) / tag filter; the choice is persisted and silently reused at startup
PDF parsingMinerU official open platform (upload → poll → zip); results stored as raw/ bundles (Markdown + images/); original PDFs are never persisted
DeepSeek notesdeepseek-chat full-text reading (100K-token cap, tail truncation) producing structured Chinese notes (abstract / method / conclusions / contributions / limitations / key quotes)
Graceful degradationNo PDF or parse failure → concise note from title + abstract; automatically upgraded to a full-text note once a PDF is added
Quota & concurrencyPer-run parse cap MAX_PARSE_PER_SYNC (default 50), concurrency 3, failures recorded and retryable next run
Wiki compileLLM topic reviews (incremental rewrite), index/authors/years pages, See Also cross-links, archive marks (no page deletion), append-only log
Agent queryminisearch in-memory full-text search with Chinese bigram tokenization; returns snippets with [key, §section] citations; explicitly reports "not found", never fabricates

Status & Roadmap

MilestoneScopeStatus
M1Zotero dual-source reading & incremental sync✅ landed, verified against a real library
M2MinerU parsing + DeepSeek note generation✅ landed, verified in a real environment (7 full-text notes + 37 abstract fallbacks, 0 failures)
M3Topic compilation & wiki generation✅ landed, verified in a real environment (deepseek-v4-flash reviews + idempotent re-run)
M4dsh plugin integration & query tools✅ landed, verified with a real dsh installation
M5Testing, packaging, documentationin progress

On the roadmap (non-blocking): vector retrieval, Zotero annotation sync, page-number citations, glossary, scheduled sync. Please file issues and suggestions on GitHub Issues.


Installation

Requirements

  • Node.js ≥ 22.19 (uses built-in node:sqlite)
  • A local Zotero library or a Zotero Web API key
  • (for parse) a MinerU token (from mineru.net) and a DeepSeek API key

Install from source (recommended during MVP)

git clone https://github.com/Wechsels/dsh-zotero-wiki.git && cd dsh-zotero-wiki
npm install
cp .env.example .env     # then edit; see Configuration below
npm run build

Register as a dsh plugin (local-path install)

npx -y @deepseek-ai/dsh plugin --profile web add file:/path/to/dsh-zotero-wiki

Once loaded, dsh silently runs an incremental sync at startup and rebuilds the query index; the three native tools become available in chat.


Configuration

All settings live in .env inside the plugin directory (see .env.example). Key entries:

KeyRequiredDefaultPurpose
ZOTERO_MODEyeslocallocal / web
ZOTERO_DATA_DIRlocal, optionalauto-detectDirectory containing zotero.sqlite and storage/
ZOTERO_API_KEY / ZOTERO_USER_ID / ZOTERO_GROUP_IDwebWeb API credentials (Group wins over User)
OBSIDIAN_VAULT_PATHyesVault root
SYNC_SCOPE_JSONnointeractivePersisted sync scope, e.g. {"mode":"all","collectionKeys":[],"tags":[]}
MINERU_TOKENparseMinerU official platform token
MINERU_MODEL_VERSIONnopipelinevlm for higher quality
DEEPSEEK_API_KEYparse/reviewsDeepSeek API key
DEEPSEEK_MODELnodeepseek-chatModel for full-text note generation
REVIEW_MODELnodeepseek-v4-flashModel for topic review generation (compile)
NOTE_TOKEN_LIMITno100000Per-paper truncation cap (conservative char-based estimate)
MAX_PARSE_PER_SYNCno50Max uploads per run (protects MinerU free quota)
PARSE_CONCURRENCYno3Parse concurrency
REVIEW_REGEN_THRESHOLDno5Regenerate a topic review after N accumulated new notes

Usage

CLI (full capabilities; first-run configuration entry point)

node dist/cli.js sync                  # incremental sync; interactive scope picker on first run
node dist/cli.js sync --interactive    # re-select sync scope

node dist/cli.js parse --dry-run       # preview pending candidates and quota usage
node dist/cli.js parse                 # MinerU parsing + DeepSeek note generation

node dist/cli.js compile               # reviews / indexes / cross-links / archive marks
node dist/cli.js compile --no-review   # skip LLM reviews (no DEEPSEEK_API_KEY needed)

dsh native tools (agent side)

ToolDescription
query_zotero_wiki(query, topic?, max_results?)Search the wiki; returns snippets, metadata and [Zotero key, §section] citations; replies "nothing found in the wiki" when empty
sync_zotero_wiki()Manual incremental sync + index rebuild
parse_zotero_wiki()Manual parse & note generation (quota-limited) + index rebuild

Sync behavior contract

  • Startup sync silently reuses the last persisted scope; interactive selection only happens on first run or with --interactive
  • Existing pages are updated/extended, new items create new pages, log.md is append-only; pages are never physically deleted — items removed from Zotero get status: archived and are auto-restored if they come back
  • Items without any Collection are skipped until classified in Zotero
  • An item in multiple Collections: one copy in raw/ (first Collection), one note page per topic in wiki/

Development

npm run typecheck   # tsc --noEmit
npm test            # vitest (18 test files / 82 cases)
npm run build       # vite → dist/cli.js + dist/plugin.js
npm run dev         # watch build

Design docs (Chinese): deepseek-zotero-plugin方案.md (overall plan) and M1–M4-实现计划.md (per-milestone implementation plans).


FAQ

Q: Startup says "SYNC_SCOPE_JSON not configured"? Run node dist/cli.js sync once in a terminal to complete the interactive scope selection; the dsh runtime has no interactive TTY, so first-time configuration must go through the CLI.

Q: Local mode can't find the Zotero data directory? Set ZOTERO_DATA_DIR in .env explicitly to the directory containing zotero.sqlite.

Q: parse is slow or items stay pending? MinerU's free quota is 2000 high-priority pages/day; beyond that, jobs queue at lower priority. Lower MAX_PARSE_PER_SYNC and run in multiple rounds.

Q: Chinese search quality? Tokenization is bigram-based keyword search (zero native dependencies). Try more specific keywords or a topic filter; vector retrieval is on the roadmap.

Q: npx @deepseek-ai/dsh says 'dsh' is not recognized? npx may fail to create the executable shim on some Windows setups. Use the CLI entry from a local dsh source checkout instead: node <dsh-repo>/apps/cli/lib/bin.js plugin --profile web add file:/path/to/dsh-zotero-wiki.

Q: dsh boot fails with Cannot find module .../dist/plugin.js? For local file: installs, pnpm packing honors .gitignore; make sure package.json has an explicit files field including dist (already configured in this repo).

Q: Can I hand-edit notes in Obsidian? Yes. Only the ## See Also section, the index pages (index/authors/years) and archive notice blocks are rewritten automatically; everything else is preserved.