本文档由英文原版机器翻译而成。如果翻译版本与英文原版之间存在任何冲突,请以英文原版为准。 阅读英文原版


公共 API

Caiioo 包含一个 REST API,允许您通过编程方式控制一切:运行智能体、管理工具、安排任务等。该 API 运行在为桌面应用和浏览器桥接提供支持的同一个本地服务器上。

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

身份验证: 提供两种身份验证方式,均由设置中的 API 开关控制:

针对外部使用者(脚本、集成、curl): 在“设置 > 连通性 > API 访问”中设置 API 访问令牌,然后将其用作 Bearer 令牌:

curl -H "Authorization: Bearer 您的_API_TOKEN" http://localhost:3847/v1/providers

针对本地应用(自动): Caiioo 桌面应用、浏览器扩展和移动应用通过现有的中继身份验证标头(x-relay-auth;HTTP 标头不区分大小写)自动完成验证。无需手动设置——应用会在后台自动处理。中继验证请求由于已被信任,会绕过“启用公共 API”开关;只有 Bearer 令牌请求受该开关控制。

设置: API 访问是一项 Pro 功能——升级到 Pro 版后,“设置”中才会显示“API 访问”部分。

  1. 打开 Caiioo 设置 > 连通性 > API 访问
  2. 开启启用公共 API
  3. 设置一个 API 访问令牌(任意字符串——请像密码一样妥善保管)
  4. 在所有 API 请求中使用该令牌

API 可在 localhost 上使用,也可通过私有中继使用。访问 GET /v1/auth/info(无需身份验证)可查看当前状态和设置说明。

速率限制: 每个 /v1/* 请求按客户端 IP 进行速率限制——读取请求为每分钟 100 次 GET 请求,写入请求合计为每分钟 30 次(POST / PATCH / DELETE)。超出限制的请求将收到 429。Webhook 推送(POST /v1/webhooks/:id)不需要 Bearer 认证,不受这些限制约束。

个人资料

单个设备可以保存多个用户个人资料(例如个人 + 工作)。API 允许外部脚本检查可用资料并在执行其他工作前切换活动资料。个人资料的创建、更新和删除有意不通过公共 API 暴露 —— 这些流程属于应用的引导界面。

列出个人资料:

GET /v1/profiles

返回 { profiles: [...] },每个未删除的资料对应一个条目。每个条目包含 id, name, email, avatarUrl, tier, accessibleModes, license, organization, preferences, onboardingComplete, createdAt, lastAccessedAt。带有令牌的字段 (serviceCredentials, oauthConnections) 和同步内部字段 (vectorClock, lastModifiedBy) 已被剥离。 使用 /v1/connectors 检查 OAuth 连接。

获取活动个人资料:

GET /v1/profiles/active

返回此服务器当前使用的 { profile }。所有作用于个人资料的 /v1/* 资源(线程、附件、设置、技能)均针对此资料操作。

切换活动个人资料:

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

{ \"profileId\": \"来自列表的用户-uuid\" }

返回新激活的 { profile }。如果 ID 不是已知资料,则返回 404。

Providers & Models

发现已配置的 LLM 提供商以及可用的模型。

列出提供商:

GET /v1/providers

返回所有支持的提供商类型。目前包括:anthropic、openai、google、openrouter、ollama、poe、mlx、perplexity、baseten、cloudflare。每个条目包含 type、displayName、icon、requiresApiKey、hasApiKey 以及一个包含以下标志的 capabilities 对象。

能力标志 含义
supportsVision 提供商可以接受图像输入
supportsPdfFile 提供商可以原生接受原始 PDF 文件内容块
supportsToolCalling 提供商支持函数/工具调用
supportsStreaming 提供商支持增量流式传输 token
supportsExtendedThinking 提供商提供推理/思考预算
supportsPromptCaching 提供商支持提示词缓存指令
nativeReasoningBlocks 提供商将思考过程作为原生消息块(而非文本)输出
requiresThoughtSignature 提供商要求将签名的思考 token 回传

能力标志镜像了每个提供商类的 readonly capabilities 字段(参见 src/shared/providers/*-provider.ts),并通过漂移哨兵测试进行验证 —— 请在运行时调用此端点,而不是硬编码矩阵。

关于 BYOK 提供商的说明:

  • perplexity 提供精选的 Sonar 模型列表(Perplexity 没有公开的 /models 端点)。
  • cloudflare (AI Gateway) 是 BYOK + 多供应商模式;模型列表由您的网关配置决定,/v1/providers/cloudflare/models 会返回空数组。请使用您自己的网关目录。

列出特定提供商的模型:

GET /v1/providers/openrouter/models

返回该提供商的模型目录。每个模型包含 id、displayName 以及可用的 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

通过墓碑机制进行软删除(跨设备同步)。返回 204。

运行智能体 (Running Agents)

这是核心功能 —— 调用智能体来处理消息。

请求体 — 支持的字段

字段 必填 描述
agentId 是 内置模式 ID(例如 general)或自定义智能体 ID
input.message 是 用户消息文本
input.attachments 否 附件 ID 数组(已通过 /v1/attachments 上传),用于附加到此轮对话
input.variables 否 单词运行的变量覆盖,将合并到智能体的变量解析器中
input.tabContext 否 作为页面上下文注入的自由格式字符串(由浏览器桥接使用)
input.messageId 否 客户端提供的消息 ID —— 在重试时用于去重
threadId 否 要继续的现有线程。如果省略,将创建并返回一个新线程
mode 否 "sync" 或 "async"。默认为 "async"

同步模式 (Synchronous Mode)

等待完整响应:

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

{
  "agentId": "general",
  "input": { "message": "What's the weather in Paris today?" },
  "mode": "sync"
}

智能体完成后返回 200 以及 { content, usage, status: "completed" }。如果智能体报错,则返回 500 以及 { error, status: "error" }。同步运行如果在 5 分钟 后仍未收到终止事件,将超时并返回 status: "error" —— 对于任何可能耗时更长的任务,请使用异步模式 + SSE。

异步模式 (Asynchronous Mode)

即发即弃 —— 适用于耗时较长的任务:

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

{
  "agentId": "my-research-agent",
  "input": { "message": "Write a 2000-word analysis of renewable energy trends" },
  "mode": "async"
}

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

轮询状态:

GET /v1/runs/{runId}

返回 { run: { runId, threadId, agentId, status, createdAt, content?, usage?, error? } }。状态为 running、completed、error 或 cancelled 之一。

实时流式事件 (SSE):

GET /v1/runs/{runId}/events

返回一个 text/event-stream,包含智能体发生的每一个事件:GENERATION_STARTED、STREAMING_CONTENT、工具调用、子智能体活动以及终止事件(GENERATION_COMPLETE、GENERATION_ERROR 或 GENERATION_CANCELLED)。

在终止事件之后,服务器会发送最后一个 SSE 帧,其 event: terminal 且数据负载为空,作为明确的流结束哨兵,然后关闭连接。客户端应将收到该帧(或连接关闭)视为停止读取的信号。

如果您在运行已经结束后才订阅,服务器将重放一帧类型为 RUN_SNAPSHOT 的数据,其中包含完整的最终 record,随后是 event: terminal 哨兵,然后关闭。

取消运行:

POST /v1/runs/{runId}/cancel

返回 { run: { ..., status: "cancelled" } }。

Threads

Threads 即对话。每一次智能体运行都发生在 Thread 中,且 Thread 会跨会话持久保存。API 允许你通过编程方式列出、读取、创建和管理 Thread。

列出所有 Thread(仅元数据):

GET /v1/threads

返回当前 Profile 的 { threads: [...] },其中 messages 已被移除(需要消息时请使用详情接口)。其他所有字段均被保留 —— id、title、createdAt、updatedAt、modeId、archived、使用统计,以及已设置的 subAgentHistories、anonymizerSnapshot、threadToolApprovals、threadVariables、threadToolOverrides、messagingBinding、scheduledTaskId。(更丰富的数据负载是 API 专有的 —— WebSocket 侧边栏广播使用更精简的格式以保持在传输限制内。)

获取包含完整消息的 Thread:

GET /v1/threads/{id}

返回完整的 Thread,包括其 messages 数组 —— 每一条用户消息、助手响应、工具调用和工具结果。

仅获取消息:

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 }

可更新字段:title、modeId、archived、lastUsedModel。更改会实时广播到侧边栏。

删除 Thread:

DELETE /v1/threads/{id}

软删除 Thread(用于同步的墓碑标记)。返回 204。删除的 Thread 会移至回收站,在清空回收站前可以恢复。

活动 Thread:

GET /v1/threads/active            # 返回 { threadId }
PUT /v1/threads/active            # Body: { "threadId": "..." }

回收站管理:

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

受保护的 Thread(通过数据保留开关保留)不会被清空回收站操作删除。

通过 API 继续对话: 要向现有 Thread 发送后续消息,请使用带有 Thread ID 的 POST /v1/runs:

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

返回当前配置文件的附件元数据。大字段(dataUrl, extractedContent, extractedImages)已被剥离 —— 请使用详情或内容端点获取这些字段。

列出特定线程的附件:

GET /v1/threads/{threadId}/attachments

获取附件元数据:

GET /v1/attachments/{id}

返回完整元数据,包括 extractedContent(OCR 文本、解析后的 markdown)、contentType、fileName、size 以及 hasContent 标志。原始二进制文件不包含在内 —— 请使用 /content 端点获取。

下载附件二进制文件:

GET /v1/attachments/{id}/content

返回带有正确 Content-Type 和 Content-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}

通过墓碑机制进行软删除。返回 204。

MCP Servers

管理您的 MCP (Model Context Protocol) 服务器连接 —— 这些服务器为智能体提供访问外部工具和数据源的权限。

列出已配置的服务器:

GET /v1/mcp-servers

返回当前配置文件下的所有 MCP 服务器配置。敏感字段(authToken、env、credentialId)将从响应中移除。

获取特定服务器配置:

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 请求接受的可选字段包括:command、args、env、url、description、transportType、authType、authToken、authHeader、headers、specType、specPath、timeoutMs、credentialId、oauthConnectionId、approval。服务器管理的字段(customOAuth、hubPackageId、profileId、connectorId、teamPublished、teamOrgId、vectorClock 等)无法通过 API 设置。

更新服务器:

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

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

可更新字段与 POST 允许列表一致(包括 credentialId 和 oauthConnectionId —— 方便在不删除并重新创建的情况下轮换 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

返回运行中的服务器进程及其 pid、startedAt 和 running 状态。

启动服务器:

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 公开的方法。

工具与工具包

浏览并调用 Agent 所使用的工具——网络浏览、搜索、日历、Gmail、Slate 等。

列出工具包(分组):

GET /v1/toolkits

返回按类别(Productivity、Search、Utilities 等)分组的内置工具,并将所有已连接的 MCP 服务器作为独立的工具包返回,且分别列出各自的操作(actions)。

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

GET /v1/tools
GET /v1/tools?source=embedded   # 仅限内置工具
GET /v1/tools?source=mcp        # 仅限 MCP 服务器工具

获取带有输入模式(input schema)的工具详情:

GET /v1/tools/calculator

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

字段 含义
inputSchema 工具输入的 JSON Schema——在调用前进行验证
actions 可选的子操作(例如 Slate 的 read/write);每个操作包含 id、displayName、description、可选的 requiredTier,以及当该操作需要先询问用户时的 requiresApproval: true(公开 API 调用会拒绝此类操作)
requiredTier 最低用户等级(若省略则为 free)。公开 API 调用会拒绝任何高于 free 的等级要求
requiredRuntimes 此工具可用的平台(macos、ios 等);省略 ⇒ 适用于所有平台
riskTier 许可风险等级:low(默认)、medium、high
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 }。系统会根据工具的 schema 验证输入——无效输入将返回带有详情的 422 错误,拼写错误的操作(action)也是如此:名称必须完全精准匹配(SEND_EMAIL 不等同于 send_email),系统不会做任何自动更正。如果工具需要线程级(thread-scoped)上下文(例如附件查询),请传入可选的 threadId。凡是将生成内容保存到对话中的工具(图像、视频、音乐和语音生成、python_run、GitHub 图像读取),都需要提供此参数:若未提供 threadId,则在生成任何内容或产生费用之前,调用就会被拒绝。结果将保存在该对话中,归属于您请求登录的 Profile 下,且该对话必须属于该 Profile(否则返回 403)。

权限拦截(Gating)——公开 API 拒绝的情形:

  • 受等级限制的工具(metadata.requiredTier !== 'free')→ 403。Agent 循环会根据用户会话检查等级;公开 API 未携带等级上下文,因此采取保守策略直接予以拒绝。请改用带有合适等级 Agent 的 POST /v1/runs。
  • 需要批准的工具(metadata.approval.requiresApproval === true)→ 403。调用流程中没有人工介入来进行确认。请通过 POST /v1/runs 调用,该方式会在应用程序中向用户弹出提示。
  • 针对每个具体操作(ACTION),在输入验证通过后——每个 403 响应都会指明具体的操作名称:
    • 在应用程序中需要先询问用户的操作(列在工具的 actionsRequiringApproval 中;对应 GET /v1/tools/:name 中的 actions[].requiresApproval)。如果某个操作是否需要批准取决于其参数,则仅当这些参数会触发应用程序询问时才会被拒绝——例如 agenda 的 create_event 仅在邀请参与者时才会询问,而 web_browsing 的 ingest_document 仅在将文档上传到 Google Drive 时才会询问(两者均为 Pro 级别操作,因此公开 API 目前无论如何都会因等级限制拒绝它们);
    • 自身 requiredTier 高于 free 的操作;
    • 在 Settings → Tool Configuration 中被关闭的操作(关闭别名对中的任一名称,例如邮件的 send_email / send_message,将同时关闭两者)。
  • 远程 MCP 工具 → 501,并提示使用 /v1/runs(它们需要 Agent 子进程传输机制)。

**视觉及使用图像的工具:**请先通过 POST /v1/attachments 上传,然后在 input 中传入返回的附件 ID(例如 { "input": { "attachment_id": "att_abc", "prompt": "What is in this image?" } })。工具会通过 threadId 从存储中读取二进制数据;无需内联传递字节数据。

连接器

管理 OAuth 集成 —— Google、Microsoft、GitHub、Notion、Slack 等。

浏览可用集成:

GET /v1/connectors/catalog

返回所有已注册的 OAuth 提供商及其名称、类别和默认作用域。

列出您的已连接账户:

GET /v1/connectors

返回当前个人资料的活动连接。令牌绝不会泄露 —— 仅返回元数据(提供商、电子邮件、状态、作用域、时间戳)。

获取单个连接:

GET /v1/connectors/{id}

返回一个连接的元数据(提供商、电子邮件、状态、作用域、时间戳)。令牌绝不会泄露。

检查连接健康状况:

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 以及 webhookSecret 和 webhookPath。请保存该密钥 —— 您需要用它来签署有效负载。

发送一个 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}

技能

技能是保存的提示词,智能体可以在空白对话视图中引用并快速启动。通过插件包安装的中心托管技能(由包安装管理)不包含在此处——仅列出并可编辑用户创作的技能。

列出技能:

GET /v1/skills

返回当前活动配置文件的用户创作技能 { skills: [...] }。已标记删除、中心覆盖和同步阴影技能会被过滤掉。

获取单个技能:

GET /v1/skills/{id}

创建技能:

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

{
  "prompt": "用 3 个要点总结此页面。",
  "tags": ["工具", "总结"],
  "isFavorite": true,
  "modes": ["general"],
  "displayName": "快速总结",
  "description": "对活动页面的三点式摘要"
}

仅 prompt 是必填项。modes(可选)将技能范围限定为特定的智能体 ID;省略则适用于所有模式。返回 201 及新技能(包括服务器分配的 id、createdAt、updatedAt)。

更新技能:

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

{ "prompt": "已更新的提示词", "isFavorite": false }

可修补字段:prompt、tags、modes、displayName、description、isFavorite。尝试修补中心覆盖技能将返回 404。

删除技能:

DELETE /v1/skills/{id}

通过标记位进行软删除。返回 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://en.wikipedia.org/wiki/Artificial_intelligence" }, "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.