Install
openclaw skills install wiki-compiler知识库Wiki编译——将原始资料系统化组织为结构清晰的Wiki知识体系。当用户说"建知识库""整理资料库""编译知识库""搭建wiki""知识体系化""把资料整理成wiki",或上传了一批资料希望系统化组织时触发。不适用于单篇摘要、简单问答、或仅搜索已有知识库内容的场景。
openclaw skills install wiki-compiler核心理念:用 LLM 作为"知识编译器",将原始资料一次性编译为结构清晰、内部互联的 Wiki 知识库,而非依赖传统 RAG 的碎片检索拼凑。编译后的 Wiki 是"真理之源"——LLM 直接基于对 Wiki 整体结构的理解进行自检索和回答,知识在系统中持续累积和演化。
判断用户状态:
明确知识库边界:
收集原始资料("源代码"):
get_knowledge_list 逐级浏览并收集所有文件search(source="web") 补充关键资料,但需告知用户确认门: 向用户展示收集到的资料清单和知识库边界,确认后再进入编译。
重要:每次编译前必须检查是否已有该主题的知识导览,避免重复创建或丢失历史版本信息。
在目标文件夹中搜索标题包含"主题导览"的笔记:
curl -s -X POST "https://ima.qq.com/openapi/wiki/v1/get_knowledge_list" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d '{"knowledge_base_id": "<kb_id>", "limit": 50}' | \
python3 -c "import sys,json; data=json.load(sys.stdin); print([f['title'] for f in data.get('data',{}).get('knowledge_list',[])])"
如果找到"主题导览:xxx"笔记,记录其 note_id 和版本信息
如果没找到,则进入新建流程
| 情况 | 处理方式 |
|---|---|
| 已有该主题的旧版本导览 | 增量更新:读取旧版本内容 → 对比知识库增量 → 更新导览 |
| 已有其他主题的导览(非本主题) | 新建:按正常流程创建新导览 |
| 没有任何知识导览 | 新建:按正常流程创建新导览 |
当存在旧版本时,执行以下步骤:
export_note 获取旧版本完整内容重要:在编译导览笔记之前,必须先批量获取所有文件的链接特性,避免写完后发现无法链接导致返工。
获取文件夹中的所有文件,提取每个文件的 media_id、media_type、title:
curl -s -X POST "https://ima.qq.com/openapi/wiki/v1/get_knowledge_list" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d '{"knowledge_base_id": "<kb_id>", "limit": 50}' | \
python3 -c "import sys,json; data=json.load(sys.stdin); [print(f\"{f['media_id']}|{f['media_type']}|{f['title']}\") for f in data.get('data',{}).get('knowledge_list',[])]"
对每个文件调用 export_media_for_ima_sandbox:
curl -s -X POST "https://ima.qq.com/openapi/wiki/v1/export_media_for_ima_sandbox" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d '{"media_id": "<media_id>"}'
根据返回结果,建立如下表格:
| media_id | title | media_type | 链接策略 | URL/备注 |
|---|---|---|---|---|
| xxx | 文章A | 2 (网页) | ✅ 可内嵌 | https://... |
| xxx | 文章B | 6 (公众号) | ✅ 可内嵌 | https://... |
| xxx | 文章C | 7 (Markdown) | ⚠️ 不内嵌 | 请在知识库中查看 |
| xxx | 文章D | 11 (笔记) | ⚠️ 不内嵌 | 请在知识库中查看 |
编译导览笔记时,根据链接特性表选择正确的写法:
| 文件类型 | 编译写法 |
|---|---|
| type 2/6 | [标题](永久URL) |
| type 7/11 | 标题(纯文本,不加链接) |
| type 1/3/4/5 | 标题 — 请在知识库中查看 |
适用于:首次编译或结构重大调整
在阅读所有原始资料后,明确:
对每个核心概念,提取:
建立概念之间的连接:
将关系转化为:
适用于:知识库已有该主题旧版本导览,需要增量更新
# 导出旧版本笔记内容
curl -s -X POST "https://ima.qq.com/openapi/note/v1/export_note" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d '{"note_id":"<旧版note_id>","target_content_format":1}' | \
python3 -c "import sys,json,urllib.request; d=json.load(sys.stdin); url=d['data']['content_url']; req=urllib.request.Request(url); resp=urllib.request.urlopen(req); print(resp.read().decode('utf-8'))"
从标题下方的版本行提取:
**版本**:v1.0 | 创建于 2026-05-08 | 更新于 2026-05-08
**更新日志**:v1.0 - 初始版本
获取文件夹最新文件列表,与旧版本对比:
# 获取文件夹中的文件列表
curl -s -X POST "https://ima.qq.com/openapi/wiki/v1/get_knowledge_list" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d '{"knowledge_base_id": "<kb_id>", "limit": 50}' | \
python3 -c "import sys,json; data=json.load(sys.stdin); print([f['title'] for f in data.get('data',{}).get('knowledge_list',[])])"
| 类型 | 判断方式 | 更新方式 |
|---|---|---|
| 新增文章 | 旧版本中不存在 | 补充到对应核心概念的关键要素中 |
| 删除文章 | 旧版本提及但知识库中已不存在 | 从列表中移除 |
| 概念变化 | 知识库中出现新的核心概念分类 | 新增核心概念卡片 |
更新原则:
链接格式要求(必须严格遵守,引用格式:[《标题》](URL)):
[《标题》](路径)[《标题》](URL)---
version: 1.1 # patch+0.0.1 或 minor+0.1 或 major+1.0
created: 2026-05-08
updated: 2026-05-08
changelog:
- v1.1: 增量更新,补充了X篇新文章,更新了关键要素描述
- v1.0: 初始版本
---
版本号规则:
将生成的导览笔记内容通过 IMA OpenAPI 创建为笔记:
# 调用IMA OpenAPI创建笔记
curl -s -X POST "https://ima.qq.com/openapi/note/v1/import_doc" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d "{\"content_format\": 1, \"content\": $(python3 -c "import json; print(json.dumps(open('/sandbox/workspace/outputs/navigation_guide.md').read()))")}}"
返回处理:
result = {
"code": 0,
"data": {
"note_id": "新创建的note_id",
"note_title": "主题导览:XXX"
}
}
如果笔记创建在根目录,需要移动到导航文件夹:
# 1. 获取根目录笔记列表
curl -s -X POST "https://ima.qq.com/openapi/note/v1/list_note_by_folder_id" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d '{"folder_id": "", "limit": 50}' | \
python3 -c "import sys,json; data=json.load(sys.stdin); [print(f\"{n['title']}: {n['note_id']}\") for n in data.get('data',{}).get('note_list',[])]"
# 2. 笔记自动归入根目录(Skill 无 move_note 权限,无需移动操作)
# 通过 add_knowledge 导入知识库后,笔记可在对应文件夹中查看
模板来源:基于"交易策略与系统"主题导览的专业实践版本
# 主题导览:[主题名称]
**版本**:v1.0 | 创建于 YYYY-MM-DD | 更新于 YYYY-MM-DD
**更新日志**:v1.0 - 初始版本,基于知识库资料编译
## 一、主题定位
(主题定义 + 解决问题 + 核心逻辑 + 依赖链条)
本主题是XX的XX层,位于XX与XX之间。它解决的核心问题是:如何XX。
本主题涵盖XX、XX、XX三个关键环节,是XX的桥梁。其核心逻辑遵循清晰的依赖链条:XX → XX → XX → XX。
## 二、核心概念与关键要素
### (一)[核心概念A]
**核心思想**:一句话概括该概念的本质。
**关键要素**:
• 要素1:详细说明。相关文章[《文章标题》](链接)指出,具体内容...
• 要素2:详细说明。相关文章[《文章标题》](链接)进一步说明...
• 要素3:详细说明。
**实践建议**:
• 建议1:具体可操作的实践指导
• 建议2:具体可操作的实践指导
### (二)[核心概念B]
(同上结构)
## 三、学习路径(融合知识网络)
(以下学习路径以主线展示知识网络的连接关系,每个步骤标注了所需的核心知识储备和与之相关的概念。可根据主题实际需要设置1-N条路径,不必固定为两条)
(如有多条路径,在此展示)
## 四、相关主题
以下主题与"本主题名称"紧密关联,构成了更宽广的知识网络:
| 相关主题 | 与本主题的关系 | 关键连接点 |
|---------|--------------|-----------|
| XX | XX | XX |
| XX | XX | XX |
| 章节 | 内容详略 | 内容要求 | 写作要点 |
|---|---|---|---|
| 一、主题定位 | 略写 一段话(约100字) | 定义 + 解决问题 + 核心逻辑 + 依赖链条 | 用"是...的XX层,位于XX与XX之间"句式;依赖链条用箭头链展示 |
| 二、核心概念与关键要素 | 详写 每概念约200-300字 | 核心思想 + 关键要素(引用文章) + 实践建议 | 每个关键要素都要引用知识库文章;实践建议要具体可操作 |
| 三、学习路径(融合知识网络) | 中等 表格+一段话 | 两条路径 + 表格形式 + 最终整合 | 表格内容精简,最终整合一段话点明闭环逻辑 |
| 四、相关主题 | 略写 表格形式 | 主题 + 关系 + 连接点 | 说明每个关联主题的具体连接点,无需展开 |
每个关键要素的写作采用以下结构:
• 要素名称:详细说明。相关文章[《文章标题》](链接)指出,具体内容...
• 要素名称:详细说明。相关文章[《文章标题》](链接)进一步说明...
要点:
[《标题》](链接) 格式,提供可点击的有效链接[《标题》](URL) 格式每个核心概念卡片末尾,用编号列表展示2-3条具体可操作的实践建议:
**实践建议**:
• 先有逻辑,后有回测:策略设计应先论证底层投资逻辑,回测只是验证工具,不能替代逻辑思考。
• 动态适应:策略参数需随市场环境变化而调整,融入宏观前瞻和状态感知可增强跨周期表现。
• 简单性优先:优先选择参数少、逻辑清晰的简单策略,减少过拟合风险。
要点:
表格列定义:
| 列名 | 内容 |
|---|---|
| 步骤 | 第X步:具体步骤名称 |
| 核心知识 | 需要掌握的核心概念 |
| 知识网络连接 | 与其他主题的关联(用→表示递进,用→ 需要表示依赖) |
最终整合:在表格后用一段话总结闭环流程。
版本信息格式(放在大标题后):
> **版本**:v1.0 | 创建于 YYYY-MM-DD | 更新于 YYYY-MM-DD
> **更新日志**:v1.0 - 初始版本,基于知识库资料编译
版本更新规则:
版本记录位置: 在笔记大标题下方用加粗行标注版本号、创建日期、更新日期和更新日志。
前置要求:链接处理必须在**第三步(预获取链接信息)**中完成,不得在编译阶段临时获取。
根据预获取阶段生成的链接特性表,选择正确的链接策略:
| media_type | 类型 | 链接策略 |
|---|---|---|
| 2 | 网页链接 | ✅ 获取真实URL,格式:[《标题》](URL) |
| 6 | 公众号文章 | ✅ 获取真实URL,格式:[《标题》](URL) |
| 7 | Markdown | ⚠️ 不内嵌链接,写为纯文本 |
| 11 | 笔记 | ⚠️ 不内嵌链接,写为纯文本 |
| 1 | ⚠️ 标注"请在知识库中查看" | |
| 3 | Word | ⚠️ 标注"请在知识库中查看" |
| 4 | PPT | ⚠️ 标注"请在知识库中查看" |
| 5 | Excel | ⚠️ 标注"请在知识库中查看" |
引用格式示例:
# 可链接的类型(type 2/6)
• 多维度指标体系:A股情绪温度计采集12个维度指标...[《A股情绪温度计》](https://...)详细阐述了...
# 不可直接链接的类型(type 7/11/1/3/4/5)
• 系统化执行:(请在知识库中查看)
curl -s -X POST "https://ima.qq.com/openapi/wiki/v1/export_media_for_ima_sandbox" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d '{"media_id": "<文件media_id>"}'
返回的 data.media_content_url_info.url 即为永久可跳转链接。
文章标题中可能含有干扰Markdown渲染的字符:
| → 替换为全角 | 或省略[ ] _ * → 需转义或省略导览笔记的文章列表必须从 get_knowledge_list 返回的实际文件生成,不能依赖本地缓存文件。
知识库需要"活"起来,而非一次性建好就搁置。
当用户说"检查知识库""知识库体检"时:
当用户说"补充知识库""更新知识库"时:
用户可基于 Wiki 生成各类产出(研究报告、总结、幻灯片大纲等),这些产出保存回笔记本后,实现知识的"增量训练"——系统持续演化,而非一次性消耗。
curl -s -X POST "https://ima.qq.com/openapi/wiki/v1/get_knowledge_list" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d '{"knowledge_base_id": "<kb_id>", "limit": 50}'
curl -s -X POST "https://ima.qq.com/openapi/note/v1/export_note" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d '{"note_id":"<note_id>","target_content_format":1}' | python3 -c "
import sys,json,urllib.request
d=json.load(sys.stdin)
if d['code']==0:
url=d['data']['content_url']
req=urllib.request.Request(url)
resp=urllib.request.urlopen(req)
print(resp.read().decode('utf-8'))
else:
print(d)
"
import json
with open('guide_content.md', 'r') as f:
content = f.read()
with open('note_request.json', 'w') as f:
json.dump({
'content_format': 1,
'content': content,
'title': '📖 主题导览:[主题名称]'
}, f, ensure_ascii=False, indent=2)
curl -s -X POST "https://ima.qq.com/openapi/note/v1/import_doc" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d @note_request.json | python3 -m json.tool
# 返回: {"code": 0, "data": {"note_id": "xxx"}}
# 列出笔记本
curl -s -X POST "https://ima.qq.com/openapi/note/v1/list_notebooks" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" | python3 -m json.tool
# 创建笔记本
curl -s -X POST "https://ima.qq.com/openapi/note/v1/create_notebook" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d '{"name": "知识导览"}' | python3 -m json.tool
# 获取目标文件夹中的笔记列表
curl -s -X POST "https://ima.qq.com/openapi/note/v1/list_note_by_folder_id" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d '{"folder_id": "<文件夹ID>", "limit": 50}' | python3 -c "
import sys,json
d=json.load(sys.stdin)
for note in d.get('data',{}).get('note_list',[]):
if '主题导览' in note.get('title',''):
print(f\"Found: {note['title']} -> note_id: {note['note_id']}\")
"
# 获取旧笔记内容
curl -s -X POST "https://ima.qq.com/openapi/note/v1/export_note" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d '{"note_id":"<旧note_id>","target_content_format":1}' | python3 -c "
import sys,json,urllib.request
d=json.load(sys.stdin)
if d['code']==0:
url=d['data']['content_url']
req=urllib.request.Request(url)
resp=urllib.request.urlopen(req)
print(resp.read().decode('utf-8'))
"
# 增量更新旧笔记(推荐方式,保留原note_id和历史)
curl -s -X POST "https://ima.qq.com/openapi/note/v1/update_note" \
-H "ima-openapi-clientid: $IMA_OPENAPI_CLIENTID" \
-H "ima-openapi-apikey: $IMA_OPENAPI_APIKEY" \
-H "Content-Type: application/json" \
-d "{\"note_id\": \"<旧note_id>\", \"content_format\": 1, \"content\": $(python3 -c "import json; print(json.dumps(open('/sandbox/workspace/outputs/navigation_guide.md').read()))")}" | python3 -m json.tool
# 必需的环境变量
IMA_OPENAPI_CLIENTID=你的ClientID
IMA_OPENAPI_APIKEY=你的APIKey
# 或使用配置文件
mkdir -p ~/.config/ima
echo "你的ClientID" > ~/.config/ima/client_id
echo "你的APIKey" > ~/.config/ima/api_key
chmod 600 ~/.config/ima/*
import urllib.request
import json
def ima_api(path, data=None):
"""IMA OpenAPI 通用调用函数"""
headers = {
"ima-openapi-clientid": "你的ClientID",
"ima-openapi-apikey": "你的APIKey",
"Content-Type": "application/json"
}
url = f"https://ima.qq.com/{path}"
req = urllib.request.Request(
url,
data=json.dumps(data or {}).encode('utf-8'),
headers=headers,
method="POST"
)
with urllib.request.urlopen(req, timeout=15) as resp:
return json.loads(resp.read().decode('utf-8'))
| 功能 | 端点 | 关键参数 |
|---|---|---|
| 获取知识库列表 | openapi/wiki/v1/get_knowledge_list | knowledge_base_id, limit |
| 搜索知识库 | openapi/wiki/v1/search_knowledge_base | query, cursor, limit |
| 获取笔记列表 | openapi/note/v1/list_note_by_folder_id | cursor, limit |
| 搜索笔记 | openapi/note/v1/search_note | query_info |
| 创建笔记 | openapi/note/v1/import_doc | content_format, content |
| 获取媒体信息 | openapi/wiki/v1/get_media_info | media_id, knowledge_base_id |
result = ima_api("openapi/wiki/v1/get_knowledge_list", {
"knowledge_base_id": "你的知识库ID",
"limit": 50
})
for item in result.get('data', {}).get('knowledge_list', []):
print(f"[{item.get('media_type')}] {item.get('title')}")
result = ima_api("openapi/wiki/v1/search_knowledge_base", {
"query": "关键词",
"cursor": "",
"limit": 20
})
result = ima_api("openapi/note/v1/import_doc", {
"content_format": 1,
"content": "# 标题\n\n正文内容"
})
note_id = result.get('data', {}).get('note_id')
| code | 说明 |
|---|---|
| 0 | 成功 |
| 51 | 参数错误(如 limit 超出范围) |
| 220004 | 无效的 knowledge_base_id |
| 404 | API 端点不存在 |