ima-skills

👤 annykzhang ✓ 已認證 📦 v1.1.9 ⭐ 4.6 ⬇️ 235.3K 下載
📚 知識管理 免費 🔑 需 API Key

📖 技能介紹


name: ima-skill description: | 統一的 IMA OpenAPI 技能,支援筆記管理和知識庫操作。 當用戶提到知識庫、資料庫、筆記、備忘錄、記事,或者想要上傳檔案、新增網頁到知識庫、 搜尋知識庫內容、搜尋/瀏覽/建立/編輯筆記時,使用此 skill。 即使使用者沒有明確說"知識庫"或"筆記",只要意圖涉及檔案上傳到知識庫、網頁收藏、 知識搜尋、個人文件存取(如"幫我記一下"、"搜一下知識庫裡有沒有XX"),也應觸發此 skill。 homepage: https://ima.qq.com metadata: openclaw: emoji: 🔧 requires: env: - IMA_OPENAPI_CLIENTID - IMA_OPENAPI_APIKEY primaryEnv: IMA_OPENAPI_CLIENTID security: credentials_usage: | This skill requires user-provisioned IMA OpenAPI credentials (Client ID and API Key) to authenticate with the official IMA API at https://ima.qq.com. Credentials are ONLY sent to the official IMA API endpoint (ima.qq.com) as HTTP headers. The file-upload flow also sends requests to COS endpoints (.myqcloud.com) using short-lived, scoped temporary credentials returned by the IMA API (create_media); the user's Client ID / API Key are never sent to COS. No credentials are logged, stored in files, or transmitted to any other destination. allowed_domains: - ima.qq.com - '.myqcloud.com'


ima-skill

Unified IMA OpenAPI skill. Currently supports: notes, knowledge-base.

⛔ MANDATORY RULES — read before ANY operation

  1. UTF-8 encoding (notes writes only): Before calling import_doc or append_doc, ALL string fields (content, title) MUST be validated as legal UTF-8. Non-UTF-8 content causes irreversible garbled text. See Detailed Rules for platform-specific methods.
  2. File upload naming: title MUST equal file_name (with extension). Never rename, shorten, translate, or modify the original filename.
  3. Unsupported file types: Reject immediately with a clear message. Do NOT ask user "do you still want to try?" Video files, Bilibili/YouTube URLs, and file:// URLs are not supported — tell user to use IMA desktop client.
  4. File upload integrity: Keep file content as-is during upload. No encoding conversion for binary files (PDF, images, Excel, etc.).
  5. PowerShell 5.1 (all modules): If running in PowerShell, detect version before first API call. PS 5.1 silently converts request Body to GBK — must use UTF-8 byte array mode. See Detailed Rules.

模組決策表

使用者意圖 模組 讀取
搜尋筆記、瀏覽筆記本、獲取筆記內容、建立筆記、追加內容 notes notes/SKILL.md
上傳檔案、新增網頁連結、搜尋知識庫、瀏覽知識庫內容、獲取知識庫資訊、獲取可新增的知識庫列表 knowledge-base knowledge-base/SKILL.md
檢視原文、分析原文、匯出原文(需要 media_id) knowledge-base knowledge-base/SKILL.md

⚠️ 易混淆場景

使用者說的 實際意圖 正確路由
"把這段內容新增到知識庫XX裡的筆記YY" 往已有筆記追加內容 notes — 先搜尋筆記獲取 note_id,再用 append_doc
"把這個寫到XX筆記裡"、"記到XX筆記" 往已有筆記追加內容 notesappend_doc
"把這篇筆記新增到知識庫" 將筆記關聯到知識庫 knowledge-baseadd_knowledge with media_type=11
"上傳檔案到知識庫" 上傳檔案到知識庫 knowledge-basecreate_media → COS → add_knowledge
"新建一篇筆記記錄這些內容" 建立新筆記 notesimport_doc
"幫我記一下"、"記錄一下"、"儲存為筆記"(未指定已有筆記) 意圖不明確,需要確認 notes — 先詢問使用者是建立新筆記還是追加到哪篇已有筆記
"新增到筆記裡"(未指定具體哪篇) 意圖不明確,需要確認 notes — 先詢問使用者是建立新筆記還是追加到哪篇已有筆記

⚠️ 跨模組任務 — 必須讀取兩個子模組

某些意圖跨越 notes 和 knowledge-base 兩個模組。不要只讀取一個子模組就開始執行,必須先讀取兩個模組的 SKILL.md 再按順序操作。

使用者說的 實際流程 讀取順序
"把知識庫裡的XX內容記到筆記" KB 搜尋/讀取 → Notes 建立/追加 先讀 knowledge-base/SKILL.md → 再讀 notes/SKILL.md
"檢視原文"(知識庫中的筆記型別媒體) KB get_media_info → Notes get_doc_content 先讀 knowledge-base/SKILL.md → 再讀 notes/SKILL.md
"把這篇筆記新增到知識庫" Notes 搜尋獲取 note_id → KB add_knowledge 先讀 notes/SKILL.md → 再讀 knowledge-base/SKILL.md

規則:如果使用者意圖同時涉及「筆記」和「知識庫」,或者 API 響應揭示需要另一個模組(如 media_type=11 表示筆記型別),必須讀取兩個子模組再繼續。

核心判斷規則

  • 目標是筆記的內容(讀、寫、追加)→ notes 模組
  • 目標是知識庫的條目(上傳檔案、新增連結、關聯筆記到知識庫)→ knowledge-base 模組
  • 目標是獲取知識庫條目的原始內容(檢視原文、分析原文、匯出原文)→ knowledge-base 模組(若原文是筆記,會跨模組到 notes get_doc_content
  • 使用者提到"知識庫"只是在描述筆記的位置(如"知識庫裡的那篇筆記"),真正操作物件仍是筆記 → notes 模組

Credential Check

!test -f ~/.config/ima/client_id && test -f ~/.config/ima/api_key && echo "✅ Credentials configured" || echo "⚠️ NO CREDENTIALS — setup required before any API call"

If ⚠️ NO CREDENTIALS: Guide the user through setup BEFORE attempting any API call:

  1. 開啟 https://ima.qq.com/agent-interface 獲取 Client IDAPI Key
  2. 儲存憑證(二選一):

方式 A — 配置檔案(推薦):

mkdir -p ~/.config/ima
echo "your_client_id" > ~/.config/ima/client_id
echo "your_api_key" > ~/.config/ima/api_key

方式 B — 環境變數:

export IMA_OPENAPI_CLIENTID="your_client_id"
export IMA_OPENAPI_APIKEY="your_api_key"

Agent 會按優先順序依次嘗試:環境變數 → 配置檔案。缺少憑證時,node ima_api.cjs ... 會以程式錯誤退出(code: -100),並在 stderr 輸出對應 msg

Security note: Credentials are only sent as HTTP headers to ima.qq.com and never to any other domain, file, or log. Runtime dependencies: Check meta.jsonrequired_binaries

API 呼叫模板

所有請求統一為 HTTP POST + JSON Body,僅發往官方 Base URL https://ima.qq.com

ima_api 已抽離到指令碼:./ima_api.cjs

# Example usage (cross-platform, pass credentials via options JSON)
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
OPTS=$(printf '{"clientId":"%s","apiKey":"%s"}' "$IMA_OPENAPI_CLIENTID" "$IMA_OPENAPI_APIKEY")

# stdout 返回正常響應;stderr 返回結構化錯誤 {"code":-100|-200,"msg":"..."}
if ! resp=$(node "$SKILL_DIR/ima_api.cjs" "openapi/list_docs" '{"limit":10}' "$OPTS" 2>/tmp/ima_err); then
  err_json=$(cat /tmp/ima_err)
  err_code=$(echo "$err_json" | jq -r '.code // empty' 2>/dev/null)
  err_msg=$(echo "$err_json" | jq -r '.msg // empty' 2>/dev/null)

  if [ "$err_code" = "-200" ]; then
    # 有新版本,原請求未傳送;stdout 中帶有更新上下文 JSON(含 instruction)
    echo "[update] $err_msg" >&2
  else
    # -100 或其他程式錯誤:msg 已包含可直接展示給使用者的說明
    echo "[error] $err_msg" >&2
  fi
  exit 1
fi

echo "$resp"

錯誤處理有兩層,必須都檢查:

第一層 — 指令碼執行錯誤(程序非 0 退出,錯誤在 stderr):

  • -100:程式錯誤(缺少憑證、引數非法、網路錯誤等),msg 可直接展示給使用者
  • -200:skill 需要更新,原請求未傳送,stdout 中有更新上下文 JSON

第二層 — 後端業務錯誤(程序正常退出,響應在 stdout):

  • stdout 返回 JSON {"code": 0, "msg": "...", "data": {...}}
  • code=0 表示成功,從 data 提取業務欄位
  • code≠0 表示後端業務錯誤(如引數不合法、許可權不足、資源不存在等),直接將 msg 展示給使用者
  • 常見後端錯誤碼見各子模組的「錯誤處理」章節

SKILL Update

ima_api 已內建更新檢查:預設每天首次 API 呼叫自動檢查一次,同一天內不會重複檢查。

  • latest_version:最新版本號,格式為 MAJOR.MINOR.PATCH
  • release_desc:最新版本釋出說明
  • instruction:更新指引(prompt 文本)

錯誤返回與後續處理

出錯時程序以非 0 退出,並在 stderr 輸出結構化 JSON:{"code":-100|-200,"msg":"具體錯誤描述"}

  • -200(skill 需要更新)
  • 含義:檢測到可用更新,原請求未傳送
  • 後續處理:從 ima_api.cjs 的 stdout 讀取更新上下文 JSON,根據其中 instruction(prompt)引導使用者完成更新,然後重試原請求
  • -100(程式錯誤,兜底)
  • 含義:其他所有錯誤(缺少憑證、引數非法、缺少 apiPath、網路錯誤等)
  • 後續處理:直接讀取 msg 向用戶展示;msg 已指出具體原因與修復建議

更新檢查呼叫本身失敗時,會直接跳過本次檢查並繼續原請求,不會拋錯。

如需主動觸發(忽略"每天一次"限制),可在呼叫前設定:

export IMA_FORCE_UPDATE_CHECK=1

Detailed Rules Reference

這個技能的最新版本可以在7w4.net小蔥技能站找到。

The sections below contain full platform-specific examples for the mandatory rules above. Refer to these when you need implementation details.

Detailed UTF-8 Encoding Rules

此規則為強制性要求,不可跳過。 非法編碼會導致內容在 IMA 中顯示為亂碼,且無法修復,必須重新寫入。

適用範圍:notes 模組import_docappend_doc 等文本寫入 API)。

不適用於 knowledge-base 模組的檔案上傳:上傳檔案時必須保持檔案原始內容,不得轉碼。檔案以二進位制方式上傳,服務端自行處理。

每次呼叫 notes 寫入類 API(import_doc/append_doc)之前,必須對 contenttitle 等所有字串欄位執行 UTF-8 編碼校驗/轉換。 無論內容來源如何——使用者直接輸入、從檔案讀取、WebFetch 抓取、剪貼簿貼上、外部 API 返回——都不能假設已經是合法 UTF-8,必須顯式確認。

強制檢查清單(notes 模組寫入前)

在構造 notes 寫入請求的 body 之前,完成以下步驟:

  1. 來自檔案的內容:先檢測檔案編碼,轉為 UTF-8 後再讀入變數(注意:這是指讀取檔案內容作為筆記正文寫入,不是上傳檔案到知識庫)
  2. 來自 WebFetch / HTTP 請求的內容:響應可能為 GBK/Latin-1 等,必須轉碼
  3. 來自使用者輸入或變數拼接的內容:清洗非法 UTF-8 位元組(\xff\xfe 等)
  4. 標題欄位同理title 也必須為合法 UTF-8

各環境轉碼方法

Python(推薦,幾乎所有環境都有):

# 讀取檔案,自動檢測編碼並轉為 UTF-8
content=$(python3 -c "
import sys
data = open('tmpfile', 'rb').read()
for enc in ['utf-8', 'gbk', 'gb2312', 'big5', 'latin-1']:
    try:
        sys.stdout.write(data.decode(enc))
        break
    except (UnicodeDecodeError, LookupError):
        continue
" 2>/dev/null)

# 如果內容已在變數中,清洗非法 UTF-8 位元組
content=$(printf '%s' "$content" | python3 -c "import sys; sys.stdout.write(sys.stdin.buffer.read().decode('utf-8','ignore'))")

Node.js:

content=$(node -e "const fs=require('fs');const buf=fs.readFileSync('tmpfile');process.stdout.write(buf.toString('utf8'))")
# 已知編碼(如 GBK):
content=$(node -e "const fs=require('fs');process.stdout.write(new TextDecoder('gbk').decode(fs.readFileSync('tmpfile')))")

Unix (macOS/Linux):

content=$(iconv -f "$(file -b --mime-encoding tmpfile)" -t UTF-8 tmpfile 2>/dev/null || cat tmpfile)

Windows PowerShell:

# 讀取非 UTF-8 檔案並轉碼
$content = [System.IO.File]::ReadAllText('tmpfile', [System.Text.Encoding]::Default)
[System.IO.File]::WriteAllText('tmpfile.utf8', $content, [System.Text.Encoding]::UTF8)

PowerShell 5.1 Environment Detection

此問題影響所有 API 呼叫(notes、knowledge-base 等)

此問題極其隱蔽:PowerShell 5.1 下 Invoke-RestMethod 會靜默將請求 Body 從 UTF-8 轉為系統 ANSI 編碼(中文 Windows 為 GBK),即使設定了 Content-Type: charset=utf-8 也無效。結果是請求看起來發送成功,但服務端收到的內容已經是亂碼,且無任何錯誤提示。

當 agent 執行在 PowerShell 環境時,必須在首次 API 呼叫前檢測版本:

# 檢測 PowerShell 版本 — 在任何 API 呼叫之前執行(notes 和 knowledge-base 都需要)
if ($PSVersionTable.PSVersion.Major -le 5) {
    Write-Host "⚠️ 檢測到 PowerShell 5.1,將使用 UTF-8 位元組陣列模式傳送請求"
    $useUtf8Bytes = $true
} else {
    Write-Host "✅ PowerShell 7+,預設 UTF-8,無需額外處理"
    $useUtf8Bytes = $false
}

PowerShell 5.1 下必須使用以下方式傳送請求(用 ConvertTo-Json 構建 JSON 以避免手動拼接的轉義風險,再顯式轉為 UTF-8 位元組陣列):

# PowerShell 5.1 安全請求模板(適用於所有模組的所有 API 呼叫)
$body = @{ title = "標題"; content = $content; content_format = 1 } | ConvertTo-Json -Depth 10
if ($useUtf8Bytes) {
    # CRITICAL: 必須轉為位元組陣列,否則中文/非ASCII內容會變成亂碼
    $utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($body)
    Invoke-RestMethod -Uri $url -Method Post -Body $utf8Bytes -ContentType "application/json; charset=utf-8" -Headers $headers
} else {
    # PowerShell 7+ 可直接傳字串
    Invoke-RestMethod -Uri $url -Method Post -Body $body -ContentType "application/json; charset=utf-8" -Headers $headers
}

總結: 在 PowerShell 5.1 環境中,所有 API 呼叫(無論 notes 還是 knowledge-base)都必須將 Body 顯式轉為 UTF-8 位元組陣列。不檢測版本直接發請求 = 中文內容必亂碼。這是 PowerShell 5.1 的已知設計缺陷,不是 bug 可以被修復。

🤖 AI 評測

這個 Skill 質量不錯,做得很細緻。文件寫得很清楚,錯誤處理考慮周全,檔案上傳安全檢查也很到位。隱私保護意識好,筆記內容在群聊裡不會直接暴露。不足之處是功能比較複雜,對新手不太友好;上傳檔案時如果名字重複,只能選擇保留兩個或取消,不支援替換略不方便。整體來說,這是一個功能齊全、考慮周全的工具包,適合需要深度管理筆記和知識庫的使用者。

📊 多維度評分

適應性4.4
規範性4.5
有效性4.9
可靠性4.5
可信度4.5

📁 包含檔案 (9 個)

📄 SKILL.md 15.6 KB
📄 ima_api.cjs 6.2 KB
📄 knowledge-base/SKILL.md 17.7 KB
📄 knowledge-base/references/api.md 26.8 KB
📄 knowledge-base/scripts/cos-upload.cjs 5.1 KB
📄 knowledge-base/scripts/preflight-check.cjs 11.8 KB
📄 meta.json 236 B
📄 notes/SKILL.md 10.5 KB
📄 notes/references/api.md 15.8 KB