内容转存到 ima 知识库
目的
当用户发来微信公众号文章,或通过触发词附带文案/文章时,自动转存到 ima 个人知识库「琪儒的知识库」。支持一次发送多个链接批量转存。
⚠️ 能力边界
| 能力 | 状态 | 说明 |
|---|---|---|
| 转存公众号文章到知识库 | ✅ | 通过 ima OpenAPI import_urls 实现 |
| 转存文本/文案到知识库 | ✅ | 生成本地 md 文件 → 文件上传流程 → 入库 → 删本地文件 |
| 批量转存(链接) | ✅ | import_urls 单次 1-10 个 URL,超过自动分批 |
| 跨用户兼容 | ✅ | 凭证和目标知识库均不硬编码在 Skill 中,分享安全 |
| 自动打标签 | ❌ | ima OpenAPI 无此接口,已移除 |
支持的输入类型
| 类型 | 识别方式 | 处理方式 |
|---|---|---|
| 微信公众号文章 | mp.weixin.qq.com/s/... 或 mp.weixin.qq.com/s?... 链接 |
import_urls |
| 文本/文案 | 触发词 + 非链接内容 | 生成本地 md → 文件上传(media_type=7)→ 删本地 |
> 其他链接类型(腾讯元宝 yb.tencent.com、Bilibili、YouTube、file:// 等)不支持。元宝链接虽能转存成功,但 ima 端无法打开,已移除支持。
⚙️ 首次配置(安装后必做)
> 本 Skill 不内置任何人的 ima 凭证或知识库信息。 以下是每人安装后需自行完成的配置。完成后下次触发即自动生效。
1. 安装 ima-skills 技能包
ima-skills 提供底层调用 ima OpenAPI 的能力。本 Skill 依赖它。
- 在 WorkBuddy 中搜索安装"腾讯ima"或
ima-skills技能包。 - 安装后确保
~/.workbuddy/skills/skill_2053082144792322048/目录存在(含ima_api.cjs和knowledge-base/子模块)。
2. 获取并配置 ima OpenAPI 凭证
- 访问 https://ima.qq.com/agent-interface 获取你的 Client ID 和 API Key。
- 以无尾随换行的方式写入两个文件:
bash printf '%s' "<你的Client ID>" > ~/.config/ima/client_id printf '%s' "<你的API Key>" > ~/.config/ima/api_key - ⚠️ 凭证是你的私人密钥,不要分享给任何人,也不要在 Skill 文件中硬编码。
3. 确认目标知识库
- 本 Skill 默认目标为「琪儒的知识库」。若你要存入别的知识库,在触发时说明目标名称即可。
- Skill 会通过
search_knowledge_base按名称动态查找知识库 ID,无需手动填 ID。
> 完成以上 3 步后,下次发送公众号文章链接或"存入ima"+文案即可自动转存。
目标知识库(动态查找)
本 Skill 不做知识库 ID 硬编码。由 agent 在每次触发时按名称动态查找,确保跨用户兼容。
查找流程:
1. 调用 ima_api "openapi/wiki/v1/search_knowledge_base" '{"query":"琪儒的知识库","cursor":"","limit":5}'。
2. 若命中:取 info_list[0].kb_id 作为 knowledge_base_id;再调 get_knowledge_list 取 current_path[0].folder_id 作为根目录 folder_id。
3. 若未命中:告知用户"未找到知识库「琪儒的知识库」,请确认名称或手动指定"。
> 参考值(此用户实测,不可硬编码到 Skill 中):
> - 琪儒的知识库 OpenAPI kb_id: $KB_ID
> - 根目录 folder_id: 0019dee139c03ad3
> - ⚠️ 这仅用于理解双 ID 体系的存在——不同用户的 kb_id 肯定不同,不要直接填入请求。
>
> 双 ID 体系(ima 的不兼容设计):MCP 连接器的 knowledge_base_id 与 OpenAPI 的 kb_id 互不通用。OpenAPI 写入用 search_knowledge_base 返回的 kb_id。
依赖
- ima-skills 技能(
~/.workbuddy/skills/skill_2053082144792322048/):提供 ima OpenAPI 底层调用。需在 WorkBuddy 中安装"腾讯ima"技能包。 - knowledge-base 子模块:
import_urls、add_knowledge、create_media、check_repeated_names - knowledge-base 脚本:
scripts/preflight-check.cjs、scripts/cos-upload.cjs - ima 凭证:需用户自行配置在
~/.config/ima/client_id与~/.config/ima/api_key(从 https://ima.qq.com/agent-interface 获取)。凭证是用户私有的,不在 Skill 中,不随分享泄露。
触发条件
满足任一即触发:
1. 用户消息包含 mp.weixin.qq.com/s 链接;
2. 用户发送微信公众号文章卡片,且可解析出上述链接;
3. 用户消息包含触发词("转存ima""存入ima""存到ima""保存到ima""存进ima"等,大小写不敏感),且附带非链接的结构性文案或文章内容。
> 若消息同时包含链接和触发词,优先按链接走模式 A。
工作流
步骤 0 — 前置检查(每次触发必做)
每次触发时,在进入模式 A 或 B 之前,先完成以下检查:
0-1. 凭证检查
test -f ~/.config/ima/client_id && test -f ~/.config/ima/api_key
若任一文件不存在:
> "本 Skill 需要你的 ima OpenAPI 凭证。请访问 https://ima.qq.com/agent-interface 获取 Client ID 和 API Key,然后运行以下命令配置:<br>
> printf '%s' '<你的Client ID>' > ~/.config/ima/client_id<br>
> printf '%s' '<你的API Key>' > ~/.config/ima/api_key<br>
> 配置完成后重新发送即可。"
0-2. ima-skills 技能检查
确认 ~/.workbuddy/skills/skill_2053082144792322048/ima_api.cjs 存在。若不存在:提示用户在 WorkBuddy 中安装"腾讯ima"或 ima-skills 技能包。
0-3. 获取目标知识库 ID
按名称动态查找(不要硬编码任何人的 ID):
# 在目标知识库章节中查找
ima_api "openapi/wiki/v1/search_knowledge_base" '{"query":"琪儒的知识库","cursor":"","limit":5}'
# 取 info_list[0].kb_id → 作为 $KB_ID
# 再调 get_knowledge_list 取 current_path[0].folder_id → 作为 $FOLDER_ID
若用户明确指定了其他知识库名称,用用户指定的名称搜索。若未命中:提示用户确认名称。
0-4. 凭证有效性验证(可选,保守场景)
若这是首次使用或上次验证较久,可调 search_knowledge_base 确认凭证有效。若返回 code=200002(skill auth failed),引导用户刷新凭证。
> 以上检查完成后,$KB_ID 和 $FOLDER_ID 已就绪,进入对应模式。
模式 A — 公众号文章转存(URL 输入)
A-1. 提取并分组 URL
从用户消息中提取所有 mp.weixin.qq.com/s/... 或 mp.weixin.qq.com/s?... 链接。
- 批量分组:
import_urls单次最多 10 个 URL。若提取到 N 个链接,按 10 个一组分批;多批依次调用。 - 若用户发的是卡片且无明文 URL:请用户提供链接后再继续,不要臆造。
- 若链接不是
mp.weixin.qq.com/s域名:告知用户本 skill 仅处理微信公众号文章。
A-2. 批量转存到知识库
加载 ima-skills 技能(knowledge-base 子模块),对每批(≤10 个 URL)调用 import_urls:
{
"knowledge_base_id": "$KB_ID",
"folder_id": "$FOLDER_ID",
"urls": ["<URL1>", "<URL2>", "..."]
}
错误处理:
- 返回 code=200002(skill auth failed):停止转存,提示用户到 https://ima.qq.com/agent-interface 重新获取 Client ID 和 API Key,更新 ~/.config/ima/client_id 与 ~/.config/ima/api_key 后重试。
- 检查 data.results 中每个 URL 的 ret_code:0=成功(记录返回的 media_id 与对应 URL);非 0=失败,记录该 URL 及 msg。
- 重复导入(文章已存在)按后端返回处理,不视为错误。
- 汇总每批结果,全部批次完成后统一输出。
模式 B — 文本/文案转存(触发词 + 文本输入)
> 不走 notes 模块的 import_doc(会在笔记库留副本,删笔记会影响知识库)。改为生成本地 md 文件 → 文件上传到知识库 → 删除本地文件,只在知识库留一份。
B-1. 识别触发词与提取内容
检测用户消息是否包含触发词("转存ima""存入ima""存到ima""保存到ima""存进ima"等,大小写不敏感,"ima"也可写作"IMA")。
- 若消息同时包含
mp.weixin.qq.com/s链接:走模式 A(链接优先)。 - 若是纯文本/文案内容:
- 提取标题:若内容以 Markdown
#开头,取该行(去掉#)作标题;若用户明确标注"标题:XXX"或"【XXX】",取之;否则取正文前 30 字符作标题。 - 提取正文:完整文本内容作为 md 文件内容(Markdown 格式)。
B-2. 生成本地 md 文件
- 清洗标题作为文件名:将标题中的非法字符(
\ / : * ? " < > |)替换为_,追加.md扩展名。文件名直接用清洗后的标题(如产品核心功能.md),不要加.tmp_前缀——因为 ima 的add_knowledge的 title 必须等于 file_name(GATE 2),前缀会污染知识库里的显示标题。 - 写入临时文件:用 Write 工具将正文写入项目目录下,文件名即清洗后的标题。文件用完即删(B-4 步骤),覆盖风险可忽略;若担心覆盖,可写入系统临时目录(如
/tmp或%TEMP%),但 file_name 仍用清洗后的标题。
B-3. 上传到知识库(文件上传流程)
通过 ima-skills 技能的 ima_api 和脚本完成,共 5 步:
步骤 1 — preflight-check.cjs(⛔ GATE 1:类型检测):
PREFLIGHT=$(node <skill_dir>/knowledge-base/scripts/preflight-check.cjs --file "<临时md路径>")
# pass=false → 终止。预期 media_type=7, content_type=text/markdown
从返回 JSON 提取:file_name、file_ext、file_size、media_type、content_type。
步骤 2 — check_repeated_names(⛔ GATE 3:重名检查):
ima_api "openapi/wiki/v1/check_repeated_names" '{
"params": [{"name": "<file_name>", "media_type": 7}],
"knowledge_base_id": "$KB_ID"
}'
# is_repeated=true → 询问用户:保留两者(追加 _YYYYMMDDHHmmss)或取消
步骤 3 — create_media(获取 COS 上传凭证):
ima_api "openapi/wiki/v1/create_media" '{
"file_name": "<file_name>",
"file_size": <file_size>,
"content_type": "text/markdown",
"knowledge_base_id": "$KB_ID",
"file_ext": "md"
}'
# 返回 media_id 和 cos_credential
步骤 4 — cos-upload.cjs(⛔ GATE 4:上传到 COS):
node <skill_dir>/knowledge-base/scripts/cos-upload.cjs \
--file "<临时md路径>" \
--secret-id "<cos_credential.secret_id>" \
--secret-key "<cos_credential.secret_key>" \
--token "<cos_credential.token>" \
--bucket "<cos_credential.bucket_name>" \
--region "<cos_credential.region>" \
--cos-key "<cos_credential.cos_key>" \
--content-type "text/markdown" \
--start-time "<cos_credential.start_time>" \
--expired-time "<cos_credential.expired_time>"
# ⛔ 非零退出 → 终止,不继续 add_knowledge
步骤 5 — add_knowledge(⛔ GATE 2:title = file_name):
ima_api "openapi/wiki/v1/add_knowledge" '{
"media_type": 7,
"media_id": "<media_id>",
"title": "<file_name>",
"knowledge_base_id": "$KB_ID",
"file_info": {
"cos_key": "<cos_credential.cos_key>",
"file_size": <file_size>,
"file_name": "<file_name>"
}
}'
B-4. 清理本地临时文件
上传成功后(步骤 5 返回 code=0),立即删除本地临时 md 文件。上传失败也要删除(避免残留)。
错误处理:
- 任意步骤 code≠0:展示 msg,终止后续步骤,删除本地临时文件。
- cos-upload 非零退出:不执行 add_knowledge,删除本地临时文件,报告错误。
- 批量文本转存时,逐条执行(每条独立的 md 生成 → 上传 → 删除),汇总结果。
输出结果
单条:
✅ 已转存到「琪儒的知识库」
标题:<标题>
类型:公众号文章 / Markdown文档
批量(≥2 条):
✅ 已批量转存到「琪儒的知识库」(共 N 条)
1. <标题1> [公众号文章]
2. <标题2> [Markdown文档]
3. <标题3> [❌ 失败:<msg>]
转存全部失败时:展示错误 msg 与修复建议(如凭证失效→引导刷新;URL 非法→请用户确认链接)。
注意事项
- 所有 ima 内部 ID(
knowledge_base_id、media_id、folder_id、note_id)不得向用户展示,用知识库名称/文件标题等表述。 - 凭证(Client ID / API Key 文件内容)在任何情况下都不得向用户展示或写入 Skill 文件。
$KB_ID和$FOLDER_ID来自步骤 0-3 动态查找,禁止在 Skill 或执行中硬编码。- 一次消息含多个链接时,按 10 个一组分批转存,全部完成后统一汇报。
- 模式 B 不走 notes 模块(不建笔记),避免笔记库被污染。
- 模式 B 的本地临时 md 文件无论成功失败都要删除,不留残文件。
- md 文件内容仅支持 Markdown 文本,不支持本地图片。若用户文本中包含本地图片路径(
file:///、C:\...等),移除这些引用并告知用户。 - 按后端返回的
msg实际处理错误,不做预判。