> For the complete documentation index, see [llms.txt](https://docs.maiagent.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.maiagent.ai/tech/api-integration/knowledge-base-api.md).

# 使用知識庫—上傳、搜尋與管理

用 API 上傳檔案到知識庫、以自然語言搜尋（檢索）知識庫內容並取回相關片段，以及管理知識庫檔案；附「上傳、等待解析、搜尋」的完整範例。

## 概述 <a href="#overview" id="overview"></a>

MaiAgent 提供開發者透過 API 管理知識庫檔案的能力。開發者可以在工作區內對知識庫進行以下操作:

* 上傳新檔案到知識庫
* 查詢知識庫中的所有檔案
* 更新現有檔案的資訊
* 刪除單一或批次檔案
* 檢索知識庫內容（見[檢索知識庫](#search-knowledge-base)）

{% hint style="info" %}
**📘 重要提醒**

使用 API 時，所有操作都需要有效的 API Key 進行身分驗證。請確保您的 API Key 具備相應的權限。
{% endhint %}

***

## 知識庫操作 <a href="#knowledge-base-operations" id="knowledge-base-operations"></a>

### 建立知識庫 <a href="#create-knowledge-base" id="create-knowledge-base"></a>

<figure><img src="https://527168072-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F38pkhhqHl1oA6yyE9R2n%2Fuploads%2FqKJxK5Gu7qnAZ1LLAxFB%2Fimage.png?alt=media&amp;token=085281d5-9df2-41e1-8c85-7ad187b1d979" alt=""><figcaption></figcaption></figure>

在開始使用知識庫前，必須先建立至少**一個**知識庫。建立知識庫時，您必須指定知識庫使用的 Embedding Model、Reranker Model、知識庫名稱及可使用此知識庫的 Agent 等資訊。

您可以將以上的設定資訊，透過腳本化的方式指定。端點是 `POST /api/v1/knowledge-bases/`，以下為建立知識庫的請求範例。`embeddingModel`、`rerankerModel` 填模型 ID，可分別用 `GET /api/v1/embedding-models/`、`GET /api/v1/reranker-models/` 查詢；`numberOfRetrievedChunks` 是檢索片段數量。

{% code overflow="wrap" %}

```json
{
  "embeddingModel": "550e8400-e29b-41d4-a716-446655440000",
  "rerankerModel": "550e8400-e29b-41d4-a716-446655440000",
  "name": "內部訓練手冊",
  "description": "此知識庫供內部訓練使用，包含使用者手冊、產品手冊及錯誤處理手冊，僅供新人教育使用",
  "numberOfRetrievedChunks": 12,
  "enableRerank": true,
  "chatbots": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000"
    }
  ],
  "groups": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000"
    }
  ]
}
```

{% endcode %}

回應 `201` 與新知識庫的內容（含 `id`）即代表建立成功，可以針對此知識庫進行操作。

### 使用 ID 操作單一知識庫 <a href="#operate-by-id" id="operate-by-id"></a>

在開始對所單一知識庫進行檔案管理之前,您需要先取得知識庫的唯一識別碼(`id`)。

{% hint style="warning" %}
如何取得知識庫 id？

1. 取得剛建立的知識庫 `id`

針對剛使用腳本建立的知識庫，在建立完成後 HTTPS 會回傳包含 id 在內的 reponse，response 中的 `id`就代表該知識庫的 `id`值。

2. 取得其他已建立的知識庫 `id`

您可以透過取得所有知識庫的 `reponse` 內容獲取您需要的對應知識庫 `id`，請參考 API 文件：[知識庫(新版)](https://docs.maiagent.ai/api/api-reference/zhi-shi-ku-xin-ban#knowledge-bases-list)
{% endhint %}

### 查詢知識庫檔案 <a href="#list-files" id="list-files"></a>

`GET /api/v1/knowledge-bases/{knowledgeBasePk}/files/` 列出知識庫中的檔案，可用 `fileType`（如 `pdf`、`docx`、`txt`、`xlsx`）、`status`、`query`（關鍵字）篩選；檔案的 `status` 為 `done` 才代表解析完成、可供 Agent 檢索。查詢參數與回應欄位見 API 文件[列出知識庫中的檔案](https://docs.maiagent.ai/api/api-reference/zhi-shi-ku-xin-ban#knowledge-bases-files-list)。

回應中三個大小相關的欄位意義不同：`size` 是上傳的檔案本體大小（位元組），`vectorStorageSize` 是這份檔案在向量索引中佔用的空間（位元組），`chunksCount` 是解析後切出的段落數。計算知識庫容量用 `size`，估算向量儲存用 `vectorStorageSize`。

#### 範例:查詢所有 PDF 檔案 <a href="#example-list-pdf-files" id="example-list-pdf-files"></a>

{% tabs %}
{% tab title="Shell/Bash" %}
{% code overflow="wrap" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/knowledge-bases/550e8400-e29b-41d4-a716-446655440000/files/?fileType=pdf&page=1&pageSize=20" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endcode %}
{% endtab %}
{% endtabs %}

***

## 檔案操作 <a href="#file-operations" id="file-operations"></a>

### 上傳檔案到知識庫 <a href="#upload-files" id="upload-files"></a>

`POST /api/v1/knowledge-bases/{knowledgeBasePk}/files/` 把已上傳到儲存空間的檔案登記到網址中的知識庫並開始解析：`file` 必須填 [Presigned 檔案上傳模式](/tech/api-integration/api_knowledge.md) Step 1 回應的 `fields.key`，不能填外部網址；一次可登記多個檔案，單次建議不超過 50 個。欄位（含選填的 `parser`、`labels`、`rawUserDefineMetadata`）見 API 文件[上傳檔案到知識庫](https://docs.maiagent.ai/api/api-reference/zhi-shi-ku-xin-ban#knowledge-bases-files-create)。

#### 範例：上傳單個文件—產品手冊 <a href="#example-upload-single-file" id="example-upload-single-file"></a>

{% code overflow="wrap" %}

```json
{
  "files": [
    {
      "filename": "產品手冊.pdf",
      "file": "media/chatbots/chatbot-file/86572e41-16ba-45dd-b049-28c69f77ffb0.pdf",
      "parser": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "labels": [
        {
          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
        }
      ]
    }
  ]
}
```

{% endcode %}

回應是新建立的檔案物件陣列，包含系統產生的檔案 ID。

#### 同名檔案與重複註冊 <a href="#duplicate-filename" id="duplicate-filename"></a>

* **檔名不是唯一鍵**：同一個知識庫再 `POST` 一個 `filename` 相同的檔案，會建立另一筆文件（`201`），不會覆蓋、也不會回衝突；兩份都會被檢索到。要更新內容請先用 `GET …/files/?query=檔名` 找到舊檔，刪除後再上傳，或用 `PATCH` 只更新標籤與元資料。
* **同一個 `fields.key` 只能註冊一次**：檔案 ID 由上傳到儲存空間的物件名稱衍生，用同一個 `fields.key` 再 `POST` 一次會回 `400`，`detail` 為「This file has already been uploaded to the knowledge base」。重送時請重新走 Presigned Step 1 → 2 取得新的 `key`。
* 檔名比對只在同一個知識庫內有意義，不同知識庫可以有同名檔案。

#### 範例：一次上傳多個檔案 <a href="#upload-multiple-files" id="upload-multiple-files"></a>

同一次請求登記的檔案都會放進網址中的知識庫；要放進不同的知識庫，請對各知識庫分別呼叫。

{% code overflow="wrap" %}

```json
{
  "files": [
    {
      "filename": "新人教育手冊.pdf",
      "file": "media/chatbots/chatbot-file/0b6f3c2e-6a51-4f43-9d3f-6e2f1c9a7b10.pdf"
    },
    {
      "filename": "D256 產品說明文件.pdf",
      "file": "media/chatbots/chatbot-file/5d1f2a7c-3b8e-4c19-9a62-1e4b7f0c8d35.pdf"
    }
  ]
}
```

{% endcode %}

{% hint style="danger" %}
請注意：單一檔案限制不能超過 100MB，否則將無法正確處理，HTTP 將回傳錯誤訊息
{% endhint %}

### 更新現有檔案資訊 <a href="#update-file" id="update-file"></a>

`PUT`／`PATCH /api/v1/knowledge-bases/{knowledgeBasePk}/files/{id}/` 只更新 `labels` 與 `rawUserDefineMetadata`，檔名與檔案內容不變、不需要重新上傳；沒帶的欄位維持不變，`labels` 帶空陣列會清空標籤。欄位見 API 文件[更新檔案資訊](https://docs.maiagent.ai/api/api-reference/zhi-shi-ku-xin-ban#knowledge-bases-files-update)。

#### 端點 <a href="#duan-dian" id="duan-dian"></a>

```
PUT /api/v1/knowledge-bases/{knowledgeBasePk}/files/{id}/
```

**請求範例**

{% code overflow="wrap" %}

```json
{
  "labels": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000"
    }
  ],
  "rawUserDefineMetadata": {
    "editDate": "2025/10/30",
    "version": "online"
  }
}
```

{% endcode %}

### 中繼資料（`rawUserDefineMetadata`）的規則 <a href="#metadata-contract" id="metadata-contract"></a>

上傳與更新檔案時的 `rawUserDefineMetadata` 是 `{"欄位名稱": 值}` 物件，欄位對應知識庫的「中繼資料欄位」（`GET`／`POST /api/v1/knowledge-bases/{knowledgeBasePk}/metadata-keys/`，欄位有 `keyName`、`isRequired`、`defaultValue`、`enabledForSearch`）。平台處理的規則：

| 規則                 | 行為                                                                                                |
| ------------------ | ------------------------------------------------------------------------------------------------- |
| 未知的欄位名稱            | 不會被拒絕：平台自動在該知識庫建立同名的自訂欄位，之後的檔案都可以使用                                                               |
| 值的型別               | 一律存成字串：物件與陣列存成 JSON 字串、布林存成 `true`／`false`、其他型別轉成字串；超過 1000 字元的值會被截斷，不會報錯                         |
| 更新時的範圍             | `PUT`／`PATCH` 帶 `rawUserDefineMetadata` 時是**整組取代**：沒列出的既有欄位會從這份檔案移除，帶 `{}` 會清空。要只改一個欄位，請把其他欄位一併帶上 |
| `defaultValue`     | 欄位設有預設值時，新上傳的檔案會自動帶入這個值                                                                           |
| `isRequired`       | 只影響後台的表單檢查；API 不會因為缺少必填欄位而拒絕上傳或更新                                                                 |
| `enabledForSearch` | 開啟時，這個欄位的值會隨檢索到的段落一併送進模型，Agent 的檔案搜尋也會比對它；關閉時只在後台顯示，不影響檢索                                         |
| 系統欄位               | `url` 與 `crawl_` 開頭的欄位由爬蟲寫入，建立時會標成系統欄位且不送進模型                                                      |

### 批次重新解析 <a href="#batch-reparse" id="batch-reparse"></a>

`PATCH /api/v1/knowledge-bases/{knowledgeBasePk}/files/batch-reparse/` 讓指定的檔案以指定的解析器重新解析。請求內容是陣列，每一項是一份檔案：

```json
[
  {"id": "<檔案 ID>", "parser": "<解析器 ID>"},
  {"id": "<檔案 ID>", "parser": null}
]
```

* `id` 必填，檔案必須屬於網址中的知識庫。
* `parser` 填解析器 ID（`GET /api/v1/parsers/` 可查）就改用該解析器；填 `null` 會清掉原本指定的解析器，重新解析時改回自動判斷。
* **沒有帶 `parser` 鍵的項目會被略過**，不會重新解析。要用原本的解析器重跑，請把它的解析器 ID 明確帶上。
* 空陣列 `[]` 回 `200` 但不做任何事，**不是**「全部重新解析」；要重解整個知識庫，請先用[查詢知識庫檔案](#list-files)取得檔案 ID 再分批送出。
* 只有狀態為 `done`、`failed`，或停留在處理中超過平台卡住門檻的檔案可以重新解析；其他狀態的檔案會讓整個請求回 `400`。重新解析會依解析器用量重新扣點。

### 刪除檔案 <a href="#delete-files" id="delete-files"></a>

#### 刪除單一檔案 <a href="#delete-single-file" id="delete-single-file"></a>

`DELETE /api/v1/knowledge-bases/{knowledgeBasePk}/files/{id}/` 從知識庫移除單一檔案，成功回 `204`，此後這份文件不會再被 Agent 參考。見 API 文件[刪除檔案](https://docs.maiagent.ai/api/api-reference/zhi-shi-ku-xin-ban#knowledge-bases-files-destroy)。

**範例**

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X DELETE "https://api.maiagent.ai/api/v1/knowledge-bases/550e8400-e29b-41d4-a716-446655440000/files/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}
{% endtabs %}

#### 批次刪除檔案 <a href="#batch-delete-files" id="batch-delete-files"></a>

<figure><img src="https://527168072-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F38pkhhqHl1oA6yyE9R2n%2Fuploads%2FdEBrHLAKKTH2d20nZqiF%2F%E8%9E%A2%E5%B9%95%E6%93%B7%E5%8F%96%E7%95%AB%E9%9D%A2%202025-10-30%20122932.png?alt=media&amp;token=ac130f96-a740-488c-87c6-67a428054d50" alt=""><figcaption></figcaption></figure>

`POST /api/v1/knowledge-bases/{knowledgeBasePk}/files/batch-delete/` 以 `ids` 一次刪除同一個知識庫內的多個檔案，不能跨知識庫；成功回 `200`，`queued` 是已排入刪除的檔案 ID，`skipped` 是正在刪除中而略過的檔案。見 API 文件[批量刪除檔案](https://docs.maiagent.ai/api/api-reference/zhi-shi-ku-xin-ban#knowledge-bases-files-batch-delete-create)。

請求範例值

```json
{
  "ids": [
    "550e8400-e29b-41d4-a716-446655440000",
    "550e8400-e29b-41d4-a716-446655449198",
    "0b6f3c2e-6a51-4f43-9d3f-6e2f1c9a7b10"
  ]
}
```

#### 刪除後的檢索一致性 <a href="#deletion-consistency" id="deletion-consistency"></a>

| 時間點                                             | 狀態                                                                                                         |
| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `DELETE` 回 `204`（或批次刪除回 `200` 且檔案在 `queued`）的當下 | 檔案的段落與引用節點已同步移除，之後的[檢索 API](#search-knowledge-base) 與 Agent 回答都不會再回這份檔案的內容；不需要等待或輪詢                        |
| 之後的背景處理                                         | 向量資料庫中的向量與儲存空間的檔案本體在背景清除；這段期間檔案列表的 `status` 可能顯示 `deleting`，清除失敗則為 `delete_failed`（可再刪一次）。這兩種狀態的檔案都不在檢索範圍內 |
| `GET …/files/{id}/`                             | 刪除後回 `404`                                                                                                 |
| 歷史對話                                            | 訊息文字保留；曾引用這份檔案的 `citationNodes` 會隨段落一起移除，舊訊息再查時不會再列出該檔案的引用。需要保留引用紀錄請在刪除前匯出                                 |
| 刪除中再送檢索或刪除                                      | 檢索正常回應（不含該檔案）；批次刪除會把正在刪除中的檔案放進 `skipped`，單檔 `DELETE` 仍回 `204`，不會報錯                                         |

刪除無法復原，重新上傳會再計一次解析與向量化費用。

***

## 檢索知識庫 <a href="#search-knowledge-base" id="search-knowledge-base"></a>

用一段文字查詢單一知識庫，取得最相關的段落（chunk）。檢索方式與 Agent 對話時相同：依知識庫設定的 Embedding 模型、Reranker、檢索片段數量與相似度門檻執行，流程見 [RAG 知識庫檢索系統](/tech/quickstart/rag.md#retrieval-flow)。

### 端點 <a href="#search-endpoint" id="search-endpoint"></a>

`POST /api/v1/knowledge-bases/{id}/search/`，`{id}` 為知識庫 ID，API Key 綁定的成員必須能存取這個知識庫。見 API 文件[搜尋特定知識庫的內容](https://docs.maiagent.ai/api/api-reference/zhi-shi-ku-xin-ban#knowledge-bases-search-create)。

### 請求欄位 <a href="#search-request" id="search-request"></a>

搜尋文字放在請求內容的 `query`（必填）；`searchMode` 可選 `hybrid`（預設，平台關閉混合檢索時自動改為 `semantic`）、`semantic` 或 `keyword`（僅 Elasticsearch）。要限定範圍時帶 `queryMetadata`，格式同 [Query Metadata](/tech/identity-and-access/zhi-shi-guan-li-quan-xian-query-metadata-cha-xun-yuan-zi-liao-zong-lan.md)，但 `knowledgeBases` 只能有一筆且 `knowledgeBaseId` 必須與網址中的知識庫 ID 相同；不帶時查詢整個知識庫。

範例：只在兩個檔案中搜尋。

```json
{
  "query": "退貨期限是幾天？",
  "searchMode": "hybrid",
  "queryMetadata": {
    "knowledgeBases": [
      {
        "knowledgeBaseId": "57a5630e-ed2f-42f4-aff1-d1edc241ceb6",
        "chatbotFileIds": ["<檔案 ID 1>", "<檔案 ID 2>"],
        "hasUserSelectedAll": false
      }
    ]
  }
}
```

### 回應欄位 <a href="#search-response" id="search-response"></a>

回應是段落物件的陣列（不分頁），依相關程度由高到低排列，筆數最多為知識庫的 <mark style="color:blue;">檢索片段數量</mark>；回應**不含**相似度分數，請以陣列順序判斷相關程度。段落來自 FAQ 時，`filename` 為 `FAQ`、`chatbotFile` 為 `null`。各欄位見 API 文件[搜尋特定知識庫的內容](https://docs.maiagent.ai/api/api-reference/zhi-shi-ku-xin-ban#knowledge-bases-search-create)。

### 錯誤與計費 <a href="#search-errors" id="search-errors"></a>

| 狀態碼         | 情況                                                                                                   |
| ----------- | ---------------------------------------------------------------------------------------------------- |
| `400`       | `queryMetadata` 格式錯誤或知識庫 ID 不一致；向量資料庫不支援 `keyword` 模式；檢索失敗（`Search failed. Please try again later.`） |
| `402`       | 組織 Credits 或成員額度不足                                                                                   |
| `403`／`404` | 金鑰綁定的成員沒有這個知識庫的存取權限，或知識庫不存在                                                                          |

每次檢索會依使用的 Embedding 與 Reranker 用量扣點，與 Agent 對話時的檢索相同。

***

## 錯誤排查 <a href="#troubleshooting" id="troubleshooting"></a>

檔案端點都掛在 `/knowledge-bases/{knowledgeBasePk}/files/…` 底下，權限先看網址裡的知識庫，再看檔案；對照下表判斷：

| 狀態碼   | 常見原因                                                                                                                                                                         | 怎麼確認與處理                                                                                                                                                                                                     |
| ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `401` | 金鑰無效、已停用，或 `Authorization` 標頭格式不是 `Api-Key <金鑰>`                                                                                                                             | 用 `GET /api/v1/knowledge-bases/` 測金鑰；見 [API 共通規範：認證](/tech/api-integration/api-conventions.md#authentication)                                                                                               |
| `403` | 金鑰綁定的成員不在這個知識庫所屬的組織（含 ID 打錯打到別人的知識庫）；或成員的角色沒有這個知識庫的存取權。寫入類（上傳、更新、重新解析）需要角色對該知識庫有「更新」權限，刪除類需要「刪除」權限，缺權限時 `detail` 會寫明是 update 還是 delete                                       | 先用 `GET /api/v1/knowledge-bases/` 確認列表裡有這個 ID；有列表但寫入 `403` 時，請組織擁有者到角色權限開啟該知識庫的更新／刪除權限，或改用擁有者的金鑰                                                                                                            |
| `404` | 知識庫已被刪除（或正在刪除中）；檔案 `{id}` 不屬於網址中的知識庫（檔案在別的知識庫、已刪除，或是對話附件而不是知識庫檔案）                                                                                                            | 用 `GET …/files/?query=檔名` 在正確的知識庫找檔案 ID；跨知識庫搬移後 ID 不變但知識庫變了，請改網址                                                                                                                                            |
| `400` | `file` 不是 Presigned 的 `fields.key`；同一個 `key` 重複註冊；副檔名沒有任何解析器支援（`detail`：「不支援解析的檔案類型」）；`fileSize` 超過上傳上限（Presigned Step 1 就會擋）；`queryMetadata` 的知識庫 ID 與網址不一致；`ids` 含其他知識庫的檔案 | 依 `detail` 修正，支援的副檔名見 [Parser 解析工具](/tech/quickstart/parser.md#document-parsers)，大小上限見 [API 共通規範：上傳大小上限](/tech/api-integration/api-conventions.md#upload-limits)，兩者都可用 `GET /api/v1/allowed-file-specs/` 取得 |
| `402` | 組織 Credits 或成員額度不足（檢索、解析都會扣點）                                                                                                                                                | 先儲值或調整額度                                                                                                                                                                                                    |
| `500` | 平台端錯誤                                                                                                                                                                        | 先用 `GET …/files/?query=檔名` 確認檔案有沒有被建立：有就不要重送（會變成兩筆），改用 `GET …/files/{id}/` 追狀態；沒有就隔幾秒重走 Step 1 → 3。仍失敗時記下時間、知識庫 ID、檔案 ID 與去掉金鑰的請求內容洽 MaiAgent 窗口                                                            |

要看每次呼叫的實際請求與回應，用後台的 [API 呼叫紀錄](https://docs.maiagent.ai/org/developer/api-logs)。解析失敗（`status: failed`）不是 HTTP 錯誤：呼叫 `GET /api/v1/knowledge-bases/{knowledgeBasePk}/files/{id}/latest-failed-reason/` 取得最近一次失敗的 `errorMessage` 與 `createdAt`，修正檔案後重新上傳或用批次重新解析端點換解析器；後台文件列表把滑鼠移到「失敗」狀態上看到的是同一筆原因。

***

## 完整範例：上傳、等待解析、檢索 <a href="#upload-poll-search-example" id="upload-poll-search-example"></a>

以下 Python 範例把一份 PDF 上傳到知識庫，等檔案解析完成後立即檢索。上傳使用 Presigned 模式，每個步驟的細節見 [Presigned 檔案上傳模式](/tech/api-integration/api_knowledge.md)。

```python
import os
import time

import requests

BASE = 'https://api.maiagent.ai/api/v1'
HEADERS = {'Authorization': 'Api-Key YOUR_API_KEY'}
KB_ID = 'YOUR_KNOWLEDGE_BASE_ID'
PATH = '/path/to/manual.pdf'

# 1. 取得 Presigned URL，並把檔案直接上傳到儲存空間
filename = os.path.basename(PATH)
presign = requests.post(
    f'{BASE}/upload-presigned-url/',
    headers=HEADERS,
    json={
        'modelName': 'chatbot-file',
        'fieldName': 'file',
        'filename': filename,
        'fileSize': os.path.getsize(PATH),
    },
)
presign.raise_for_status()
presign = presign.json()
with open(PATH, 'rb') as f:
    upload = requests.post(presign['url'], data=presign['fields'], files={'file': f})
assert upload.status_code == 204, upload.text

# 2. 把上傳結果註冊到知識庫，開始解析
created = requests.post(
    f'{BASE}/knowledge-bases/{KB_ID}/files/',
    headers=HEADERS,
    json={'files': [{'filename': filename, 'file': presign['fields']['key']}]},
)
created.raise_for_status()
file_id = created.json()[0]['id']

# 3. 輪詢檔案狀態，直到 done 或 failed
deadline = time.time() + 30 * 60
while True:
    status = requests.get(
        f'{BASE}/knowledge-bases/{KB_ID}/files/{file_id}/', headers=HEADERS
    ).json()['status']
    if status in ('done', 'failed'):
        break
    if time.time() > deadline:
        raise TimeoutError('檔案解析逾時')
    time.sleep(10)
if status == 'failed':
    raise RuntimeError('檔案解析失敗，請到後台查看失敗原因')

# 4. 檢索
results = requests.post(
    f'{BASE}/knowledge-bases/{KB_ID}/search/',
    headers=HEADERS,
    json={'query': '保固期限是多久？'},
)
results.raise_for_status()
for node in results.json():
    print(node['displayTitle'], node['pageStart'], node['displayText'][:80])
```

* 狀態 `initial`、`processing` 代表還在處理；只有 `done` 的檔案才會被檢索到。
* 解析時間依檔案大小、頁數與解析器而定，大檔案可能需要數分鐘。輪詢間隔建議 5 秒以上，並設定逾時上限。
* 解析失敗（`failed`）時，呼叫 `GET …/files/{file_id}/latest-failed-reason/` 取得失敗原因（後台文件列表的「失敗原因」是同一筆），修正檔案後重新上傳或重新解析，見[錯誤排查](#troubleshooting)。

***

## 使用案例 <a href="#use-cases" id="use-cases"></a>

知識庫檔案管理 API 有許多實際應用場景,例如:

### 1. 自動化文件更新 <a href="#use-case-auto-update" id="use-case-auto-update"></a>

當您的產品文件在 Git 儲存庫中更新時，可以透過 CI/CD 流程自動將最新版本上傳到知識庫。確保 Agent 始終能存取最新的產品資訊。

#### **範例流程** <a href="#use-case-auto-update-flow" id="use-case-auto-update-flow"></a>

{% stepper %}
{% step %}
**偵測到文件更新的 commit**
{% endstep %}

{% step %}
**查詢是否已存在該檔案**

使用 MaiAgent API 查詢知識庫內是否有可匹配之檔案。
{% endstep %}

{% step %}
**更新/上傳檔案**

若存在則使用<mark style="color:blue;">部分更新資訊端點</mark>更新；如果不存在則使用<mark style="color:blue;">上傳檔案端點</mark>上傳新檔案。
{% endstep %}
{% endstepper %}

### 2. 內容管理系統整合 <a href="#use-case-cms-integration" id="use-case-cms-integration"></a>

如果您使用 MaiAgent 作為內容管理系統 (CMS)，可以建立一個管理介面,讓內容編輯者能夠

* 上傳新的內容檔案
* 使用標籤組織內容
* 搜尋和篩選特定類型的內容
* 批次刪除過期內容

***

## 總結 <a href="#summary" id="summary"></a>

MaiAgent 的公開 REST API 可以讓您更有效率管理知識庫檔案，包括：

* 建立知識庫
* 查詢和篩選檔案
* 上傳新檔案
* 更新檔案資訊
* 刪除單一或批次檔案
* 檢索知識庫內容

## 下一步 <a href="#next-steps" id="next-steps"></a>

* 查看完整的 [API 參考文件](https://docs.maiagent.ai/api)開始使用 MaiAgent API 服務
* 探索 [MaiAgent Web Chat SDK ](https://docs.maiagent.ai/tech/api-integration/web-chat-sdk)以簡化 API 整合


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.maiagent.ai/tech/api-integration/knowledge-base-api.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
