本文件為英文原版的機器翻譯。若翻譯版本與英文原版之間存在任何歧義,概以英文原版為準。 閱讀英文原版


公共 API

Caiioo 包含一個 REST API,讓您可以透過程式控制一切:執行代理、管理工具、排程任務等。該 API 位於支援桌面應用程式和瀏覽器 Bridge 的同一個本機伺服器上。

基礎 URL: http://localhost:3847/v1

身份驗證: 有兩種驗證方式,均受設定中 API 開關的控制:

針對外部使用者(腳本、整合、curl): 在 設定 > API 存取 中設定一個 API 存取 Token,然後將其作為 Bearer Token 使用:

curl -H \"Authorization: Bearer YOUR_API_TOKEN\" http://localhost:3847/v1/providers

針對本機應用程式(自動): Caiioo 桌面應用程式、瀏覽器擴充功能和行動應用程式會透過現有的 relay 驗證標頭 (x-relay-auth;HTTP 標頭不區分大小寫) 自動驗證。無需手動設定 — 應用程式會在幕後處理。Relay-auth 請求會繞過「啟用公共 API」開關,因為它們已被信任;只有 Bearer Token 請求受開關控制。

設定:

  1. 開啟 Caiioo 設定 > API 存取
  2. 啟用公共 API 切換為開啟
  3. 設定一個 API 存取 Token(您選擇的任何字串 — 請將其視為密碼)
  4. 在所有 API 請求中使用該 Token

API 可在 localhost 和透過私有 Relay 使用。查看 GET /v1/auth/info(無需驗證)以獲取目前狀態和設定說明。

速率限制: 每個 /v1/* 請求都會根據用戶端 IP 進行速率限制 — 讀取操作為 每分鐘 100 次 GET 請求,寫入操作(POST / PATCH / DELETE)合計為 每分鐘 30 次請求。超過限制的請求將收到 429。Webhook 交付 (POST /v1/webhooks/:id) 不需要 Bearer 驗證,也不受這些限制約束。

設定檔

單一裝置可以擁有多個使用者設定檔(例如:個人 + 工作)。API 允許外部腳本檢查可用的設定檔,並在執行其他工作前切換目前的活動設定檔。設定檔的建立、更新和刪除刻意不透過公開 API 開放——這些流程屬於應用程式的引導 UI。

列出設定檔:

GET /v1/profiles

回傳 { profiles: [...] },每個未刪除的設定檔各有一條項目。每條項目包含 idnameemailavatarUrltieraccessibleModeslicenseorganizationpreferencesonboardingCompletecreatedAtlastAccessedAt帶有權杖的欄位(serviceCredentialsoauthConnections)和同步內部資訊(vectorClocklastModifiedBy)已被移除。 請使用 /v1/connectors 來檢查 OAuth 連線。

取得活動設定檔:

GET /v1/profiles/active

回傳此伺服器目前使用的 { profile }。所有範圍限定於設定檔的 /v1/* 資源(對話串、附件、設定、技能)都針對此設定檔運作。

切換活動設定檔:

PUT /v1/profiles/active
Content-Type: application/json

{ "profileId": "來自列表的 user-uuid" }

回傳新啟用的 { profile }。如果 ID 不是已知設定檔,則回傳 404

Providers & Models

探索已配置的 LLM 提供商以及可用的模型。

列出提供商:

GET /v1/providers

返回所有支援的提供商類型。目前包括:anthropicopenaigoogleopenrouterollamapoemlxperplexitybasetencloudflare。每個條目包含 typedisplayNameiconrequiresApiKeyhasApiKey 以及一個包含下方標記的 capabilities 物件。

能力標記 (Capability flag) 意義
supportsVision 提供商可接受圖片輸入
supportsPdfFile 提供商可原生接受原始 PDF 檔案內容區塊
supportsToolCalling 提供商支援函數/工具調用 (tool calling)
supportsStreaming 提供商以增量方式串流 Token
supportsExtendedThinking 提供商提供推理/思考預算 (reasoning/thinking budget)
supportsPromptCaching 提供商支援提示詞快取 (prompt-cache) 指令
nativeReasoningBlocks 提供商將思考內容作為原生訊息區塊輸出(而非純文字)
requiresThoughtSignature 提供商要求將簽署的思考 Token 回傳

能力標記與每個提供商類別的 readonly capabilities 欄位同步(參見 src/shared/providers/*-provider.ts),並通過漂移哨兵測試 (drift sentinel test) 進行驗證 — 請在執行時調用此端點,而非硬編碼該矩陣。

BYOK 提供商注意事項:

  • perplexity 提供精選的 Sonar 模型列表(Perplexity 沒有公開的 /models 端點)。
  • cloudflare (AI Gateway) 屬於 BYOK + 多供應商模式;模型列表由您的 Gateway 配置決定,且 /v1/providers/cloudflare/models 會返回空陣列。請使用您自己的 Gateway 目錄。

列出特定提供商的模型:

GET /v1/providers/openrouter/models

返回該提供商的模型目錄。每個模型包含 iddisplayName 以及可用的 contextLength。當提供商缺少 API 金鑰或其上游目錄無法連線時,返回 503

跨所有提供商的扁平化目錄:

GET /v1/models

將所有已配置提供商的模型合併為一個列表。未配置 API 金鑰的提供商將被跳過並列於 warnings 中。

代理 (Agents)

代理是 Caiioo 的核心。每個代理都是一個模式 (Mode) —— 一個配置好的個性,擁有自己的系統提示詞、工具、變數和技能。

列出所有代理:

GET /v1/agents

返回內建代理(購物、職場、一般)以及您建立的任何自定義代理。每個代理都標有 source: \"builtin\"source: \"custom\"

建立自定義代理:

POST /v1/agents
Content-Type: application/json

{
  \"id\": \"my-research-agent\",
  \"branding\": {
    \"name\": \"研究代理\",
    \"description\": \"搜尋網頁並總結發現\"
  },
  \"defaultSettings\": {
    \"systemPrompt\": \"你是一位研究助手。務必引用來源。\",
    \"enabledTools\": { \"web_browsing\": true, \"search_tools\": true }
  },
  \"settingLevels\": {}
}

返回 201 以及建立的代理。系統會自動附加向量時鐘用於同步。

更新代理:

PATCH /v1/agents/my-research-agent
Content-Type: application/json

{ \"branding\": { \"name\": \"研究代理\", \"description\": \"更新後的描述\" } }

將補丁合併到現有代理中並更新向量時鐘。內建代理返回 403 —— 它們是唯讀的。

刪除代理:

DELETE /v1/agents/my-research-agent

透過標記 (tombstone) 進行軟刪除(跨裝置同步)。返回 204

執行 Agent

這是核心功能 — 調用 Agent 來處理訊息。

請求主體 — 支援的欄位

欄位 必填 描述
agentId 內建模式 ID(例如 general)或自定義 Agent ID
input.message 使用者訊息文字
input.attachments 附件 ID 陣列(已透過 /v1/attachments 上傳),用於附加至此輪對話
input.variables 每次執行時的變數覆蓋,將合併至 Agent 的變數解析器中
input.tabContext 作為頁面上下文注入的自由格式字串(由瀏覽器橋接器使用)
input.messageId 用戶端提供的訊息 ID — 在重試時用於去重(dedup)非常有用
threadId 要繼續的現有對話串。如果省略,將建立並回傳一個新的對話串
mode "sync""async"。預設為 "async"

同步模式 (Synchronous Mode)

等待完整回應:

POST /v1/runs
Content-Type: application/json

{
  "agentId": "general",
  "input": { "message": "今天巴黎的天氣如何?" },
  "mode": "sync"
}

在 Agent 完成後回傳 200 以及 { content, usage, status: "completed" }。如果 Agent 發生錯誤,則回傳 500 以及 { error, status: "error" }。同步執行若在 5 分鐘內未收到終端事件,將以 status: "error" 逾時 — 對於任何可能耗時較長的操作,請使用非同步模式 + SSE。

非同步模式 (Asynchronous Mode)

發送後即不理會 — 適用於長時間運行的任務:

POST /v1/runs
Content-Type: application/json

{
  "agentId": "my-research-agent",
  "input": { "message": "撰寫一份 2000 字的可再生能源趨勢分析" },
  "mode": "async"
}

立即回傳 202 以及 { runId, threadId, status: "running" }

輪詢狀態:

GET /v1/runs/{runId}

回傳 { run: { runId, threadId, agentId, status, createdAt, content?, usage?, error? } }。狀態為 runningcompletederrorcancelled 其中之一。

即時串流事件 (SSE):

GET /v1/runs/{runId}/events

回傳 text/event-stream,包含 Agent 發生時的每個事件:GENERATION_STARTEDSTREAMING_CONTENT、工具調用、子 Agent 活動,以及終端事件(GENERATION_COMPLETEGENERATION_ERRORGENERATION_CANCELLED)。

在終端事件之後,伺服器會發送最後一個 SSE 框架,帶有 event: terminal 和空的資料負載,作為明確的串流結束標記,然後關閉連線。用戶端應將收到該框架(或連線關閉)視為停止讀取的訊號。

如果您在執行已經結束後才訂閱,伺服器會重播一個類型為 RUN_SNAPSHOT 的框架,其中包含完整的最終 record,隨後是 event: terminal 標記,然後關閉。

取消執行:

POST /v1/runs/{runId}/cancel

回傳 { run: { ..., status: "cancelled" } }

Threads

Threads 是對話。每一次代理程式(agent)的執行都發生在 Thread 中,且 Thread 會跨工作階段持久保存。API 讓您可以透過程式化方式列出、讀取、建立及管理 Thread。

列出所有 Thread(僅限中繼資料):

GET /v1/threads

回傳目前設定檔的 { threads: [...] },其中 messages 已被移除(需要訊息時請使用詳細資訊端點)。其他所有欄位均保留 —— idtitlecreatedAtupdatedAtmodeIdarchived、使用統計,以及已設定的 subAgentHistoriesanonymizerSnapshotthreadToolApprovalsthreadVariablesthreadToolOverridesmessagingBindingscheduledTaskId。(較豐富的負載為 API 專屬 —— WebSocket 側邊欄廣播使用更嚴格的移除機制以保持在傳輸限制內。)

獲取包含完整訊息的 Thread:

GET /v1/threads/{id}

回傳完整的 Thread,包括其 messages 陣列 —— 每一條使用者訊息、助理回應、工具調用(tool call)及工具結果。

僅獲取訊息:

GET /v1/threads/{id}/messages

僅回傳 messages 陣列 —— 當您只需要對話內容時,這比完整的 Thread 物件更輕量。

建立 Thread:

POST /v1/threads
Content-Type: application/json

{ "title": "Research project", "modeId": "general" }

回傳 201{ thread }。新 Thread 會立即顯示在側邊欄(透過 WebSocket 廣播)。API 在建立時絕不會切換應用程式的活動 Thread —— 如果您需要切換,請另外呼叫 PUT /v1/threads/active

更新 Thread:

PATCH /v1/threads/{id}
Content-Type: application/json

{ "title": "Renamed project", "archived": true }

可更新欄位:titlemodeIdarchivedlastUsedModel。變更會即時廣播至側邊欄。

刪除 Thread:

DELETE /v1/threads/{id}

軟刪除(soft-delete)該 Thread(用於同步的標記)。回傳 204。刪除的 Thread 會移至垃圾桶,在清理垃圾桶前均可復原。

活動 Thread:

GET /v1/threads/active            # 回傳 { threadId }
PUT /v1/threads/active            # 主體: { "threadId": "..." }

垃圾桶管理:

GET /v1/threads/trash/count       # 回傳 { count }
POST /v1/threads/trash/empty      # 回傳 { deletedCount, protectedCount }

受保護的 Thread(透過資料保留切換開關保留)將不包含在垃圾桶清理範圍內。

透過 API 繼續對話: 若要向現有的 Thread 發送後續訊息,請使用 POST /v1/runs 並帶上 Thread 的 ID:

POST /v1/runs
Content-Type: application/json

{
  "agentId": "general",
  "threadId": "existing-thread-id",
  "input": { "message": "Follow up on that last point" },
  "mode": "sync"
}

代理程式將會看到該 Thread 的完整對話歷史記錄。

附件

附件是連結到對話串的檔案 —— 螢幕截圖、PDF、文件、上傳的圖片、產生的成品。API 讓您可以列出、上傳、下載和管理它們。

列出所有附件(僅限元數據):

GET /v1/attachments

返回當前設定檔的附件元數據。大型欄位(dataUrlextractedContentextractedImages)會被移除 —— 請使用詳情或內容端點獲取這些資訊。

列出特定對話串的附件:

GET /v1/threads/{threadId}/attachments

獲取附件元數據:

GET /v1/attachments/{id}

返回完整的元數據,包括 extractedContent(OCR 文字、解析後的 markdown)、contentTypefileNamesize 以及 hasContent 標記。原始二進位檔案 包含在內 —— 請使用 /content 端點獲取。

下載附件二進位檔案:

GET /v1/attachments/{id}/content

返回帶有正確 Content-TypeContent-Disposition 標頭的原始檔案。將其導向至檔案:

curl -o output.pdf \
  -H "Authorization: Bearer $API_TOKEN" \
  http://localhost:3847/v1/attachments/{id}/content

上傳附件:

POST /v1/attachments
Content-Type: application/json

{
  "threadId": "thread-id",
  "type": "user_upload",
  "contentType": "application/pdf",
  "fileName": "report.pdf",
  "description": "季度報告",
  "dataUrl": "data:application/pdf;base64,JVBERi0xLjQ..."
}

dataUrl 是一個 base64 編碼的資料 URL。返回 201 以及新的附件 ID。附件會連結到指定的對話串。

更新附件元數據:

PATCH /v1/attachments/{id}
Content-Type: application/json

{ "description": "更新後的描述", "fileName": "new-name.pdf" }

刪除附件:

DELETE /v1/attachments/{id}

透過標記 (tombstone) 進行軟刪除。返回 204

MCP 伺服器

管理您的 MCP (Model Context Protocol) 伺服器連線 — 這些伺服器為代理程式 (agents) 提供存取外部工具和資料來源的權限。

列出已配置的伺服器:

GET /v1/mcp-servers

回傳目前設定檔 (profile) 的所有 MCP 伺服器配置。敏感欄位(authTokenenvcredentialId)會從回應中移除。

獲取特定伺服器配置:

GET /v1/mcp-servers/{id}

新增 MCP 伺服器:

POST /v1/mcp-servers
Content-Type: application/json

{
  "id": "my-server",
  "name": "My MCP Server",
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/files"],
  "serverType": "local"
}

對於遠端 HTTP 伺服器,請使用 "url" 代替 "command"

{
  "id": "remote-server",
  "name": "Remote API",
  "url": "https://my-mcp-server.example.com/sse",
  "serverType": "remote"
}

POST 接受的可選欄位:commandargsenvurldescriptiontransportTypeauthTypeauthTokenauthHeaderheadersspecTypespecPathtimeoutMscredentialIdoauthConnectionIdapproval。伺服器管理的欄位(customOAuthhubPackageIdprofileIdconnectorIdteamPublishedteamOrgIdvectorClock 等)無法透過 API 設定。

更新伺服器:

PATCH /v1/mcp-servers/{id}
Content-Type: application/json

{ "name": "Renamed Server", "args": ["-y", "@mcp/server-v2"] }

可更新的欄位與 POST 允許清單相同(包括 credentialIdoauthConnectionId — 方便在不刪除重建的情況下更換 OAuth 連線)。伺服器管理的欄位保持唯讀。

啟用/停用伺服器:

POST /v1/mcp-servers/{id}/toggle
Content-Type: application/json

{ "enabled": false }

刪除伺服器:

DELETE /v1/mcp-servers/{id}

程序管理

對於本地 (stdio) MCP 伺服器,您可以直接管理伺服器程序。

列出執行中的程序:

GET /v1/mcp-servers/processes

回傳執行中的伺服器程序,包含 pidstartedAtrunning 狀態。

啟動伺服器:

POST /v1/mcp-servers/{id}/start

從伺服器配置中讀取 command/args/env 並產生程序。回傳程序狀態。

停止伺服器:

POST /v1/mcp-servers/{id}/stop

正常關閉伺服器程序(發送 SIGTERM,若無效則發送 SIGKILL)。

直接呼叫 JSON-RPC 方法:

POST /v1/mcp-servers/{id}/call
Content-Type: application/json

{ "method": "tools/list", "params": {} }

向伺服器發送原始 JSON-RPC 2.0 請求並回傳結果。適用於偵錯或呼叫未透過工具 API 公開的方法。

Tools & Toolkits

瀏覽並調用代理程式使用的工具 — 網頁瀏覽、搜尋、行事曆、Gmail、Slate 等。

列出工具包(分組):

GET /v1/toolkits

傳回按類別(生產力、搜尋、公用程式等)分組的內建工具,以及任何已連接的 MCP 伺服器作為獨立工具包,並列出各自的操作。

列出所有工具(扁平列表):

GET /v1/tools
GET /v1/tools?source=embedded   # 僅限內建工具
GET /v1/tools?source=mcp        # 僅限 MCP 伺服器工具

獲取包含輸入架構的工具詳情:

GET /v1/tools/calculator

傳回 { tool: { name, displayName, description, source, category, inputSchema, actions?, requiredTier?, requiredRuntimes?, riskTier?, riskExplanation?, requiresApproval? } }

欄位 意義
inputSchema 工具輸入的 JSON Schema — 調用前進行驗證
actions 選用子操作(例如 Slate 的 read/write);每個操作都有 iddisplayNamedescription 及選用的 requiredTier
requiredTier 最低使用者等級(若省略則為 free)。公開 API 調用將拒絕任何高於 free 的請求
requiredRuntimes 此工具可用的平台(macosios 等);若省略則代表適用於所有平台
riskTier 同意風險:low(預設)、mediumhigh
riskExplanation riskTier 升高的易於理解之原因
requiresApproval 當工具需要每次調用都經過使用者核准時為 true — 公開 API 調用將拒絕這些請求

直接調用工具:

POST /v1/tools/calculator/invoke
Content-Type: application/json

{ "input": { "expression": "sqrt(144) + 3^2" }, "threadId": "optional-thread-id" }

傳回 { result }。輸入將根據工具的架構進行驗證 — 無效輸入將傳回 422 及其詳情。如果工具需要執行緒範圍的上下文(例如附件查詢),請傳遞選用的 threadId

門檻限制 — 公開 API 拒絕的情況:

  • 等級限制工具 (metadata.requiredTier !== 'free') → 403。代理程式迴圈會根據使用者工作階段檢查等級;公開 API 沒有攜帶等級上下文,因此保守政策是拒絕。請改為使用具有正確等級的代理程式透過 POST /v1/runs 進行。
  • 需要核准的工具 (metadata.approval.requiresApproval === true) → 403。因為沒有人在迴圈中進行詢問。請透過 POST /v1/runs 調用(這會向使用者顯示提示),或在應用程式中將工具核准模式設置為 approve_all 以繞過。
  • 遠端 MCP 工具501 並引導使用 /v1/runs(它們需要代理程式子程序傳輸)。

視覺與影像使用工具: 請先透過 POST /v1/attachments 上傳,然後在 input 中傳遞傳回的附件 ID(例如 { "input": { "attachment_id": "att_abc", "prompt": "這張圖片裡有什麼?" } })。工具會透過 threadId 從儲存空間讀取二進位檔案;您不需要內聯傳遞位元組數據。

連接器

管理 OAuth 整合 — Google、Microsoft、GitHub、Notion、Slack 等。

瀏覽可用的整合:

GET /v1/connectors/catalog

回傳所有已註冊的 OAuth 提供商及其名稱、類別和預設權限範圍。

列出您已連接的帳戶:

GET /v1/connectors

回傳目前個人資料的活動連線。Token 絕不會 被公開 — 僅回傳元數據(提供商、電子郵件、狀態、權限範圍、時間戳記)。

獲取單一連線:

GET /v1/connectors/{id}

回傳一個連線的元數據。Token 絕不會被公開。

檢查連線健康狀況:

POST /v1/connectors/{id}/test

回傳 { health: { status, isTokenExpired, canRefresh } }

移除連線:

DELETE /v1/connectors/{id}

建立新連線需要透過應用程式 UI 或 /auth/* 路徑進行互動式 OAuth 流程。

觸發器

排程代理自動執行 — 每日簡報、每週報告、基於間隔的監控。

每個觸發器都有一個 kind 辨識碼:schedule(預設 — 按時鐘觸發)、webhook(當外部服務向 webhook 路徑發送 POST 時觸發)或 messaging(從連接的訊息配接器觸發 — 例如符合頻道過濾條件的傳入 Slack/Discord 訊息)。

列出觸發器:

GET /v1/triggers

回傳 { triggers: [...] }。每個項目包含其 kind、排程和特定類型的欄位(例如 webhook 觸發器的 webhookSecret/webhookPath,訊息觸發器的 messagingAdapterId/messagingChannelFilter)。

獲取單一觸發器:

GET /v1/triggers/{id}

建立排程觸發器:

POST /v1/triggers
Content-Type: application/json

{
  \"name\": \"Morning Briefing\",
  \"prompt\": \"總結我的未讀郵件和今天的行事曆\",
  \"modeId\": \"general\",
  \"schedule\": { \"type\": \"daily\", \"time\": \"08:00\" }
}

支援的排程類型:

  • { \"type\": \"interval\", \"minutes\": 60 } — 每 N 分鐘(最小 15,最大 1440)
  • { \"type\": \"daily\", \"time\": \"09:00\" } — 每天特定時間
  • { \"type\": \"weekly\", \"day\": \"mon\", \"time\": \"09:00\" } — 每週
  • { \"type\": \"weekdays\", \"time\": \"08:30\" } — 週一至週五
  • { \"type\": \"daysOfWeek\", \"days\": [\"mon\", \"wed\", \"fri\"], \"time\": \"10:00\" } — 特定日期
  • { \"type\": \"monthly\", \"dayOfMonth\": 1, \"time\": \"09:00\" } — 每月
  • { \"type\": \"manual\" } — 僅在透過 API 觸發時執行

手動啟動觸發器:

POST /v1/triggers/{id}/fire

回傳 202 以及該次執行的 threadId

更新或刪除:

PATCH /v1/triggers/{id}
DELETE /v1/triggers/{id}

Webhooks

Webhook 觸發器允許外部服務(CI/CD、監控、表單建立器)透過 HTTP 觸發代理執行。

建立 Webhook 觸發器:

POST /v1/triggers
Content-Type: application/json

{
  \"name\": \"Deploy hook\",
  \"prompt\": \"發生了一次部署:{{webhook.body}}\",
  \"modeId\": \"general\",
  \"kind\": \"webhook\"
}

回傳 201 以及 webhookSecretwebhookPath。請儲存該密鑰 — 您將需要它來簽署負載。

發送 Webhook:

# 計算原始請求主體的 HMAC-SHA256
SIGNATURE=$(echo -n '{\"repo\":\"my-app\",\"branch\":\"main\"}' | openssl dgst -sha256 -hmac \"$WEBHOOK_SECRET\" | awk '{print $2}')

POST /v1/webhooks/{triggerId}
Content-Type: application/json
X-Webhook-Signature: $SIGNATURE

{\"repo\": \"my-app\", \"branch\": \"main\"}

Webhook 端點不需要 Bearer 驗證 — 它使用 HMAC 驗證。回傳 202 以及分派執行的 threadId。觸發提示詞中的 {{webhook.body}} 佔位符將被替換為原始請求主體。

訊息觸發器

當連接的訊息配接器(例如透過社群中心安裝的 Slack 或 Discord 整合)收到符合觸發器過濾條件的傳入訊息時,訊息觸發器會啟動。使用 kind: \"messaging\" 建立:

POST /v1/triggers
Content-Type: application/json

{
  \"name\": \"Mention responder\",
  \"prompt\": \"提供有用的回覆給:{{message.text}}\",
  \"modeId\": \"general\",
  \"kind\": \"messaging\",
  \"messagingAdapterId\": \"slack-team-acme\",
  \"messagingChannelFilter\": \"#support\"
}

配接器負責將符合的事件分派到觸發器中;messagingChannelFilter 取決於具體的配接器。

自訂函數

建立代理可以調用的專屬工具。函數使用 JavaScript 或 Python 編寫,並在沙箱中執行。

列出函數:

GET /v1/functions

建立函數:

POST /v1/functions
Content-Type: application/json

{
  "name": "calculate_bmi",
  "description": "根據身高和體重計算身體質量指數",
  "language": "javascript",
  "source": "return { bmi: (input.weightKg / (input.heightM * input.heightM)).toFixed(1) };",
  "inputSchema": {
    "type": "object",
    "properties": {
      "weightKg": { "type": "number" },
      "heightM": { "type": "number" }
    },
    "required": ["weightKg", "heightM"]
  }
}

JavaScript 函數接收 input 並必須返回結果。Python 函數則設定 result 變數:

# Python 範例
result = {"bmi": round(input["weightKg"] / (input["heightM"] ** 2), 1)}

直接執行函數:

POST /v1/functions/{id}/execute
Content-Type: application/json

{ "input": { "weightKg": 75, "heightM": 1.80 } }

安全性: JavaScript 在 Node 的 vm 沙箱中運行(無檔案系統或網路存取,10 秒超時)。Python 作為子程序運行,超時時間為 30 秒。兩者在執行前都會驗證輸入。

更新或刪除:

PATCH /v1/functions/{id}
DELETE /v1/functions/{id}

技能

技能是儲存的提示詞,代理程式可以參考這些提示詞,並從空白對話視圖中快速啟動。透過套件安裝管理的中心安裝技能(Hub-installed skills)「不」包含在此處——僅列出並可編輯使用者創作的技能。

列出技能:

GET /v1/skills

回傳活動設定檔中使用者創作的 { skills: [...] }。已標記刪除、中心覆蓋和同步陰影技能會被過濾掉。

取得單一技能:

GET /v1/skills/{id}

建立技能:

POST /v1/skills
Content-Type: application/json

{
  "prompt": "用 3 個列點總結此頁面。",
  "tags": ["utility", "summarize"],
  "isFavorite": true,
  "modes": ["general"],
  "displayName": "快速總結",
  "description": "活動頁面的三點式摘要"
}

prompt 為必填。modes(選填)將技能範圍限定於特定的代理程式 ID;若省略則適用於所有模式。回傳 201 以及新技能(包含伺服器分配的 idcreatedAtupdatedAt)。

更新技能:

PATCH /v1/skills/{id}
Content-Type: application/json

{ "prompt": "更新後的提示詞", "isFavorite": false }

可修補欄位:prompttagsmodesdisplayNamedescriptionisFavorite。嘗試修補中心覆蓋技能會回傳 404

刪除技能:

DELETE /v1/skills/{id}

透過標記(tombstone)進行軟刪除。回傳 204。中心覆蓋技能會回傳 404——請改為解除安裝來源套件。

工作流

在 DAG(有向無環圖)中編排多個代理 —— 盡可能平行執行步驟,並將早期步驟的輸出饋送到後續步驟中。

驗證工作流圖表:

POST /v1/workflows/validate
Content-Type: application/json

{
  "graph": {
    "nodes": [
      { "id": "research", "agentId": "general", "prompt": "研究可再生能源趨勢" },
      { "id": "analyze", "agentId": "general", "prompt": "研究競爭對手定價" },
      { "id": "report", "agentId": "general", "prompt": "撰寫一份結合以下內容的報告:{{outputs.research}} 和 {{outputs.analyze}}", "dependsOn": ["research", "analyze"] }
    ]
  }
}

返回 { valid: true/false, errors: [...] }。檢查循環引用、重複 ID 以及缺失的依賴引用。

執行工作流:

POST /v1/workflows/execute
Content-Type: application/json

{
  "graph": {
    "nodes": [
      { "id": "research", "agentId": "general", "prompt": "研究可再生能源趨勢" },
      { "id": "summarize", "agentId": "general", "prompt": "總結:{{outputs.research}}", "dependsOn": ["research"] }
    ]
  }
}

返回 { status: "completed", outputs: { research: "...", summarize: "..." }, nodeResults: {...} }

獨立節點(無共享依賴)會平行執行。節點提示詞中的 {{outputs.nodeId}} 佔位符將被替換為指定上游節點的內容輸出。每個節點都是一次完整的代理執行,因此它可以使用工具、瀏覽網頁並存取目標代理的所有功能。

知識庫

將文件組織成可搜尋的集合,供代理參考。

列出知識庫:

GET /v1/knowledge/bases

建立知識庫:

POST /v1/knowledge/bases
Content-Type: application/json

{ "name": "研究論文" }

返回 201 以及新的知識庫 ID。

上傳文件到知識庫:

POST /v1/knowledge/bases/{id}/documents
Content-Type: application/json

{
  "fileName": "research-paper.pdf",
  "contentType": "application/pdf",
  "dataUrl": "data:application/pdf;base64,JVBERi0xLjQ...",
  "description": "2026 年可再生能源趨勢"
}

dataUrl 欄位是一個 base64 編碼的資料 URL。返回 201 以及文件元數據。

列出知識庫中的文件:

GET /v1/knowledge/bases/{id}/documents

在知識庫中搜尋:

POST /v1/knowledge/bases/{id}/search
Content-Type: application/json

{ "query": "可再生能源" }

根據檔案名稱和描述返回匹配的文件。語義(向量)搜尋將在未來版本中推出。

刪除文件或知識庫:

DELETE /v1/knowledge/bases/{id}/documents/{docId}
DELETE /v1/knowledge/bases/{id}

匯出與匯入代理

將代理作為可攜式套件分享 —— 跨裝置、團隊或社群中心。

匯出代理:

POST /v1/agents/{id}/export

返回一個 JSON 套件,其中包含代理定義、工具需求(衍生自啟用的工具)、連接器需求(需要哪些 OAuth 提供商)和觸發器範本。同步元數據會被移除 —— 該套件是一個乾淨、獨立的藍圖。

匯入代理:

POST /v1/agents/import
Content-Type: application/json

{
  \"package\": {
    \"$schema\": \"caiioo.agent.package/v1\",
    \"agent\": {
      \"id\": \"shared-research-agent\",
      \"branding\": { \"name\": \"研究代理\", \"description\": \"來自團隊\" },
      \"defaultSettings\": { \"systemPrompt\": \"你負責研究事物。\" },
      \"settingLevels\": {}
    },
    \"toolRequirements\": [
      { \"toolId\": \"web_browsing\", \"enabled\": true },
      { \"toolId\": \"search_tools\", \"enabled\": true }
    ]
  }
}

返回 201 以及安裝的代理。若 ID 與內建或現有代理衝突,則返回 409

錯誤處理

API 使用標準 HTTP 狀態碼:

代碼 意義
200 成功
201 已建立
202 已接受(非同步操作已開始)
204 已刪除(無內容)
400 錯誤請求 — 請檢查 error 欄位了解詳情
401 未授權 — 遺失或無效的對話密鑰
403 禁止存取 — 例如嘗試修改內建代理
404 找不到
409 衝突 — 例如代理 ID 已存在
422 驗證錯誤 — 輸入不符合工具結構描述
429 速率限制 — 請參閱身份驗證章節中的速率限制預算
500 伺服器錯誤 — 請檢查 error 欄位
501 未實作 — 功能存在但無法以此方式使用
503 服務不可用 — 儲存或提供商未就緒

所有錯誤回應均包含 { \"error\": \"人類可讀的訊息\" }

快速入門範例

這是一個完整的工作流:建立代理、執行它並串流結果。

# 1. 建立自訂代理
curl -X POST http://localhost:3847/v1/agents \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "quick-summarizer",
    "branding": { "name": "快速總結器" },
    "defaultSettings": {
      "systemPrompt": "用 3 個列點簡潔地總結任何輸入。",
      "enabledTools": { "web_browsing": true }
    },
    "settingLevels": {}
  }'

# 2. 非同步執行
RUN=$(curl -s -X POST http://localhost:3847/v1/runs \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "agentId": "quick-summarizer", "input": { "message": "總結 https://zh.wikipedia.org/wiki/人工智能" }, "mode": "async" }')

RUN_ID=$(echo $RUN | jq -r '.runId')

# 3. 串流事件
curl -N http://localhost:3847/v1/runs/$RUN_ID/events \
  -H "Authorization: Bearer $API_TOKEN"

# 4. 匯出代理以供分享
curl -X POST http://localhost:3847/v1/agents/quick-summarizer/export \
  -H "Authorization: Bearer $API_TOKEN"

This guide is maintained by the Caiioo team using Slate, our built-in editor.