mcpField
L
llm-wiki

llm-wiki

github.com/nashsu生产力1521.8k 次安装23 周前更新
代码仓库

关于 llm-wiki

llm-wiki 是用于通过本地 HTTP API 查询 LLM Wiki 的技能,面向需要从个人知识库检索和读取内容的 Agent。它涵盖项目选择、搜索、页面读取、图谱查询和来源重扫,并强调项目边界与令牌安全。

主要功能

  1. 01通过本地 HTTP API 访问
  2. 02搜索并读取 Wiki 页面
  3. 03查询 Wikilinks 图谱
  4. 04重扫来源文件
  5. 05支持多项目解析

适用场景

  1. 01查询 Wiki 中的主题资料
  2. 02读取指定页面并引用路径
  3. 03查看 Wiki 图谱结构
  4. 04为新增来源触发重扫

MCP 相关

此技能未说明与 MCP 的关系。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/nashsu/llm_wiki_skill --skill llm-wiki

安装后在 Claude Code 中输入/llm-wiki确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
examples.md
api-reference.md

详细介绍

LLM Wiki 本地 API 技能

通过内置 HTTP API 与用户本地运行的 LLM Wiki 应用交互。这是一个标准 JSON API——直接使用环境中已有的任意 HTTP 工具调用(curl、fetch、requests、http 中间件等)。无需安装客户端库,也无需学习 SDK。

将该 wiki 视为用户一直在整理的私有、结构化知识库:页面位于 wiki/**.md,原始文档位于 raw/sources/,wiki 链接构成一个图谱。

何时调用

仅当用户明确指的是 LLM Wiki 时才调用——例如提到应用名称,或以 wiki、知识库 的语境来表述。具体来说:

  • 提出的问题是:“我的 wiki/知识库/我的知识库/LLM Wiki 对 X 有什么说法?”
  • 要求“在我的 wiki/LLM Wiki 项目/我的知识库中搜索 X”
  • 提到某个wiki 页面的文件名(不含扩展名)/标题,并希望阅读或添加交叉链接
  • 询问 wiki 图谱/知识图谱/wiki 概览/wiki 结构
  • 刚在 LLM Wiki 的源文件夹下添加或编辑文件,并希望重新运行导入/重新索引
  • 表示“用我的 wiki提供上下文”/“让你的回答以我的 wiki为依据”/“检查我的 LLM Wiki”
  • 提到一个 wiki 项目(通过 ID、绝对路径或 current)

在用户这样说时,请勿调用:

  • “搜索我的笔记”,且没有进一步说明——可能指 Obsidian/Apple Notes/Notion/Logseq/Bear 等
  • “在我的笔记本里查找”——可能指 Jupyter/OneNote/Notability
  • “查看我的 Obsidian/Notion/Roam/Logseq 知识库”——明确指的是其他工具
  • “查一下我的 Anki/Readwise/Pocket”——这是其他工具
  • “搜索我的文件/我的 Documents 文件夹”——这是通用文件系统,不是 wiki
  • 一般性的世界知识、时事,或任何用户明确希望从开放网络获取的内容

如果无法确定用户指的是哪个知识工具,请询问:“你指的是 LLM Wiki,还是其他工具?”——不要在用户可能指的是 Obsidian 知识库时,悄悄调用 LLM Wiki API。

快速开始

整个 API 都是纯 HTTP + JSON。最快的方式:

BASE=http://127.0.0.1:19828
TOKEN="${LLM_WIKI_API_TOKEN:-<paste-from-Settings>}"

# 1. probe state — no auth needed
curl -s $BASE/api/v1/health

# 2. list projects
curl -s -H "Authorization: Bearer $TOKEN" $BASE/api/v1/projects

# 3. search
curl -s -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"query":"rope embedding","topK":5}' \
  $BASE/api/v1/projects/current/search

# 4. read a page
curl -s -H "Authorization: Bearer $TOKEN" \
  "$BASE/api/v1/projects/current/files/content?path=wiki/concepts/rope.md"

如果你使用 TypeScript/JavaScript:

const res = await fetch("http://127.0.0.1:19828/api/v1/projects/current/search", {
  method: "POST",
  headers: { "Authorization": `Bearer ${process.env.LLM_WIKI_API_TOKEN}`, "Content-Type": "application/json" },
  body: JSON.stringify({ query: "rope embedding", topK: 5 }),
})
const { results } = await res.json()

Python 也是同样的形式——使用 urllib.request、requests、httpx 或你已有的任何工具。不要安装任何新工具。

身份验证模型

API 仅限 localhost 使用。令牌来源为以下之一:

  1. LLM_WIKI_API_TOKEN 环境变量(如果已设置,则优先于 UI 设置)
  2. 用户通过 Settings → API Server 保存的 apiConfig.token
  3. allowUnauthenticated: true 模式(无需令牌;仅在少见情况下由用户主动启用)

务必先检查 /api/v1/health——它会返回 { enabled, authConfigured, allowUnauthenticated, tokenSource }。如果 authConfigured: false && allowUnauthenticated: false,请让用户打开 Settings → API Server → Generate new token。在完成身份验证设置前不要继续。

发送令牌的三种等效方式:

Authorization: Bearer <token>          # preferred
X-LLM-Wiki-Token: <token>              # alternative header
?token=<urlencoded-token>              # query param — last resort, leaks into logs

绝不要记录或回显令牌。绝不要将令牌放入用户能在输出中看到的 URL 中(Referer/shell 历史记录/日志都会泄露令牌)。

标准工作流

当用户要求“在我的 wiki 里查一下”时:

  1. 解析项目(见下文项目解析)。
  2. 搜索:使用 { query, topK: 5..10 } 调用 POST /api/v1/projects/{id}/search → 返回按相关性排序的结果(path、title、snippet、score、titleMatch,以及可选的 vectorScore、images)。检查 response.mode,以确定是否启用了混合检索。
  3. 阅读靠前的结果:对每个有用的结果,调用 GET /api/v1/projects/{id}/files/content?path=... 获取完整 Markdown 内容。也可以在搜索请求中传入 includeContent: true,以免再次发起请求。
  4. 引用并回答:基于阅读过的页面综合回答。引用你使用的每个页面的 path,方便用户核实并在应用中直接跳转。
解读评分

score 字段的量级取决于 mode:

  • mode: "keyword" — 关键词累加评分。文件名完全匹配约为 200;标题中包含短语约为 50+;词元集合匹配通常只有个位数。低于最高结果约 5% 的评分应视为置信度较低。
  • mode: "hybrid" 或 "vector" — RRF(倒数排名融合)评分,通常在 0.015–0.035 范围内。绝对数值较小,重要的是相对排序。如需了解嵌入匹配的强度,可使用每条结果的 vectorScore(原始余弦值,范围 0–1)。

不要对不同模式应用固定的评分阈值。按 score 降序排列,并参考相对差距。

项目解析

每个项目范围端点中的 {id} 接受 四种形式:

形式使用时机示例
current(字面值)“我的 wiki / 我的知识库 / 这个项目 / 这个 wiki”的默认值。用户指的是桌面 UI 中当前打开的项目。/api/v1/projects/current/search
UUID用户提供了项目 ID,或者你之前已将名称解析为 ID,想要再次使用。/api/v1/projects/a0e90b29-fcf3-4364-9502-8bd1272de820/files
绝对文件系统路径(URL 编码)用户指定了路径(例如 ~/notes/research)。当用户有多个名称相似的项目时很有用。/api/v1/projects/%2FUsers%2Fme%2Fwiki%2Fresearch/files
项目名称不直接支持。 必须先执行 GET /api/v1/projects,按 name 查找匹配项,然后使用该项目的 id。

决策树:根据用户的描述判断:

"my wiki" / "my 知识库" / "this wiki" / "this project" / unspecified
    → use `current`

"my Research project" / "in Reading"
    → GET /api/v1/projects
    → name-match (case-insensitive substring on `name`)
    → use the resulting `id`
    → if 0 matches: tell the user, list available names, fall back to `current` only if they confirm
    → if 2+ matches: ask the user to disambiguate, quoting both names + paths

"the project at /Users/me/foo"
    → URL-encode the path, use directly
    → if the API returns 404, the project isn't registered — list and let user pick

"project a0e90b29-…"
    → use the UUID literally

在本次对话的其余部分缓存已解析的 id——无需每次调用都重新执行 GET /projects。但如果用户在对话中途切换上下文(“现在查看我的 Reading 项目”),则重新解析。

如果用户没有说明要查找哪个项目,默认使用 current,并提及一次:“正在查看你的活动项目(Research Notes)……”。这样可以避免意外跨项目查找。

对于图谱 / 交叉引用问题:

  • GET /api/v1/projects/{id}/graph?limit=200 → { nodes: [{id, label, nodeType, path, linkCount}], edges: [{source, target, weight}] }
  • 使用 ?q=term(对 id/label 进行不区分大小写的子字符串匹配)和 ?nodeType=entity|concept|... 进行筛选

对于“我添加了新文档”请求:

  • POST /api/v1/projects/{id}/sources/rescan → 返回 { queue: { tasks }, changedTasks: [...] }。告知用户有多少个文件发生了变化。实际摄取通过桌面队列异步运行。

端点约定(v1)

方法路径说明
GET/api/v1/health无需身份验证。返回 { ok, status, version, enabled, authRequired, authConfigured, allowUnauthenticated, tokenSource }。
GET/api/v1/projects列出项目。每项包含:{ id, name, path, current }。
GET/api/v1/projects/{id}/files?root=wiki|sources|all&recursive=true&maxFiles=2000{ name, path, isDir, size, children } 树。上限为 10000 个节点(413)。
GET/api/v1/projects/{id}/files/content?path=wiki/foo.md仅限文本文件(md/mdx/txt/json/yaml/yml/csv/html/htm/xml/rtf/log)。最大 2 MB。二进制文件返回 415,超出大小限制返回 413,路径超出范围返回 403。
POST/api/v1/projects/{id}/search请求体:{ "query": "...", "topK": 10, "includeContent": false }。当用户在 Settings 中配置了嵌入时,使用 混合搜索(关键词 + 向量);否则回退到仅关键词搜索。响应包含 mode: "keyword" | "vector" | "hybrid",以及 tokenHits / vectorHits 和每条结果的 vectorScore。查询为空时返回 400。
GET/api/v1/projects/{id}/graph?q=&nodeType=&limit=200来自 wiki/*.md 的 Wiki 链接图谱。上限限制为 1000。
POST/api/v1/projects/{id}/sources/rescan使用用户的 Source Watch 配置触发后端重新扫描。返回重新扫描后的队列以及实际发生变化的任务。
POST/api/v1/projects/{id}/chat501 — v1 中尚未实现。不要调用。

{id} 接受 UUID、绝对文件系统路径(URL 编码)或字面字符串 current。

错误处理

始终将状态码视为约定:

状态码含义处理方式
200正常额外检查 body.ok === true;载荷位于同一对象中。
400请求错误显示 body.error。常见原因:query 为空、?root= 无效、请求体过大。
401未授权Token 缺失或错误。告知用户在“设置 → API Server”中设置或重新生成 Token。
403禁止访问路径遍历或超出范围(例如 ../app-state.json)。不要使用相同路径重试。
404未找到未知项目 ID 或未知路由。遇到未知项目时,先列出项目以恢复操作。
405方法不允许HTTP 方法错误。
413载荷过大文件超过 2 MB、文件树超过 maxFiles,或请求体超过 1 MB。建议缩小范围。
415不支持的媒体类型文件内容为二进制或非 UTF-8。API 仅支持文本。
429请求过多触发速率限制(全局 120 req/sec)。至少等待 1 秒后再试。
500内部错误记录并报告;不要循环重试。
501尚未实现/chat 占位接口。不要重试。
503服务不可用有两种情况:API 已关闭(error 包含 "disabled");并发请求数已达上限(64)("busy")。至少等待 2 秒后再试。

如果 HTTP 调用本身失败(connection refused / ENOTFOUND):说明桌面应用未运行。告知用户:“启动 LLM Wiki,然后重试。”

使用规范

  • 引用路径。 使用 Wiki 内容回答时,注明页面:(from wiki/concepts/rope.md)。用户可以通过这些路径核实内容并在应用中跳转。
  • 默认只读。 只有 sources/rescan 会修改状态;其他操作都只读取数据。不要编造写入端点——v1 中不存在此类端点。
  • 除非用户要求,否则不要倾倒完整页面。 通常只需提供片段和路径。只有在推理确实需要时,才获取完整内容。
  • 遵守项目边界。 当前项目是用户的活动上下文。不要在不告知用户的情况下切换项目。
  • 遵守速率限制。 对于顺序操作,120 req/sec 绰绰有余,但并行读取页面可能会接近此限制。API 允许时应批量处理(搜索时设置 includeContent: true 可避免 N+1 次读取)。
  • 绝不泄露 Token。 请求头是安全的;查询参数和你输出的文本则不安全。

另请参阅

  • api-reference.md — 完整的端点结构及请求 / 响应示例
  • examples.md — 常见对话模式及其对应的直接 curl / fetch 调用序列
  • README.md — 面向用户的设置说明(Token 生成、端口冲突、故障排查)

评论

支持 Markdown