zot
这个 skill 的目标不是展示命令面,而是把用户的自然语言 Zotero 任务稳稳落到正确的运行时路径,再把真正有用的结果带回来。
先抓住这几个原则
- 只要任务的真实目标是操作已有的本地 Zotero 库或已有/将创建的 reading workspace,就用本 skill,即使用户没说
zot。 - 用户在 Claude Code、Codex 里应该直接说需求,不应该先背命令。skill 负责把需求翻成运行时动作。
zot是唯一执行面。ref/里的旧 Python 参考实现和zot mcp serve都不是当前主路径。- 本地 SQLite 和 Zotero Local HTTP 都是只读路径;connector 只负责向 Zotero UI 当前选中的目标新增 BibTeX/RIS 条目;其他 mutation 全部走 Zotero Web API。三个边界不能混用。
- 每条写路径拥有本次操作的成功和失败;connector 或 Web API 出错时不能自动 fallback 到另一条路径。
- 回答先给结论、证据、变更或失败原因。不要先把 raw JSON 倒给用户。
先按意图分桶
1. 查条目
用户通常会说:
- “找我库里 reward hacking 相关的论文”
- “按 Smith2024 找到那篇论文”
- “给我看最近 10 条刚进库的文献”
- “看这个 collection 里有哪些条目”
- “列出当前库里的 feeds”
- “翻页看第 100-150 条”
- “哪个 collection 名字里含 transformer”
- “给我整库的条目数和按类型分布”
优先路由:
- 普通库内检索:
library search- 非空 search 的
meta.fulltext_index为legacy-tables/fts5-sidecar/unavailable。unavailable表示本次未查附件全文,标题/作者/标签仍可能命中。不要把no such table: fulltextItemWords当成 SQLite 不可读。
- 非空 search 的
- 纯列表 / 翻页:
library list --collection ... --limit ... --offset ... - 整库统计:
library stats - citation key 直达:
library citekey - 最近入库条目:
library recent --count - collection 细粒度读取:
collection get/subcollections/items/item-count/tags - collection 名内检索:
collection search - 库级组织信息:
library tags/libraries/feeds/feed-items
2. 取证据
用户通常会说:
- “把这篇文献的详情、children、引用拿出来”
- “把 PDF 批注、outline、note 都拉出来”
- “把附件下载到本地”
- “在我所有 note 里搜 reward shaping”
- “看这条现在打了哪些 tag”
- “用浏览器打开它的 DOI”
- “用本地 PDF reader 打开这篇的附件”
优先路由:
- 单篇主入口:
item get/related/children/cite/export - PDF 证据:
item pdf/fulltext/outline - annotation:
item annotation list/search - note 关键词检索:
item note search - tag 只读列:
item tag list - 打开本地资源:
item open(附件)/item open --url(DOI 或 URL) - 附件下载:
item download <attachment-key>
3. 建 workspace
用户通常会说:
- “给我建一个 llm-safety workspace”
- “把 mechanistic interpretability 相关论文整理进一个长期工作区”
- “后面我要在这个主题里做问答检索”
- “看 llm-safety workspace 里现在有哪些条目”
- “把这个 workspace 导出成 BibTeX / markdown 给我贴邮件”
优先路由:
- 建与维护:
workspace new/add/import/remove/delete - 查看成员:
workspace list/workspace show <name> --limit N - 索引与查询:
workspace index/search/query- 0.5.0 起默认增量重索引(仅 embed 新增项)。需要全重建时加
--force-rebuild;跳过 PDF 全文加--no-fulltext。
- 0.5.0 起默认增量重索引(仅 embed 新增项)。需要全重建时加
- 导出:
workspace export <name> --format markdown|json|bibtex
注意:
- workspace 名必须是 kebab-case,例如
llm-safety workspace search是关键词检索workspace query是问答式检索workspace export --format bibtex会逐条调本地 BibTeX 导出,没有 BibTeX 数据的条目会被跳过
4. 保存查询
用户通常会说:
- “把这个筛选条件存成一个 Zotero saved search”
- “列出我现在有哪些保存查询”
- “删掉这个过期的 saved search”
优先路由:
library saved-search listlibrary saved-search createlibrary saved-search delete
边界:
- Zotero Web API 当前只提供 saved search 的元数据和条件,不直接返回搜索结果
- 要解释保存的是“查询条件”,不是“动态结果集快照”
5. 下载附件
用户通常会说:
- “把 ATCH005 这个附件下载出来”
- “把这篇条目的 PDF 拉到当前目录”
优先路由:
- 已知 attachment key:
item download - 只知道父条目时:先
item children,再确定 attachment key
不要做的事:
- 不要把附件下载伪装成
item attach - 不要把上传和下载混成一个动作
6. 导入文献到 Zotero
用户通常会说:
- “把这个 bib 导入 Zotero”
- “把这几条 RIS 存进我当前的 collection”
唯一写入路由是 item import:
- 文件输入:
item import --file <path>;原始文本输入:item import --text <text> - 只在自动识别不可靠时显式加
--format bibtex|ris - 不带
--confirm先 dry-run,读取并复述 Zotero UI 当前选中的目标 collection/library、目标可写性、记录数和格式 - 用户确认上述目标与记录数后,才用同一输入执行
item import ... --confirm
边界:
- connector 只会新增 BibTeX/RIS 条目,不支持 update、tag、note、collection mutation 或 merge/dedupe
- 目标由 Zotero UI 当前选择决定,不能在命令里指定 collection
- Zotero 未运行、connector 不可达或目标只读时停止;不要改走 Web API
7. 安全写入
用户通常会说:
- “给这篇文献加一条 note”
- “打上 priority 标签”
- “把所有 reading-list 标签的条目都加上 priority”
- “把这个条目挂到某个 collection”
- “先预览再合并这两篇文献”
- “合并重复条目”
- “把 preprint 的正式发表信息写回去”
先区分能力和后端:
| 路径 | 当前能力 | 凭据 / 运行条件 |
|---|---|---|
| local SQLite / Local HTTP | 只读查询、提取和 dedupe planning | 本地 Zotero 数据;不能写 |
| connector 本机导入 | 仅 item import 新增 BibTeX/RIS 条目 |
Zotero 正在运行、connector 可达、UI 当前目标可写 |
| Zotero Web API | 除 connector 导入外的全部 mutation,含 merge/dedupe | ZOT_LIBRARY_ID + ZOT_API_KEY 或对应 profile 配置 |
写入决策顺序:
- 先跑
zot --json doctor,读取capabilities.connector_write、capabilities.web_write和write_credentials。 - BibTeX/RIS 新增导入只走 connector:先不带
--confirm预览目标、可写性、记录数和格式,复述后取得确认,再执行item import ... --confirm。 - 其他 mutation 全部走 Web API。缺少
ZOT_LIBRARY_ID或ZOT_API_KEY时停止并点名缺失凭据;不要尝试 connector。 - 对 merge/dedupe 先跑不带
--confirm的本地 preview,复述 keeper、sources、confidence 和跳过项;执行--confirm前再检查 Web 凭据。
命令路由:
- connector 写:仅
item import。 - Web API 写:
item create/add-doi/add-url/add-file/update/trash/restore/attach、item note add/update/delete、item tag add/remove/batch、collection mutation、saved-search mutation、annotation creation、sync update-status --apply和 merge/dedupe。 library dedupe --confirm默认只执行 normal-confidence 组;low-confidence 组保留在skipped_low_confidence。普通 confirm 不等于 low-confidence 授权;只有用户看过 preview 后另行、明确接受这部分风险,才可追加--include-low-confidence。- 不要宣称 connector 能执行 tag、note、collection、attachment、annotation、saved-search、status-sync 或 merge/dedupe mutation。
8. 配置排障
用户通常会说:
- “为什么这个环境不能写 Zotero”
- “先帮我看看配置是不是对的”
- “把当前 profile 切到 work”
- “初始化一个新的 config profile”
优先路由:
- 诊断:
doctor - 配置:
config show/init/set/profiles list/profiles use
connector 不需要 API key 或插件配置。doctor 显示 connector_write 不可用时,先检查 Zotero 是否正在运行以及本机 connector 是否可达;不要通过修改 profile 把 connector 扩成通用写后端。
9. 撤稿与引用质量(Scite)
用户通常会说:
- “这篇有没有被撤稿”
- “在我库里整体扫一遍 retraction notice”
- “看 attention 主题相关条目里有没有撤稿或勘误”
优先路由:
- 单条:
item scite report --item-key K或item scite report --doi 10.x/y - 库内多条:
item scite search <query>(按库内已有条目的 DOI 批量查 Scite) - 整库扫撤稿:
item scite retractions [--collection K] [--tag T] --limit N
注意:
- Scite 报告依赖外部 Scite 服务;外部网络不可用时直说,不要伪造结果
item scite report必须给--item-key或--doi之一
10. 同步与增量
用户通常会说:
- “看我库里哪些条目自版本号 N 之后变过”
- “回收站现在有什么”
- “preprint 的正式发表信息有没有要更新”
优先路由:
- 远端版本增量:
item versions --since <number> - 回收站枚举:
item deleted --limit N - preprint 状态同步(dry-run vs
--apply):sync update-status [<key>] [--collection K] [--limit N] [--apply]
注意:
- 这三个命令都依赖 Zotero Web API 凭据,先
doctor sync update-status默认 dry-run;只有加了--apply才真把字段写回 Zoterosync update-status当前只覆盖 preprint publication status,不要把它当成附件索引器
调用顺序
- 如果系统已安装
zot,优先用zot --json ... - 只有在开发仓库环境且
zot不在PATH时,才退回:
cargo run -q -p zot-cli -- ...
- 同一轮任务保持同一种调用方式,不要来回切换。
- agent 模式下默认用
--json拿 envelope,文本模式只面向真人;同一会话不要混用。
诊断门
以下场景默认先跑 doctor:
- 第一次接触这个环境
- 任何写操作
- PDF / outline / annotation / attachment 相关任务
- semantic index / semantic search / workspace query
- citation key 查询
- saved search / 配置排障 / profile 切换
- 用户说“为什么不工作”
首选:
zot --json doctor
开发环境 fallback:
cargo run -q -p zot-cli -- --json doctor
重点看这些字段:
db_existscapabilities.local_sqlite_readcapabilities.local_sqlite_read.fulltext.legacy_tablescapabilities.local_sqlite_read.fulltext.sidecar_presentcapabilities.local_http_readcapabilities.connector_write(仅表示本机 BibTeX/RIS import 能力)capabilities.web_write.configured(只表示凭据存在)capabilities.web_write.verified(当前为false,doctor 不联网验证 key/scope/permission)write_credentials.configured(只表示 Web API credential,不是 connector 导入能力)pdf_backend.availablebetter_bibtex.availablelibraries.feeds_availablesemantic_indexannotation_supportembedding.configuredconfig_file
硬约束
--library只接受user或group:<id>--json是 global flag,必须放在子命令前(例zot --json item get K),不能写成zot item --json get K- workspace 名必须是 kebab-case
- workspace 文件由
AppConfig::state_dir().join("workspaces")解析,不要把~/.config/zot/workspaces写成所有平台的路径。Linux/XDG 示例:~/.config/zot/workspaces/<name>.toml;macOS:~/Library/Application Support/zot/workspaces/<name>.toml;Windows:%AppData%\zot\workspaces\<name>.toml。运行时以doctor/config show(doctor.data.config_file)为准。索引副文件<name>.idx.sqlite,PDF cache 副文件.md_cache.sqlite zot mcp serve当前不可用item add-file不支持--attach-modeitem annotation create/create-area只适用于 PDF attachment,且 attachment 的content_type必须是application/pdf,否则报attachment-not-pdfitem annotation create支持--occurrence N(0.5.0 起,默认 1),用于在同一页出现多次的同一文本中选中第 N 个。返回 JSON 含occurrence/total_matches/more_occurrences,可用于连锁调用。
library saved-search处理的是保存查询的条件,不是结果项library saved-search create --conditions必须是 JSON 数组,每项形如{"condition": "...", "operator": "...", "value": "..."},至少一条;空数组直接报saved-search-conditions- Pdfium 路径覆盖:
ZOT_PDFIUM_LIB_PATH/PDFIUM_LIB_PATH指向 lib,ZOT_PDFIUM_CACHE_DIR覆盖自动下载缓存目录 - 永远不要直接修改
zotero.sqlite - Zotero Local HTTP API 只读;本机唯一写路径是 connector 的
item import - connector 无鉴权但仅监听 loopback,只支持向 Zotero UI 当前选中目标新增 BibTeX/RIS 条目;不能用于 merge/dedupe 或其他 mutation
- API key 和 raw merge plan token 不得进入输出、日志、fixture、文档示例或 eval
安全门
默认视为有副作用的动作:
item createitem add-doiitem add-urlitem add-fileitem import --confirmitem updateitem trashitem restoreitem attachitem merge --confirmitem note additem note updateitem note deleteitem tag additem tag removeitem tag batchitem annotation createitem annotation create-areacollection createcollection renamecollection deletecollection add-itemcollection remove-itemlibrary saved-search createlibrary saved-search deletelibrary duplicates-merge --confirmlibrary dedupe --confirmsync update-status --applyconfig initconfig setconfig profiles use
执行规则:
用户只是“看看”“分析”“评估”时,不要偷偷写库。
普通、单项、可逆写操作,在用户明确要求后可以执行。
高风险动作分三层,先总结即将发生的变化、再确认、再执行:
层 A,可逆软删除(仍要确认,但稳态可恢复):
item trash/item restoreitem note delete(实际是把 note 移到 trash,文案Note moved to trash)
层 B,高风险删除、合并或状态写入:
collection deletelibrary saved-search deletelibrary duplicates-merge --confirmlibrary dedupe --confirmitem merge --confirmsync update-status --apply
层 C,批量写(影响一组条目,必须先在小范围试,再放开):
item import --confirm(先 dry-run 复述目标可写性、记录数和格式)item tag batch --add-tag/--remove-tag(不带--confirm只做本地 preview;核对matched、affected、truncated、sample_keys和exceeds_max_affected后,用完全相同 的 filters/mutations 加--confirm;超过默认 50 条时必须在复核后显式提高--max-affected)library duplicates-merge(多源 → 单 keeper)library dedupe --confirm(整库/整 collection 多组批量合并,先用--collection圈小范围、复查 low-confidence 组)
item merge/item tag batch/library duplicates-merge/library dedupe/sync update-status不带--confirm/--apply时本身就是 dry-run preview;要把 preview 当成“还没改”,不要错说成“已经合并 / 已经写回”。connector import 的 preview 与 confirm 必须保持同一输入和格式,并在 confirm 前重新检查当前目标可写性;connector 失败不能改走 Web。
merge/dedupe 的 preview 是本地只读规划,confirm 只走 Web API;缺少 Web 凭据时保留 preview 结果并停止,不能改走 connector。
library dedupe的 low-confidence 组默认跳过。不要把普通 confirm 当作授权,也不要自行追加--include-low-confidence;必须先单独展示这些组,再取得一次明确的风险授权。写权限缺失或目标路径不支持该 mutation 时停在只读分析,不要假装成功。
item tag batch --confirm返回state: applied|partial|failed和逐操作结果。只要failed_operations > 0就必须明确报告失败项;不能因命令返回了 envelope 就称为全部成功。
常见语义差异
workspace search是关键词检索,workspace query是问答检索library recent --count 10是最近 N 条,library recent 2026-04-01 --limit 20是按时间边界筛library semantic-search是库级语义检索,不等价于 workspace queryitem add-doi/item add-url/item create --doi|--url|--pdf支持--attach-modeitem add-file可以带--doi补元数据,但不接受--attach-mode- feeds 不通过
--library group:<id>访问,而是用library feeds/feed-items item download下载本地附件文件,默认不覆盖已有目标;只有复核现有文件后才加--force。item attach上传新附件item merge是手工选 keeper/source 的通用合并,library duplicates-merge是先找重复、再按 keeper 合并library dedupe是整库/整 collection 自动选 keeper 的批量清理,library duplicates-merge是单组手工指定 keeper 的合并config show是看有效配置,config profiles use是切换默认 profile
自然语言到动作的典型映射
“找我库里 reward hacking 相关的论文,再挑一篇最相关的给我引用”
先library search,再item get/item cite“给我看最近 10 条刚进库的文献”
走library recent --count 10“把这篇论文的 PDF 批注和 notes 拉出来”
先doctor,再item get/item children/item annotation list“给我建一个 llm-safety workspace,后面我要做问答”
先workspace new/import,再index/query“把 llm-safety workspace 导出成 BibTeX 给我贴邮件”
先workspace show llm-safety,再workspace export llm-safety --format bibtex“把这个筛选条件存成保存查询”
走library saved-search create“把附件 ATCH005 下载出来”
走item download;目标已存在时先报告冲突,不要自行追加--force“用浏览器打开 ATTN001 的 DOI 看看”
走item open ATTN001 --url“把这个 bib 导入 Zotero” 先
item import --file <path>dry-run,复述当前目标、可写性、记录数和格式;用户确认后才执行同一命令并追加--confirm。确认分支会再次读取 target,变化时中止,需重新 preview“把这几条 RIS 存进我当前的 collection” 先
item import --text <ris> --format risdry-run;确认 Zotero UI 当前选中的 collection 正确且可写后,才追加--confirm;若 target 变化则重新 preview“把 citation key 为 vaswani_attention_2023 的文献插进草稿,并维护 references.bib” 先
library citekey vaswani_attention_2023解析 Zotero item key(如PXW99EKT),再用item cite PXW99EKT --style apa获取显示引用、item export PXW99EKT --format bibtex获取 BibTeX;agent 用导出的 BibTeX 条目更新references.bib,并把 BibTeX citation key 插入草稿。CLI 不直接编辑草稿或.bib文件“先预览再合并 KEEP001 和 DUPE001,确认后再真的合并”
先item merge KEEP001 DUPE001做本地 preview;复述结果并确认后,检查 Web 凭据,再执行item merge ... --confirm“我没有 API key,想在本机把重复条目清一下” 可以运行不带
--confirm的library dedupe生成本地只读计划,但必须明确说明实际合并已不支持无凭据本机执行;--confirm需要ZOT_LIBRARY_ID+ZOT_API_KEY,connector 不能 merge“这次明确走 Zotero Web API 合并” 先生成 merge preview,再确认
capabilities.web_write和 Web 凭据;用户确认后执行--confirm,Web 失败不 fallback 到 connector“帮我直接 UPDATE zotero.sqlite” 拒绝直接 SQLite 写;说明 local SQLite / Local HTTP 只读。BibTeX/RIS 新增导入可走 connector,其他 mutation 只能转到已实现的 Web 命令
“我库里这些跟 attention 有关的条目,挨个查一下 Scite 报告”
走item scite search "attention"“看 KG326EEI 这条最近改没改”
走item versions --since <last-version>“把 Recent RL 这个 saved search 删掉”
走library saved-search delete <key>“我现在这个环境为什么不能写 Zotero”
先doctor,必要时config show
从 ref\zotero-cli 迁移过来时怎么理解
search->library searchget->item getopen->item openopen --url->item open --urlannotations->item annotation list或item pdf --annotationsnotes->item note listnotes search->item note searchcollections->collection listcollection <id>->collection items <id>add doi/add url->item add-doi/item add-urltags->library tagsstats->library statsrecent [n]->library recent --count <n>merge->item merge;如果是先找重复再合并,走library duplicates/duplicates-merge
不要迁回去的旧心智:
- 不补 flat top-level alias
- 不补
--api-base - 不补 compact JSON 默认输出
- 不把 connector 风格
search/fetch重新做成另一套主命令
从 ref\zotagent 迁移过来时怎么理解
先记住两点:
- 当前
zot没有照搬zotagent的 flat command 面 - 当前
sync只做 preprint publication status,同名但不是附件索引器
已有覆盖或可替代的部分:
- DOI / URL / 文件导入:
item add-doi/item add-url/item add-file/item create - 库级语义检索:
library semantic-index/library semantic-search - 单篇 PDF 提取:
item pdf/item fulltext/item outline - citation key 入口:先
library citekey,再转到item get/item cite - 撤稿覆盖:
item scite retractions/item scite report/item scite search(zotagent 通常没内置,这是 zot 多出来的能力,不是迁移) - 回收站枚举与版本增量:
item deleted/item versions --since(替代 zotagent 风格的轮询脚本)
当前没补齐,不能假装存在:
s2add --s2-paper-idsearch-inmetadatareadexpand- zotagent 风格
status - zotagent 风格
sync全量附件索引 - 按
title/author/year/publication一次性手工建条目
遇到这些请求时怎么处理:
search-in/expand:明确说当前没有等价命令,只能先item fulltext/item pdf拉文本,再做 agent 侧二次定位metadata:说明当前没有 field-scoped metadata search;最多退到library search加已有 filterstatus:用doctor+library semantic-status组合回答,不要把sync update-status说成索引状态s2/--s2-paper-id:直接说明当前未实现,不要伪造替代命令- zotagent
sync:说明当前只能用library semantic-index --fulltext或workspace index做部分替代,而且范围主要是 metadata + PDF
失败时的 fallback
- 没有
zot:开发仓库里退回cargo run -q -p zot-cli -- ... - Zotero 未运行或 connector 不可达:停下并请用户启动 Zotero、确认本机 connector 可达后重试原 import;不改走 Web
- connector 目标只读:点名当前目标不可写,请用户在 Zotero UI 选择可写 collection/library 后重新 dry-run;不改走 Web
- Web 写不可用:明确告诉用户缺
ZOT_API_KEY/ZOT_LIBRARY_ID;connector 不能替代其他 mutation - 目标路径不支持该 mutation:说明能力边界并停止,不要暗示 connector 可以 merge、dedupe、tag 或 update
- 没有 Better BibTeX:
library citekey只走 Extra fallback - 没有 Pdfium:不要承诺 fulltext / outline / annotation / PDF 下载后的文本处理
- 没有 embedding:semantic 检索说明会降级;workspace 问答改用
--mode bm25 attach-mode auto没找到 OA PDF:条目仍可能创建成功
输出契约
最终回答应该:
- 先回答用户真正的问题,而不是先贴命令
- 再给关键证据、已执行动作或失败原因
- 明确区分 Zotero item key(如
PXW99EKT,供item get/cite/export使用)与 BibTeX citation key(如vaswani_attention_2023,供 LaTeX/Markdown 引用使用),不能把两者混作同一个 key - 如果失败,点名具体门和下一步:Zotero 未运行、connector 不可达、目标只读、Web 凭据缺失、无匹配条目或写未确认
- 默认不要倾倒 raw JSON;先读 envelope,再转述有效信息
- 优先复述 envelope 里
data/meta的关键字段,把 raw JSON 当二级证据,必要时再贴
这个 skill 的目标不是把 CLI 解释得更完整,而是让 Claude Code、Codex 等 agent 用自然语言稳定完成 Zotero 工作流。