:基于真实书签数据的 AI 标签质量盲测实战指南)
Karakeep 模型对比工具compare-models基于真实书签数据的 AI 标签质量盲测实战指南【免费下载链接】hoarderA self-hostable bookmark-everything app (links, notes and images) with AI-based automatic tagging and full text search项目地址: https://gitcode.com/GitHub_Trending/ho/hoarder本文围绕 Karakeep 仓库中 tools/compare-models/README.md 所描述的独立 CLI 工具展开。该工具用你实例中真实存在的书签数据以「盲测 随机乱序」的方式对比不同 AI 模型的自动打标签质量是你在更换/升级打标签模型、做 AI 标签质量验收时的实用评估方案。读完本文你将掌握两种对比模式模型 vs 模型、模型 vs 现有 AI 标签的完整配置、运行与投票交互流程并理解其背后复用的 Karakeep 共享推理与提示词基础设施。工具定位为什么需要对比模型打标签效果Karakeep 的核心能力之一是「AI 自动打标签」系统会把书签内容交给配置好的大模型生成一组规范化标签。当你想从gpt-4o-mini换到claude-3-5-sonnet或想验证某个新模型是否比现有模型更优秀时单纯跑一两次推理很难得出可靠结论——标签质量带有较强主观性且不同模型对同一内容的标签风格差异很大。compare-models工具正是为此设计它从你的 Karakeep 实例拉取真实书签对每个书签分别让两个候选方两个模型或一个模型 vs 现有 AI 标签生成标签然后由你人工投票选出更优的一方。整个过程是盲测的——投票界面只显示 Model A / Model B模型真实名称直到最终结果才揭晓同时每个书签的左右位置会随机打乱消除位置偏见。正如 README 所强调的这是一个「human-in-the-loop」人在回路的手动评估工具结果只输出到控制台、不做持久化适合作为模型选型与质量验收的决策依据。前置条件与整体架构你需要准备什么一个可访问的 Karakeep 实例本机或远程并拥有 API Key实例中已有若干链接型link书签在「模型 vs 现有」模式下还需这些书签已带 AI 生成的标签一个兼容 OpenAI 接口的推理服务可以是 OpenAI 官方也可以是 OpenRouter 等聚合服务工具通过OPENAI_BASE_URL切换见下文支持pnpm的 Node.js 环境推荐使用 pnpm workspace 运行。从源码看工具的模块划分工具位于 tools/compare-models/src源码结构清晰地对应了 README 描述的功能index.ts主流程入口负责模式判断、取数、逐条推理、投票统计与最终结果展示config.ts用 zod 对全部环境变量做校验与默认值处理apiClient.ts基于karakeep/sdk封装 Karakeep API 客户端负责分页拉取书签bookmarkProcessor.ts把书签内容拼装成提示词输入inferenceClient.ts创建 OpenAI 兼容推理客户端并解析结构化标签输出interactive.ts终端交互投票提问、盲测展示、进度与最终结果渲染types.tsBookmark、ComparisonResult、FinalResults等核心类型定义。该工具本身不重复造轮子而是直接复用 Karakeep 主应用的共享基础设施API 走karakeep/sdk类型安全、自带鉴权推理走karakeep/shared/inference的 OpenAI 客户端支持结构化输出提示词走karakeep/shared/prompts的统一标签提示词构建器含 token 管理。这一点在 package.json 的依赖声明中可以得到印证karakeep/sdk、karakeep/shared均为 workspace 依赖另有chalk终端着色与zod校验/解析。环境变量与配置详解工具的全部配置都通过环境变量注入并在 config.ts 中由 zod schema 统一校验。README 给出的必填项如下# Karakeep API 配置 KARAKEEP_API_KEYyour_api_key_here KARAKEEP_SERVER_ADDRhttps://your-karakeep-instance.com # 对比模式默认: model-vs-model # - model-vs-model: 两个模型互相比较 # - model-vs-existing: 新模型 vs 现有 AI 标签 COMPARISON_MODEmodel-vs-model # 待比较的模型 # MODEL1_NAME: 要测试的新模型始终必填 # MODEL2_NAME: 第二个参与对比的模型仅 model-vs-model 模式必填 MODEL1_NAMEgpt-4o-mini MODEL2_NAMEclaude-3-5-sonnet # OpenAI/OpenRouter API 配置用于推理 OPENAI_API_KEYyour_openai_or_openrouter_key OPENAI_BASE_URLhttps://openrouter.ai/api/v1 # 可选默认直连 OpenAI # 可选测试书签数量默认: 10 COMPARE_LIMIT10源码中隐藏的可选进阶参数对照 config.ts除 README 列出的变量外源码还支持以下几组进阶推理参数README 未展开但实战中很有用环境变量类型/取值范围默认值作用COMPARISON_MODEmodel-vs-model/model-vs-existingmodel-vs-model对比模式COMPARE_LIMIT整数10参与测试的书签数量INFERENCE_CONTEXT_LENGTH整数8000推理上下文长度控制送入模型的 token 上限INFERENCE_MAX_OUTPUT_TOKENS整数2048模型最大输出 token 数INFERENCE_USE_MAX_COMPLETION_TOKENStrue/falsefalse是否使用最大补全 token 上限INFERENCE_REASONING_EFFORTlow/medium/high/none/xhigh未设置推理强度适配支持 reasoning effort 的模型OPENAI_SERVICE_TIERauto/default/flex未设置OpenAI 服务等级需要说明的是config.ts用z.string().min(1)校验KARAKEEP_API_KEY、MODEL1_NAME、OPENAI_API_KEY用z.string().url()校验KARAKEEP_SERVER_ADDR与OPENAI_BASE_URL因此缺失或格式错误的环境变量会让工具启动即报错退出——这也是 README「错误处理」一节中「缺失必填环境变量会以明确错误信息退出」的源码依据。若配置非法zod 抛出的校验错误会被 index.ts 末尾的main().catch()捕获并以红色✗ Fatal error打印。直连 OpenAI 与使用 OpenRouter工具通过OPENAI_BASE_URL决定推理端点README 给出了两种典型配置使用 OpenRouter可在一个 Key 下访问多个模型OPENAI_BASE_URLhttps://openrouter.ai/api/v1 OPENAI_API_KEYyour_openrouter_key直连 OpenAIOPENAI_API_KEYyour_openai_key # OPENAI_BASE_URL 省略即可直连 OpenAI从 inferenceClient.ts 的源码可以看到createInferenceClient会把上述变量连同textModel、imageModel此处均设为待比较的模型名、contextLength、maxOutputTokens、outputSchema: structured等一起传给共享的OpenAIInferenceClient。这也意味着只要是 OpenAI 兼容协议的服务OpenRouter、各类自建网关等都可以通过OPENAI_BASE_URL接入。安装与三种运行方式方式一pnpm 运行推荐README 推荐的开发运行方式利用tsx直接执行 TypeScript 源码并自动加载.env文件cd tools/compare-models pnpm install pnpm runpnpm run实际执行的是 package.json 中的脚本tsx --env-file./.env src/index.ts——注意它要求当前目录下存在.env文件。方式二使用 .env 文件先创建.envKARAKEEP_API_KEYyour_api_key KARAKEEP_SERVER_ADDRhttps://your-karakeep-instance.com MODEL1_NAMEgpt-4o-mini MODEL2_NAMEclaude-3-5-sonnet OPENAI_API_KEYyour_openai_key COMPARE_LIMIT10然后同样执行pnpm run方式三编译后直接用 node 运行先构建出dist/index.js再用环境变量注入方式运行pnpm build export KARAKEEP_API_KEYyour_api_key export KARAKEEP_SERVER_ADDRhttps://your-karakeep-instance.com export MODEL1_NAMEgpt-4o-mini export MODEL2_NAMEclaude-3-5-sonnet export OPENAI_API_KEYyour_openai_key node dist/index.jspnpm build对应脚本为tsc chmod x dist/index.js构建产物位于dist/index.js同时 package.json 声明了bin: { compare-models: dist/index.js }即构建后可获得compare-models命令行入口。README 特别提示推荐pnpm run走 tsx 开发模式以获得最佳体验。两种对比模式与使用流程Model vs Model两个模型互相对比COMPARISON_MODEmodel-vs-model MODEL1_NAMEgpt-4o-mini MODEL2_NAMEclaude-3-5-sonnet该模式下每个书签会让两个模型各自独立推理生成标签然后由你投票选择哪一组的标签更好。源码 index.ts 在启动时会校验MODEL2_NAME是否提供缺失则直接红色报错并以退出码 1 终止。Model vs Existing新模型 vs 现有 AI 标签COMPARISON_MODEmodel-vs-existing MODEL1_NAMEgpt-4o-mini # 该模式不需要 MODEL2_NAME此模式不再让第二个模型跑推理而是把书签上已经存在的 AI 标签作为对手。它适合三种典型场景测试新模型是否比当前模型产出更好的标签评估是否值得从当前模型切换到另一个模型对现有 AI 标签做质量抽检QA。关键过滤规则该模式只对比已带 AI 标签的书签。README 明确说明只保留attachedBy: ai的标签源码 index.ts 中对应实现为bookmarks.filter((b) b.tags.some((t) t.attachedBy ai))。attachedBy字段的取值在数据库层被约束为ai | human见 packages/db/schema.ts。若过滤后没有符合条件的书签工具会打印黄色提示并直接结束。完整使用流程结合源码拉取书签KarakeepAPIClient.fetchBookmarks调用 SDK 的GET /bookmarks以 50 条一批分页拉取携带includeContent: true与archived: false参数并在客户端侧过滤出content.type link的书签最终截取前COMPARE_LIMIT条。这一点对应 README「Bookmark Filtering」中「只测链接型书签、非归档、最新 N 条」的说明apiClient.ts。逐条推理对每个书签先由extractBookmarkContent把 URL、标题、描述、HTML 内容拼接为文本再调用共享的buildTextPrompt构建打标签提示词空自定义提示词、标签风格为as-generated即保留模型原始生成结果见 bookmarkProcessor.ts。随后用 zod 定义的{ tags: string[] }结构约束模型输出并解析为标签数组见 inferenceClient.ts。推理按顺序逐条执行保证状态管理简单README 已注明。随机乱序 盲测展示源码用Math.random() 0.5决定模型 1 还是模型 2 显示在 Model A 位置投票界面只显示 Model A / Model BdisplayComparison的blind参数为true模型真名在投票阶段完全隐藏。人工投票界面形如 README 给出的示例 Bookmark 1/10 How to Build Better AI Systems https://example.com/article This article explores modern approaches to... ───────────────────────────────────── Model A (blind): • ai • machine-learning • engineering Model B (blind): • artificial-intelligence • ML • software-development ───────────────────────────────────── Which tags do you prefer? [1Model A, 2Model B, sskip, qquit] 合法输入与对应行为interactive.ts 的askQuestion index.ts 的计票逻辑1投给 Model A计票时按乱序结果映射回真实模型2投给 Model Bs/skip跳过本次对比计入 Skippedq/quit提前退出并展示当前累计结果。展示最终结果全部完成或提前退出后控制台输出投票汇总与胜者─────────────────────────────────────── FINAL RESULTS ─────────────────────────────────────── gpt-4o-mini: 6 votes claude-3-5-sonnet: 3 votes Skipped: 1 Errors: 0 ─────────────────────────────────────── Total bookmarks tested: 10 WINNER: gpt-4o-mini ───────────────────────────────────────从 interactive.ts 的displayFinalResults源码可见票数相同会显示 RESULT: TIE否则显示 WINNER: 模型名。只有在这个最终结果里真实模型名才会揭晓。错误处理任一模型在某书签上推理失败时会打印红色错误信息✗ Error: ...该次对比计入Errors流程继续index.ts 中的try/catchcounters.errors错误数在最终结果中单独一行展示Errors: N必填环境变量缺失/非法时工具以清晰的错误信息退出见上文配置校验部分。书签过滤规则的实现细节README 明确当前工具只测试以下书签这些规则都可以在源码中找到对应实现仅链接型书签fetchBookmarks中用b.content?.type link过滤不含文本笔记text notes与资产assets类书签非归档请求参数固定携带archived: false最新 N 条分页拉取后slice(0, limit)limit即COMPARE_LIMITmodel-vs-existing 模式附加条件仅保留含attachedBy: ai标签的书签且该模式下模型 2 的「标签」直接取自书签上现有的 AI 标签bookmark.tags.filter((t) t.attachedBy ai).map((t) t.name)不再触发推理。从源码看架构复用与设计取舍README「Architecture」一节总结了工具对 Karakeep 共享基础设施的复用结合源码可以看得更具体API 客户端apiClient.ts使用createKarakeepClient来自karakeep/sdk以Bearer ${KARAKEEP_API_KEY}鉴权baseUrl 为${KARAKEEP_SERVER_ADDR}/api/v1/请求GET /bookmarks并支持 cursor 分页——与 Karakeep 主应用使用同一套类型安全 SDK。推理inferenceClient.ts复用karakeep/shared/inference的OpenAIInferenceClient配置outputSchema: structured配合 zod schema 获得结构化、可解析的标签输出。提示词bookmarkProcessor.ts复用karakeep/shared/prompts.server的buildTextPrompt带contextLengthtoken 管理并以as-generated保留模型原始标签风格保证对比的是模型真实能力而非被提示词改写后的结果。这种「零代码重复、全量复用主应用核心逻辑」的设计保证了对比结论与 Karakeep 实际打标签路径的一致性——你在工具里测出的模型差异就是将来接入主应用后的真实差异。注意事项与使用建议评估方式工具面向人工、人在回路的评估结果只打印在控制台不持久化、不写回 KarakeepREADME「Notes」已明确内容拉取书签以includeContenttrue拉取因此评估依据的是真实抓取内容推理顺序推理串行执行模型数量与书签数量较多时耗时较长建议先用较小的COMPARE_LIMIT如默认 10试跑样本选择测试结果受所选书签样本影响较大若要评估模型切换建议覆盖不同类型、不同领域的书签并可多次运行观察一致性现有 AI 标签的前提使用model-vs-existing前请确认实例中确有 AI 生成的标签无则工具会提示 No bookmarks found with AI tags 并退出。构建与产物如需生成独立可执行产物pnpm build构建产物为dist/index.js可执行位已在构建脚本中设置配合 package.json 中的bin声明可通过compare-models命令直接调用。产物同样依赖上述环境变量运行方式与「方式三」一致。小结compare-models是 Karakeep 生态中一个轻量而严谨的模型评估工具以真实书签为样本、以共享推理管线为引擎、以盲测与随机乱序消除主观偏差、以人工投票作为最终裁决。无论你是想换一个更便宜的模型、评估开源模型能否替代商业模型还是例行抽检已有 AI 标签质量都可以用 tools/compare-models/README.md 与本文提供的源码级细节在几分钟内搭建起一次可复现的对比实验。【免费下载链接】hoarderA self-hostable bookmark-everything app (links, notes and images) with AI-based automatic tagging and full text search项目地址: https://gitcode.com/GitHub_Trending/ho/hoarder创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考