# getoat 中文文档

规范地址：https://npmcn.com/package/getoat/

版本：0\.1\.1
npm 元数据更新时间：2026-11-03T16:09:34.963Z
中文译文更新时间：2026-11-03T19:39:53.720Z
软件包许可：MIT

本文由上游 README 机器翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/getoat
原文对照：https://npmcn.com/package/getoat/?lang=original
项目主页：https://getoat.sh/
源码仓库：https://github.com/oatdotagent/OAT

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：336 kB，59 个文件
- 模块格式：ES Module
- TypeScript 类型：未声明
- Node.js 要求：^22\.13\.0 \|\| \>=24
- 运行依赖：9 个
- 首次发布：2026-11-03T15:47:12.367Z
- 最新版本发布：2026-11-03T16:09:34.815Z
- 已发布版本数：3（近 12 个月 3 个）

## 中文简介

在您自己的计算机上跨提供商运行AI工作流，具有自动回退和验证输出。

## 安装

```sh
npm install getoat
```

也可以使用：`pnpm add getoat`、`yarn add getoat`、`bun add getoat`

## README

# 人工智能代理基础设施后端

一个TypeScript/Fastify后端，用于协调对外部AI和数据提供程序的调用。它运行声明性工作流，根据显式标准验证其输出，并记录所有内容以供审计和可观察性。

它是 **不** 代理运行时。没有模型决定控制流。每个步骤和依赖项都固定在存储的工作流定义中，实际工作委托给外部提供者。

## 在你的电脑上运行

这个 `getoat` 命令使用您自己的提供程序密钥在您自己的机器上一起运行API和控制台。它会监听 `127.0.0.1` 只有，你的钥匙和数据留在里面 `~/.getoat` (或 `GETOAT_HOME`）.

```bash
npx getoat          # first run asks for your API keys, then opens the Console
npx getoat --mock   # try it with labelled sample output, no keys needed
```

需要Node.js 22.13或更新版本。提供程序的使用由每个提供程序对您自己的密钥计费。

| 命令 | 目的 |
| --- | --- |
| `getoat` | 启动OAT并打开控制台(`--port`， `--no-open`， `--mock`） |
| `getoat setup` | 添加或更改提供程序API密钥 |
| `getoat token` | 打印您的本地访问令牌 |

## 快速启动

```bash
npm install
cp .env.example .env
npm run token:create -- alice admin   # put the printed "alice:admin:<hash>" into AUTH_TOKENS
npm run migrate                       # optional; the server also migrates on start
npm run dev                           # http://127.0.0.1:3000/api/v1/health
```

要尝试没有任何提供程序密钥的工作流，请设置 `ENABLE_MOCK_PROVIDERS=true` (开发)。模拟输出带有前缀 `[MOCK]`，每张唱片都贴上了标签 `isMock: true`。

| 脚本 | 目的 |
| --- | --- |
| `npm run dev` | 观看模式（tsx） |
| `npm run build` / `npm start` | 编译, `dist/` /运行编译服务器 |
| `npm test` | 单元+集成测试（模拟所有外部调用） |
| `npm run typecheck` / `npm run lint` | 输入check / ESLint |
| `npm run migrate` | 应用数据库迁移 |
| `npm run token:create -- <user> [admin|user]` | 生成一个API令牌+ its `AUTH_TOKENS` 条目 |

要求节点≥22.13（使用内置） `node:sqlite`;在Node 24上开发的)。

## 体系结构

```
src/
  api/            API gateway: Fastify app, envelope, error handling, auth hooks, routes (/api/v1)
  auth/           Bearer-token auth (hashed tokens), roles → permissions, ownership scoping
  config/         Strict env validation (zod) + .env loader
  providers/      Provider Manager, capability contracts, adapters (anthropic, gemini, jina, tavily, exa, github, mock)
  orchestration/  Workflow definition schema, static validation (DAG/refs), templates, coordinator
  verification/   JSON Schema + acceptance-criteria engine with evidence
  observability/  HTTP metrics (provider metrics are persisted)
  storage/        SQLite (node:sqlite), migrations, repositories
  lib/            Errors, secret redaction, SSRF guard, safe JSON paths
```

**请求路径:** 网关（请求ID→CORS/头盔→速率限制→auth→权限→zod验证）→路由→存储库/协调器→ProviderManager→适配器→外部API。

**供应商管理器。** 每个功能都有一个输入/输出合约(`providers/capabilities.ts`）. 经理:

-   验证输入
-   为URL输入运行SSRF预飞行
-   使用配置的路由选择提供程序（首先是健康的提供程序）
-   应用每次尝试超时，AI文本生成时间更长(`LLM_TIMEOUT_MS`）
-   重试超时，429秒，5xx和网络错误与指数回退和抖动，荣誉 `Retry-After`
-   根据合约验证适配器的输出
-   将功能限制为中指定的提供程序 `PROVIDER_ROUTING` (例如 `llm.generate=gemini`）. 路由是严格的：如果没有配置路由提供程序，则功能不可用，API将命名缺失的设置，不会静默切换到另一个提供程序或模拟。
-   只有在标记了功能后才回退到下一个提供者 `fallbackCompatible`： `web.search`， `web.extract` 和 `text.rerank`。 `text.embed` 被排除在外，因为来自不同供应商的矢量是不可互换的，和 `llm.generate` 和 `github.repo` 也被排除在外。
-   将错误归一化为代码，例如 `timeout`， `rate_limited`， `auth_failed`， `malformed_response`， `refused`， `blocked_url` 和其他人
-   跟踪被动运行状况并保存每个呼叫的延迟、尝试、使用和估计费用

**编排。** 工作流是包含多达50个步骤的DAG。每一步都是一个功能调用 `input` 可以引用 `{{input.*}}` 或 `{{steps.<dep>.output.*}}`． 验证拒绝循环、未知依赖项和对非依赖项的引用。协调器:

-   并行运行独立的步骤(`maxParallelism`）
-   跳过失败步骤的依赖项
-   支持 `continueOnError`、取消、执行超时和全局并发上限
-   保存每个步骤的状态、持续时间、尝试、回退和错误

重新启动时，正在执行的执行将被标记 `interrupted`。

**验证。** 每一步都可以声明一个JSON Schema +标准： `required`， `min_items`， `max_items`， `string_length`， `contains`， `not_contains`， `equals`， `number_range` 和 `urls_in_step`． 最后一个是基础检查：输出中引用的每个URL必须出现在检索步骤的结果中。每张支票都与证据一起保存。

A验证记录 `factualClaimsVerified: false` 每一次，它的总结分为三件事：

-   **结构的一致性:** 输出与声明的模式和标准匹配。
-   **引文跟踪:** 引用的url实际上是由检索步骤返回的。
-   **事实真相:** 从来没有被这个热机建立过。

用户模式不受信任。 `pattern` 和 `patternProperties` 被拒绝（ReDoS风险），并且只有本地 `$ref`S是允许的。

## 空气污染指数(均在 `/api/v1`）

成功响应使用 `{ data, meta: { requestId, page? } }`． 错误使用 `{ error: { code, message, details? }, meta: { requestId } }`． 每个回应都有一个 `x-request-id` 头;您可以发送自己的（8-128个字符的） `[A-Za-z0-9._-]`）.

| 方法与路径 | 身份验证 | 目的 |
| --- | --- | --- |
| `GET /health` | 公共 | 活性 |
| `GET /health/ready` | 公共 | DB +迁移准备（如果未准备好，则为503） |
| `GET /providers` | 用户 | 具有输入/输出JSON模式的提供程序（已配置/运行状况）和功能 |
| `GET /providers/health` | 用户 | 被动提供者健康状况 |
| `POST /providers/health/probe` | 管理 | 主动探针，在没有支付配额的情况下可用（Anthropic模型查找，GitHub） `/rate_limit`）; 经审计的 |
| `POST /workflows/validate` | 用户 | 在不保存的情况下验证草稿：错误、平行阶段、准备情况 |
| `POST /workflows` | 用户 | 创建工作流（无效为422，使用禁用功能为403） |
| `GET /workflows` | 用户 | 列出自己的工作流（admin: all）； `limit`， `offset` |
| `GET /workflows/:id` | 业主/管理 | 得到工作流程 |
| `PUT /workflows/:id` | 业主/管理 | 替换定义和凹凸 `version` （无效的422，不允许的403）；过去的处决保留了他们执行的版本 |
| `DELETE /workflows/:id` | 业主/管理 | 永久删除工作流、其执行和验证（当运行处于活动状态时）；提供者统计信息和审计事件将被保留 |
| `POST /workflows/:id/validate` | 业主/管理 | 对现有供应商进行复查；可选 `{ input }` 验证对 `inputSchema` |
| `POST /workflows/:id/executions` | 业主/管理 | 开始执行 `{ input }` → **202** `{ id }`;422输入错误，409提供程序不可用 |
| `GET /executions` | 用户 | 列出自己的执行情况；过滤器 `workflowId`， `status` |
| `GET /executions/:id` | 业主/管理 | 执行+每步运行（状态、提供者、尝试、输出、错误、验证id） |
| `POST /executions/:id/cancel` | 业主/管理 | 取消正在进行的执行（409） |
| `GET /verifications/:id` | 业主/管理 | 检查、证据和评估 |
| `GET /metrics` | 管理 | HTTP延迟/状态、提供者调用/错误/令牌/成本、执行计数(`windowHours`） |
| `GET /audit-events` | 管理 | 审计跟踪 |

其他用户拥有的记录返回404，因此无法探测id。

### 示例工作流

```json
{
  "name": "Research brief",
  "inputSchema": { "type": "object", "required": ["topic"], "properties": { "topic": { "type": "string" } } },
  "steps": [
    { "id": "search", "capability": "web.search", "input": { "query": "{{input.topic}}", "count": 5 } },
    {
      "id": "summary", "capability": "llm.generate", "dependsOn": ["search"],
      "input": { "prompt": "Summarize {{input.topic}} using only these results and cite URLs: {{steps.search.output.results}}" },
      "verification": {
        "criteria": [{ "type": "urls_in_step", "path": "text", "sourceStep": "search" }],
        "required": false
      }
    }
  ]
}
```

## 供应商

| 提供者 | 功能 | 时启用 | 笔记 |
| --- | --- | --- | --- |
| Anthropic（官方SDK） | `llm.generate` | `ANTHROPIC_API_KEY` | 默认的 `claude-opus-5-5`,明确 `effort`，服务器端拒绝回退；拒绝表面上是 `refused`． 根据公布的每个令牌费率估算的成本。 |
| 谷歌双子座 | `llm.generate` | `GEMINI_API_KEY` (可选 `GEMINI_MODEL`、默认 `gemini-3.6-flash`； `GEMINI_MAX_OUTPUT_TOKENS`（默认为8192） | 提供免费层。主要从 [aistudio.google.com/apikey](https://aistudio.google.com/apikey)，发送到 `x-goog-api-key` 头（从不在url中）。在免费层，谷歌可以使用提示和输出来改进其产品。没有估算成本，因为API不报告键的层。安全块表面为 `refused`。 |
| 胜者人工智能 | `text.embed`， `text.rerank`， `web.extract` | `JINA_API_KEY` (读者也可通过 `JINA_READER_KEYLESS=true`） | 形状的 `api.jina.ai/openapi.json`;读者通过 `r.jina.ai` JSON模式。 |
| Tavily | `web.search` | `TAVILY_API_KEY` | 主要搜索: `POST https://api.tavily.com/search` 与 `Authorization: Bearer`， `search_depth: basic` （每次呼叫1学分）。主要从 [app.tavily.com](https://app.tavily.com/)． a429荣誉 `Retry-After`． HTTP 432/433（已达到计划或现收现付限制）显示为 `quota_exceeded`未重试，退到Exa。空结果列表是有效的输出(使用 `min_items` 需要结果的验证)。管理活动探针使用 `GET /usage`， tily将其限制在每10分钟10个请求。 |
| 穰 | `web.search` | `EXA_API_KEY` | 回退搜索;报告 `costDollars`。 |
| GitHub休息 | `github.repo` | `GITHUB_TOKEN` | 只读的。 |
| 模拟 | 所有 | `ENABLE_MOCK_PROVIDERS=true` | Dev /测试;生产中被拒绝。 |

自由层限制改变。在依赖每个提供商之前，请检查它们的仪表板。集成时：Jina为新密钥提供免费令牌，而Reader在没有密钥的情况下允许20 RPM。Exa为新账户提供免费积分。tily开发键限制为每分钟100个请求；在app.tavily.com上查看你的每月信用额度。

## 安全总结

-   严格的环境验证。在生产中，它需要 `AUTH_TOKENS` 并拒绝开发绕过、模拟提供程序和通配符CORS。
-   只配置API令牌的SHA-256哈希值，并且在恒定时间内比较它们。
-   角色映射到显式权限；非管理员用户的范围仅限于他们拥有的记录。每个用户允许列出每种功能(`USER_ALLOWED_CAPABILITIES`）.
-   只有json的请求体有大小限制，并且在每个路由上进行验证。
-   每个凭证的速率限制，对执行开始和探测有更严格的限制。
-   SSRF防护装置 `web.extract`：
    -   端口80/443上只有http， URL中没有凭据
    -   内部主机名被阻止
    -   解析DNS，拒绝私有地址、环回地址、链路本地地址、元数据地址和映射地址
    -   可选allowlist和denylist
-   秘密从日志、持久化错误和审计细节中编校：配置的键值、通用键格式、承载头和私钥形状的十六进制。日志从不包含请求主体或授权标头。
-   不存在区块链或财务功能，并且GitHub适配器是只读的。

## 网页前端(`web/`）

登陆页面(`/`)和控制台(`/console/`)都是用Vite构建的普通TypeScript。通过vitest， Vite已经在工具链中了，所以没有添加UI框架。fasttify为构建提供服务 `web/dist` 基于与API相同的来源，具有严格的CSP，对散列资产进行不可变缓存，并且对静态文件没有速率限制。

| 命令 | 目的 |
| --- | --- |
| `npm run build` | 构建服务器(`dist/`)和前端(`web/dist/`） |
| `npm run dev` + `npm run dev:web` | 后端：3000，Vite开发服务器：5173代理 `/api` |
| `npm run test:e2e` | 后 `npm run build`：实时浏览器检查安装Chrome/Edge (`CHROME_PATH` 覆盖)在320-1440px |

-   **登录页面:** 英雄的身份牌读大众 `/health` 和 `/health/ready` 端点。仪表板预览使用样例值，并以这种方式进行标记。
-   **控制台:** 使用个人API令牌登录。它被保存在 `sessionStorage` 仅针对当前选项卡，而提供程序键永远不会到达浏览器。控制台包括：
    -   **概述:** 实时提供程序运行状况、功能和活动探测（仅限管理员）
    -   **工作流程:** 模板、服务器端验证和准备
    -   **执行:** 实时轮询、取消和验证证据
    -   **指标:** 管理员只
-   **模拟数据:** mock提供程序生成的任何东西都被标记为mock。

## 前端集成（定制客户端）

1.  为前端的用户生成令牌 `npm run token:create -- <user> user` 并将打印的条目添加到 `AUTH_TOKENS`． 将前端原点添加到 `CORS_ORIGINS`。
2.  发送 `Authorization: Bearer <token>` 如果可以的话，从服务器端代理或BFF发送，因此令牌永远不会到达浏览器。对于本地开发，直接调用API是可以的。
3.  呼叫 `GET /api/v1/providers` 构建功能选择器。每个功能包括 `inputSchema` 和 `outputSchema` (JSON模式), `available` 和 `allowedForCaller`。
4.  呼叫 `POST /api/v1/workflows/validate` 当用户编辑工作流时。显示 `errors[].path` 和 `message`，并进行渲染 `stages` 作为执行计划。
5.  呼叫 `POST /api/v1/workflows/:id/executions` 开始跑步：开始跑步民意调查 `GET /api/v1/executions/:id` 直到 `status` 是 `succeeded`， `failed`， `cancelled` 或 `interrupted`． 目前还没有推送频道。
6.  的步骤 `verificationId`，显示验证 `assessment.summary` 一字不差，永远不要把模型输出说成是“验证过的”。徽章结果如下 `isMock` 是真的。

## 常见问题

### getoat 是什么？

在您自己的计算机上跨提供商运行AI工作流，具有自动回退和验证输出。

### 如何安装 getoat？

在项目目录运行 npm install getoat，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 getoat，可以用 npx getoat 直接运行。

### getoat 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/getoat 是否存在。

### getoat 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### getoat 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js ^22\.13\.0 \|\| \>=24。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### getoat 可以商用吗？

getoat 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### getoat 还在维护吗？

最新版本 0\.1\.1 发布于 2026/11/04（今天）；至今共发布 3 个版本，其中过去 12 个月发布了 3 个；首次发布于 2026/11/03。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

