关于 llm-wiki
llm-wiki 是用于通过本地 HTTP API 查询 LLM Wiki 的技能,面向需要从个人知识库检索和读取内容的 Agent。它涵盖项目选择、搜索、页面读取、图谱查询和来源重扫,并强调项目边界与令牌安全。
主要功能
- 01通过本地 HTTP API 访问
- 02搜索并读取 Wiki 页面
- 03查询 Wikilinks 图谱
- 04重扫来源文件
- 05支持多项目解析
适用场景
- 01查询 Wiki 中的主题资料
- 02读取指定页面并引用路径
- 03查看 Wiki 图谱结构
- 04为新增来源触发重扫
MCP 相关
此技能未说明与 MCP 的关系。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nashsu/ llm_wiki_skill --skill llm-wiki安装后在 Claude Code 中输入/llm-wiki确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdexamples.mdapi-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 使用。令牌来源为以下之一:
LLM_WIKI_API_TOKEN环境变量(如果已设置,则优先于 UI 设置)- 用户通过 Settings → API Server 保存的
apiConfig.token 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 里查一下”时:
- 解析项目(见下文项目解析)。
- 搜索:使用
{ query, topK: 5..10 }调用POST /api/v1/projects/{id}/search→ 返回按相关性排序的结果(path、title、snippet、score、titleMatch,以及可选的vectorScore、images)。检查response.mode,以确定是否启用了混合检索。 - 阅读靠前的结果:对每个有用的结果,调用
GET /api/v1/projects/{id}/files/content?path=...获取完整 Markdown 内容。也可以在搜索请求中传入includeContent: true,以免再次发起请求。 - 引用并回答:基于阅读过的页面综合回答。引用你使用的每个页面的
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}/chat | 501 — 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 生成、端口冲突、故障排查)