资讯动态

Karakeep 标签(Tags)完全指南:轻量标签体系的原理、实战与源码级解析

发布时间:2026/9/12 15:57:12 来源:尧图企业网站定制
Karakeep 标签Tags完全指南轻量标签体系的原理、实战与源码级解析【免费下载链接】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标签Tags是 Karakeep 中附着在任何书签上的轻量标签用于在不引入僵硬文件夹结构的前提下为内容附加语义记录主题、来源、人物或工作流状态。本文将围绕官方文档中的标签体系结合仓库源码packages/trpc/routers/tags.ts、packages/trpc/models/tags.ts、packages/shared/types/tags.ts与 Web 端实现系统讲解标签的使用场景、AI 标签与人工标签的差异、标签管理界面操作、搜索过滤语法及底层数据模型帮助你从会打标签进阶到用好标签体系。一、标签是什么轻量、可组合、随书签流动Karakeep 官方文档docs/docs/04-using-karakeep/tags.md对标签的定位非常明确标签是附着在任何书签上的轻量标签用来添加含义而不是建立僵硬的文件夹。这意味着标签与书签的关系是多对多的扁平关联而非树状的层级归属。文档给出了三条核心使用准则用标签捕捉主题、来源、人物或工作流状态例如ai、design、to-read。这些标签可以自由组合覆盖这个话题讲什么、来自哪里、跟谁相关、处于哪个处理阶段等多个维度组合多个标签进行过滤或构建智能列表标签会跟随书签出现在任何地方列表、搜索结果、智能列表等不会因为书签被移动而丢失AI 标签可能看起来有点杂乱但额外的标签让查找更容易。标签适合广撒网式的泛化发现当你想要一个干净、精挑细选的集合时再使用列表Lists。从源码看这一设计被完整落实标签存储于数据库表bookmarkTags书签与标签的关联表为tagsOnBookmarks见 packages/db/schema.ts由 packages/trpc/models/tags.ts 引用。一张书签可以挂多个标签一个标签也可以挂多本书签且每个标签都带有一个attachedBy字段标记其来源ai或human这正是AI 标签与人工标签区分的底层基础。二、AI 自动标签与人工标签attachedBy 双轨体系文档强调AI tags might look a little messy, but the extra labels make finding things easier。Karakeep 的标签体系因此是双轨制人工标签human由你自己创建和选择的标签语义精确、命名可控AI 标签ai由 AI 自动打上的标签基于书签内容推断数量更多、覆盖面更广但可能包含噪声。这一设计在数据模型上体现得淋漓尽致。在 packages/shared/types/tags.ts 中export const zAttachedByEnumSchema z.enum([ai, human]); export type ZAttachedByEnum z.infertypeof zAttachedByEnumSchema; export const zBookmarkTagSchema z.object({ id: z.string(), name: z.string(), attachedBy: zAttachedByEnumSchema, });而 packages/trpc/models/tags.ts 在统计每个标签的使用次数时会分别统计 AI 挂载数与人工挂载数const countAi sqlnumber SUM(CASE WHEN ${tagsOnBookmarks.attachedBy} ai THEN 1 ELSE 0 END) ; const countHuman sqlnumber SUM(CASE WHEN ${tagsOnBookmarks.attachedBy} human THEN 1 ELSE 0 END) ;在 Web 界面的书签编辑器apps/web/components/dashboard/bookmarks/TagsEditor.tsx中AI 标签与人工标签也有明显的视觉区分AI 标签以紫色背景加Sparkles图标呈现人工标签则以普通 accent 背景呈现用户一眼即可分辨标签来源。需要特别说明的是attachedBy是标签与书签的关联这一层级的属性而非标签本身的属性。同一个标签名可以同时以 AI 和人工两种方式附着在不同书签上。前端在展示时做了简化处理如果一个标签在任意书签上被人工挂载过就把它归为人工标签见 apps/web/components/dashboard/bookmarks/TagsEditor.tsx 中的numBookmarksByAttachedType.human 0 ? human : ai判断。2.1 标签命名规范化与 AI 标签风格无论标签来自 AI 还是人工输入名称都会经过统一规范化。在 packages/shared/utils/tag.ts 中/** * Ensures exactly ONE leading # */ export function normalizeTagName(raw: string): string { return raw.trim().replace(/^#/, ); // strip every leading # }即标签名会去掉首尾空白并剥除开头的所有#号——你输入#ai最终会存储为ai。同时 packages/shared/types/tags.ts 规定标签名必须非空空名会被校验拒绝。针对 AI 标签的命名风格Karakeep 在用户设置中提供了tagStyle选项控制 AI 生成标签的格式。见 packages/shared/utils/tag.ts风格值说明示例lowercase-hyphens小写字母 连字符默认machine-learning、web-developmentlowercase-spaces小写字母 空格machine learninglowercase-underscores小写字母 下划线machine_learningtitlecase-spaces标题大小写 空格Machine Learningtitlecase-hyphens标题大小写 连字符Machine-LearningcamelCase驼峰命名machineLearningas-generated保持模型原始输出—此外同文件中的getCuratedTagsPromptpackages/shared/utils/tag.ts与getPotentialRelevantTagsPromptpackages/shared/utils/tag.ts展示了 Karakeep 如何驯化 AI 标签精选标签Curated Tags可以给 AI 一份预定义标签白名单提示词会强制只允许使用此列表中的标签不要创建列表之外的任何新标签如果没有合适的标签就不要输出任何标签相关标签提示Potential Relevant TagsAI 打标签时会参考相似书签被贴过的标签提示词要求尽量复用这些标签无关则忽略。这两个机制直接服务于文档中AI 标签有点乱的痛点通过白名单与参考复用让 AI 标签逐步收敛、变得可控。三、标签管理界面AllTagsView 三区视图Karakeep 的标签管理页面Dashboard → Tags由 apps/web/components/dashboard/tags/AllTagsView.tsx 实现将标签分为三个独立区块展示你的标签Your Tags仅展示人工挂载过的标签attachedBy: humanAI 标签AI Tags展示由 AI 挂载的标签attachedBy: ai未使用的标签Unused Tags尚未附着在任何书签上的空标签attachedBy: none。这三个区块分别通过三个并行查询获取每页 50 条并支持Load More分页加载见 apps/web/components/dashboard/tags/AllTagsView.tsx其中未使用标签的过滤逻辑在 packages/trpc/models/tags.ts 中实现having( opts.attachedBy ? switchCase(opts.attachedBy, { ai: and(eq(countHuman, 0), gt(countAi, 0)), // 只有 AI 挂载、没有人工挂载 human: gt(countHuman, 0), // 存在人工挂载 none: eq(countAny, 0), // 完全没有任何挂载 }) : undefined, );页面上还提供搜索框与排序下拉菜单搜索按标签名模糊匹配后端使用 SQLLIKE %name%见 packages/trpc/models/tags.ts输入有 100ms 防抖排序支持usage按使用次数降序默认、name按名称升序、relevance按相关性排序仅在搜索时可用见 packages/shared/types/tags.ts 的 refine 校验。相关性排序的实现逻辑是完全匹配得 2 分、前缀匹配得 1 分再按名称长度升序见 packages/trpc/models/tags.ts。3.1 创建标签点击页面右上角的 Create Tag 按钮CreateTagModal.tsx输入名称即可创建一个新标签。后端 packages/trpc/routers/tags.ts 的create接口会做以下处理名称经normalizeTagName规范化后非空校验若同名标签已存在数据库唯一约束会触发SQLITE_CONSTRAINT_UNIQUE后端返回BAD_REQUESTTag name already exists for this user.见 packages/trpc/models/tags.ts。也就是说标签名在单个用户范围内必须唯一重名会直接报错。3.2 重命名、删除与合并重命名通过update接口修改标签名见 packages/trpc/routers/tags.ts 与 packages/trpc/models/tags.ts。若重命名后的名称撞上已有标签同样触发唯一约束报错后端错误信息会贴心提示You might want to consider a merge instead——建议你改用合并而非重命名。删除delete接口会先查出所有挂载该书签的关联记录再删除标签本身并触发受影响书签的搜索索引重建triggerSearchReindex见 packages/trpc/models/tags.ts。合并merge接口将多个标签合并为一个intoTagId为目标标签fromTagIds为被合并的源标签列表整个过程在数据库事务中完成先解除源标签与书签的关联再将这些关联重新指向目标标签去重后onConflictDoNothing最后删除源标签见 packages/trpc/models/tags.ts。合并是清理AI 标签噪音最有力的工具——把语义相同的 AI 标签合并成一个人工维护的规范标签。AllTagsView 还提供了拖拽合并开关Drag and drop merging开启后标签以可拖拽的TagPill呈现把 A 标签拖到 B 标签上即可触发合并关闭拖拽开关后则进入批量编辑模式BulkTagAction.tsx可多选标签后执行批量重命名/删除等操作。3.3 一键清理未使用标签页面底部提供 Delete All Unused Tags 按钮一次性删除所有未附着在任何书签上的空标签。后端 packages/trpc/routers/tags.ts 的deleteUnused接口调用 packages/trpc/models/tags.ts 的实现删除该用户下所有在tagsOnBookmarks中不存在的标签NOT EXISTS子查询并返回删除数量。该按钮在未使用标签数为 0 时自动禁用。四、在书签上添加、移除标签在实际使用中给书签打标签主要通过书签编辑器中的标签输入框完成对应组件 TagsEditor.tsx。它的交互逻辑包括搜索或创建输入关键字会即时查询已有标签无输入时按使用量排序有输入时按相关性排序见 apps/web/components/dashboard/bookmarks/TagsEditor.tsx若输入的内容与任何已有标签都不完全匹配下拉框会提供Create xxx选项直接回车或点击即可创建并挂载新标签选中与取消点击下拉项即可挂载标签再次点击已选中的标签则将其移除按 Backspace输入为空时可快速移除最后一个标签乐观更新前端采用乐观更新策略创建新标签时先生成temp-前缀的临时 ID 立即渲染待服务器返回真实 ID 后替换见 apps/web/components/dashboard/bookmarks/TagsEditor.tsx交互响应迅速AI 标签可视化已挂载的 AI 标签显示紫色背景与 Sparkles 图标人工标签显示常规背景来源一目了然。文档中tags travel with a bookmark wherever it appears在此得到印证标签是书签数据的组成部分书签出现在列表、搜索结果、智能列表或导入导出时其标签都会随之携带。五、用标签过滤与搜索tag: 查询语法文档指出可以组合多个标签进行过滤。在 Karakeep 的搜索框中这通过tag:查询前缀实现。搜索语法解析器位于 packages/shared/searchQueryParser.ts其中tag:前缀第 46 行的识别列表以及第 217-220 行的解析分支用于按标签名精确匹配tag:ai只匹配贴有ai标签的书签tagged关键字第 140-143 行用于按是否有任何标签过滤tagged:true匹配所有带标签的书签tagged:false匹配所有无标签的书签。组合示例tag:ai tag:design # 同时带 ai 和 design 两个标签的书签 tagged:true # 所有带标签的书签 tag:to-read tagged:false # 理论上带 to-read 标签且……按解析器语义组合过滤搜索过滤器可以与关键词、is:、list:等前缀自由组合实现在某个列表内、含某个标签、标题含某词的复合检索。更多语法细节可参考 搜索查询语言文档。六、标签 vs 列表何时用哪个文档给出了一条非常清晰的决策准则用标签做广泛发现broad discovery用列表做干净精挑clean, hand-picked setup。结合实际用法可以这样理解标签适合AI 自动标注的海量语义关键词、临时的工作流状态to-read、done、多维度交叉筛选。标签可以多对多、可以自动生成、可以合并和批量清理代价是命名可能不统一、会有冗余列表适合需要人工精心编排的固定集合如本周精读、某个专题合集。列表是经过挑选的书签集合适合展示和分享但不适合承载自动化的、大规模的标注。一个推荐的组合工作流是让 AI 自动打标签负责广撒网搜索时用tag:快速召回候选再用列表把真正精选的内容手工收纳二者互补而非互斥。七、标签的底层实现数据库模型与 API7.1 数据模型标签体系涉及两张核心表见 packages/db/schema.tsbookmarkTags标签主表字段至少包含id、name、userId标签属于哪个用户且(userId, name)上有唯一约束这是同名标签报错的数据库层保障tagsOnBookmarks书签与标签的多对多关联表字段包含bookmarkId、tagId、attachedByai/human是AI 标签 vs 人工标签的存储位置。标签的归属校验贯穿所有操作任何对标签的读写都会先校验tag.userId ctx.user.id否则抛出FORBIDDEN见 packages/trpc/models/tags.ts。7.2 tRPC 接口一览标签相关的 tRPC 路由全部定义在 packages/trpc/routers/tags.ts挂在tagsscope 下createScopedAuthedProcedure(tags)并统一使用事件日志中间件记录tag.create等操作接口类型输入要点说明tags.createmutation{ name }创建标签重名报BAD_REQUESTtags.getquery{ tagId }获取单个标签详情与统计书签数、AI/人工分布tags.updatemutation{ tagId, name }重命名标签tags.deletemutation{ tagId }删除标签tags.deleteUnusedmutation—删除所有未使用标签返回{ deletedTags }tags.mergemutation{ intoTagId, fromTagIds }合并标签事务 搜索重索引tags.listquery{ nameContains, ids, attachedBy, sortBy, cursor, limit }分页查询标签列表tags.list支持的分页上限为单页 1000 条MAX_NUM_TAGS_PER_PAGE见 packages/shared/types/tags.ts默认按usage排序返回每个标签的numBookmarks与numBookmarksByAttachedTypeAI/人工挂载数拆分。7.3 搜索索引同步标签变更并非孤立操作重命名、删除、合并标签后所有受影响的书签都需要重新索引以保持全文搜索与标签过滤的一致性。代码中通过triggerSearchReindex(bookmarkId, { groupId: ctx.user.id })触发见 packages/trpc/models/tags.ts 与 packages/trpc/models/tags.ts失败时仅记录错误日志而不中断主流程。这就是改一个标签所有相关书签的搜索结果立即同步更新的底层机制。八、实用工作流建议综合文档与源码推荐以下标签使用实践为 AI 标签设定风格与白名单在设置中指定tagStyle如lowercase-hyphens必要时配置 Curated Tags 白名单从源头减少 AI 标签的杂乱定期清理未使用标签使用标签页的 Delete All Unused Tags 一键清理空标签避免标签库无限膨胀用合并收敛同义标签遇到语义相同但写法不同的 AI 标签如ml与machine-learning使用拖拽合并或tags.merge统一为一个人工维护的规范标签用tag:语法做日常检索把tag:to-read、tag:ai这类常用查询固化到搜索习惯中快速召回候选标签 列表分层管理AI 标签负责自动化发现人工列表负责精挑细选二者结合即可兼顾找得到与够整洁。九、延伸阅读标签体系总览当前版本docs/docs/04-using-karakeep/tags.md列表Lists使用指南docs/docs/04-using-karakeep/lists.md搜索查询语言含tag:语法docs/docs/04-using-karakeep/search-query-language.md标签类型定义与校验packages/shared/types/tags.ts标签名称规范化与 AI 标签提示词packages/shared/utils/tag.ts标签业务模型创建/查询/合并/删除packages/trpc/models/tags.ts标签 tRPC 路由packages/trpc/routers/tags.ts标签管理界面apps/web/components/dashboard/tags/AllTagsView.tsx书签标签编辑器apps/web/components/dashboard/bookmarks/TagsEditor.tsx【免费下载链接】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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价