Skip to main content
ClaudeWave
ES, Spanish
Skill2.4k estrellas del repoactualizado 12d ago

knowledge-base

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/UnicomAI/wanwu /tmp/knowledge-base && cp -r /tmp/knowledge-base/configs/microservice/bff-service/configs/agent-skills/clawhub/ima-skills/knowledge-base ~/.claude/skills/knowledge-base
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

# Knowledge Base (知识库)

API base path: `openapi/wiki/v1` — 完整数据结构和接口参数详见 `references/api.md`。

## 接口决策表

| 用户意图                                      | 调用接口                                                               | 关键参数                                                                                           |
| --------------------------------------------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| 上传文件到知识库                              | `check_repeated_names` → `create_media` → COS Upload → `add_knowledge` | `media_type`(按扩展名),`knowledge_base_id`,`file_name`,`file_size`                            |
| 上传文件到知识库的某个文件夹                  | 先定位文件夹 → 同上(`folder_id` 传入目标文件夹 ID)                   | 见「文件夹操作」章节                                                                               |
| 添加网页/微信文章到知识库                     | `import_urls`                                                          | `urls`(1-10 个),`knowledge_base_id`,可选 `folder_id`(省略则根目录)                           |
| 添加笔记到知识库                              | `add_knowledge`                                                        | `media_type=11`,`note_info.content_id=<note_id>`,`knowledge_base_id`                             |
| 添加 URL(文件型)到知识库                    | `check_repeated_names` → 下载文件 → 走"上传文件"流程                   | URL 指向 PDF/Word/PPT 等文件时,按文件方式处理                                                     |
| 检查文件名是否重复                            | `check_repeated_names`                                                 | `params[].name`,`params[].media_type`,`knowledge_base_id`,`folder_id`                           |
| 获取知识库信息                                | `get_knowledge_base`                                                   | `ids`(1-20 个,不重复)                                                                           |
| 浏览知识库内容列表 / 浏览文件夹               | `get_knowledge_list`                                                   | `knowledge_base_id`,`cursor`,`limit`(1~50),可选 `folder_id`                                     |
| 在知识库中搜索(含文件和文件夹)              | `search_knowledge`                                                     | `query`,`knowledge_base_id`,`cursor`                                                             |
| 按关键词查找知识库(用户知道名字但不知道 ID) | `search_knowledge_base`                                                | `query`,`cursor`,`limit`(1~20)                                                                   |
| 查看/了解自己有哪些知识库                     | `search_knowledge_base`(`query` 传空字符串)                          | `query: ""`,`cursor`,`limit`(1~20)                                                               |
| 添加内容但**未指定**目标知识库                | `get_addable_knowledge_base_list` → 展示列表让用户选择                 | `cursor`,`limit`(1~50)                                                                            |
| 查看原文、分析原文、导出原文                  | `get_media_info`                                                       | `media_id`;导出/下载时在 URL 后追加 `response-content-type` + `response-content-disposition` 参数 |

### `search_knowledge_base` vs `get_addable_knowledge_base_list`

| 场景                                             | 使用接口                                       | 原因                               |
| ------------------------------------------------ | ---------------------------------------------- | ---------------------------------- |
| 用户说了知识库名称(如"添加到产品文档库")       | `search_knowledge_base`                        | 按名称搜索,找到 ID 后继续操作     |
| 用户想浏览/了解某个知识库                        | `search_knowledge_base` → `get_knowledge_base` | 先搜到 ID,再获取详情              |
| 用户想查看自己有哪些知识库(无具体关键词)       | `search_knowledge_base`(`query: ""`)         | 空 query 返回用户的所有知识库列表  |
| 用户要添加内容但**没说添加到哪个知识库**         | `get_addable_knowledge_base_list`              | 列出有权限添加的知识库,让用户选择 |
| 用户说"添加到知识库"但上下文中无法确定哪个知识库 | `get_addable_knowledge_base_list`              | 同上,不要猜测,让用户选择         |

**绝不要**在用户已明确指定知识库名称时调用 `get_addable_knowledge_base_list`。

---

## 写入类工作流

### ⛔ 文件上传安全门(仅适用于文件上传 → `add_knowledge` 流程)

以下 4 条规则**仅**在上传文件到知识库时适用。搜索、浏览、获取信息等读取操作不受影响。

```
GATE 1 [TYPE CHECK]
  Run preflight-check.cjs FIRST. pass=false → reject immediately.
  NEVER ask "do you still want to try?" for unsupported types.
  Video files, Bilibili/YouTube URLs, file:// URLs → tell user to use IMA desktop client.

GATE 2 [NAMING]
  add_knowledge title MUST equal file_name (with extension).
  NEVER rename, shorten, translate, or modify the original filename.
  Example: file is "音频.mp3" → title="音频.mp3", file_name="音频.mp3"

GATE 3 [DUPLICATES]
  Call check_repeated_names BEFORE create_media for ALL file uploads.
  is_repeated=true → ask user: keep both (append timestamp) or cancel.
  "Replace" is NOT supported.
  Timestamp format: {name}_YYYYMMDDHHmmss.{ext}

GATE 4 [UPLOAD EXIT]
  cos-upload.cjs non-zero exit → STOP immediately.
  Do NOT call add_knowledge. Report error to user.
```

### 上传文件到知识库

完整流程:前置检查 → 重名检查 → 创建媒体 → COS 上传 → COS 验证 → 添加知识。

```bash
# ── Step 1: preflight-check.cjs ← ⛔ GATE 1 ──
# 有扩展名时自动推断;无扩展名时需传 --content-type
PREFLIGHT=$(node .claude/skills/ima-skill/knowledge-base/scripts/preflight-check.cjs \
  --file "/path/to/report.pdf")
echo "$PREFLIGHT"
# pass=false → 终止,将 reason 展示给用户。NEVER ask "want to try?"

# ── Step 2: Extract fields ──
FILE_NAME=$(echo "$PREFLIGHT" | node -e "const d=JSON.parse(require('fs').readFileSync(0,'utf8'));process.stdout.write(d.file_name)")
FILE_EXT=$(echo "$PREFLIGHT" | node -e "const d=JSON.parse(require('fs').readFileSync(0,'utf8'));process.stdout.write(d.file_ext)")
FILE_SIZE=$(echo "$PREFLIGHT" | node -e "const d=JSON.parse(require('fs').readFileSync(0,'utf8'));process.stdout.write(String(d.file_size))")
MEDIA_TYPE=$(echo "$PREFLIGHT" | node -e "const d=JSON.parse(require('fs').readFileSync(0,'utf8'));process.stdout.write(String(d.media_type))")
CONTENT_TYPE=$(echo "$PREFLIGHT" |