Corsair 集成 CustomGPT:用 40 个类型安全操作管理 AI Agent 的完整指南
【免费下载链接】corsairConnect your users to their apps项目地址: https://gitcode.com/GitHub_Trending/corsa/corsair
@corsair-dev/customgpt是 Corsair 官方的 CustomGPT 插件包,把 CustomGPT.ai 的"以自有业务内容训练的自定义 ChatGPT 式 Agent"能力接入你的应用:安装插件后,即可通过corsair.customgpt.api.*调用 40 个类型安全操作,覆盖 Agent(项目)生命周期、知识库文档、数据源、会话消息、报告分析和用户管理。读完本文,你将掌握该插件的安装接入、API Key 认证机制、全部 40 个操作的分域用法、风险分级与权限控制,以及它背后的 REST 映射、错误重试和本地缓存实现。
插件是什么:Corsair 与 CustomGPT 之间的连接层
Corsair 是一个开源集成层,为 AI Agent 与应用之间提供 OAuth、Token 刷新、Webhook、限流等能力,并把每个连接的凭据加密存储在你自己的数据库中。customgpt插件是这个生态中面向 CustomGPT.ai 的接入包,其定位在 packages/customgpt/README.md 中写得很直接:CustomGPT plugin for Corsair。
从源码结构看,这个包是一份典型的 Corsair 插件实现(packages/customgpt/index.ts):
customgpt()工厂函数返回一个满足CorsairPlugin接口的插件对象,声明了id: 'customgpt'、认证配置、数据库 schema、端点树、端点元数据与错误处理器;- 端点按域组织成嵌套结构
projects / pages / sources / licenses / settings / personas / conversations / messages / reports / limits / user,调用时通过corsair.customgpt.api.<domain>.<action>()访问; - 每个端点都配有 zod 输入/输出契约(
customGPTEndpointSchemas)和风险级别元数据(customGPTEndpointMeta)。
在 package.json 中,插件的peerDependencies声明为corsair >= 0.1.0与zod ^4.1.13,这意味着你需要先安装 Corsair 核心 SDK 才能使用本插件。
安装与接入:三步把 CustomGPT 挂进你的应用
第一步:安装依赖
pnpm add corsair @corsair-dev/customgpt如果你的包管理器是 npm 或 yarn,命令等价替换即可。插件本身以dist/index.js作为主入口,类型声明一并随包发布(见 package.json)。
第二步:注册到 Corsair 实例
参照 Corsair 的通用插件接入方式(见 docs/guides/plugins.mdx),在创建createCorsair时把customgpt()加入plugins数组:
import { createCorsair } from 'corsair'; import { customgpt } from '@corsair-dev/customgpt'; export const corsair = createCorsair({ plugins: [ customgpt(), // ...其他插件 ], kek: process.env.CORSAIR_KEK!, // 信封加密用的密钥加密密钥 multiTenancy: false, // 单租户;多租户场景设为 true });第三步:配置 API Key
认证方式为 API Key(README 原文:Auth: API key. Corsair prompts your tenant for credentials on first use.)。首次使用时,Corsair 会提示你的租户提供凭据。密钥可以通过 Corsair 的通用配置流程提供——CLI、环境变量或应用内 setup 流程皆可(见 docs/concepts/api-key.mdx)。CLI 命令沿用 Corsair 的setup模式:
pnpm corsair setup --plugin=customgpt api_key=<your-customgpt-api-key>在单租户(solo)模式下,一个 API Key 被整个应用共享;开启multiTenancy: true后,每个租户持有各自的密钥,Corsair 会为每个租户分别加密存储。
底层认证逻辑:keyBuilder 源码解读
插件如何拿到 API Key?答案在 packages/customgpt/index.ts 的keyBuilder回调中:
keyBuilder: async (ctx, source) => { if (source === 'endpoint' && options.key) { return options.key; // ① 构造时直接注入静态 key } if (source === 'endpoint' && ctx.authType === 'api_key') { const res = await ctx.keys.get_api_key(); // ② 从加密存储中读取 if (!res) { throw new AuthMissingError('customgpt', 'api_key'); } return res; } throw new AuthMissingError('customgpt', 'api_key'); },也就是说:优先使用构造选项里的key,否则从 Corsair 的密钥存储中读取;两者都缺失时抛出AuthMissingError,提示租户先完成凭据配置。这正好印证了 README 中"首次使用提示租户提供凭据"的行为。
40 个操作全景:按域分组的使用指南
README 完整列出了 40 个操作(测试文件 packages/customgpt/api.test.ts 的用例注释也明确写着All 40 Operations)。每个操作都有唯一的 Operation ID(形如customgpt.api.<domain>.<action>)和风险级别。下面按域分组完整展开。
1. projects:Agent(项目)生命周期管理
CustomGPT API 把 Agent 称为"项目"(project),这是全插件的核心域。
| Operation | Operation ID | Risk | 说明 |
|---|---|---|---|
projects.list | customgpt.api.projects.list | read | 列出当前认证用户的所有 CustomGPT 项目(Agent),返回含 ID、名称、类型、聊天状态与时间戳的完整信息,支持page分页。用于发现可用 Agent 或遍历全部项目 |
projects.get | customgpt.api.projects.get | read | 获取单个 Agent 的完整配置与当前状态。用于检查处理进度、查看设置或读取元数据 |
projects.create | customgpt.api.projects.create | write | 通过 sitemap URL 或文件上传创建新 Agent,创建后立即开始处理内容以构建知识库。sitemap_path或file必须提供其一 |
projects.update | customgpt.api.projects.update | write | 更新 Agent 的名称或配置,不触碰知识库,返回完整更新后的项目信息 |
projects.delete | customgpt.api.projects.delete | destructive | 按 ID 永久删除 Agent。[DESTRUCTIVE · IRREVERSIBLE] |
projects.clone | customgpt.api.projects.clone | write | 克隆 Agent,完整复制其知识库、人设(persona)与设置。用于测试变体或模板化复用 |
projects.stats | customgpt.api.projects.stats | read | 获取 Agent 统计:会话总数、查询次数、文档统计与处理信息。用于监控 Agent 表现或生成用量报告 |
projects.plugins | customgpt.api.projects.plugins | read | 读取特定 Agent 的插件配置、状态与元数据 |
从 packages/customgpt/endpoints/projects.ts 可以看到这些操作的 REST 映射:projects.list对应GET /projects,projects.create对应POST /projects(multipart 表单),projects.clone对应POST /projects/{projectId}/replicate,projects.plugins对应GET /projects/{projectId}/actions。创建与更新操作会调用fileFormFields把 base64 文件解码为真正的File对象参与上传(见 packages/customgpt/endpoints/shared.ts)。
2. pages:知识库文档管理
CustomGPT API 把知识库中的文档称为"页面"(page)。
| Operation | Operation ID | Risk | 说明 |
|---|---|---|---|
pages.list | customgpt.api.pages.list | read | 列出 Agent 知识库中的所有文档,含网页、PDF 与上传文件。支持按抓取/索引状态过滤和分页,用于审计知识来源或验证文档入库 |
pages.delete | customgpt.api.pages.delete | destructive | 永久删除知识库中的文档,删除后 Agent 不再引用该内容。警告:不可撤销。[DESTRUCTIVE · IRREVERSIBLE] |
pages.reindex | customgpt.api.pages.reindex | write | 重新抓取并索引基于 URL 的文档以更新内容。仅对 URL 型文档生效,适合源内容变更时使用 |
pages.getMetadata | customgpt.api.pages.getMetadata | read | 获取文档元数据:标题、来源 URL、字数、自定义元数据字段 |
pages.updateMetadata | customgpt.api.pages.updateMetadata | write | 更新文档的自定义元数据字段(标题、描述、URL、图片等),用于给文档打标签、分类或补充组织信息 |
3. sources:数据源管理
数据源是知识库的"输入管道",可以是 sitemap、文件上传或集成。
| Operation | Operation ID | Risk | 说明 |
|---|---|---|---|
sources.list | customgpt.api.sources.list | read | 列出 Agent 连接的所有数据源(sitemap、Google Drive 文件夹、SharePoint 站点或上传文件),用于管理知识库内容来源 |
sources.add | customgpt.api.sources.add | write | 通过 sitemap URL、文件上传或集成添加数据源,创建后立即开始索引。适合接入文档、FAQ 或知识内容 |
sources.update | customgpt.api.sources.update | write | 更新数据源索引与同步设置:自动同步频率、抓取深度、文件过滤、刷新行为。可精细调优 sitemap 抓取(JavaScript 执行、图片提取)、控制同步增删页面、设置自定义刷新计划 |
sources.delete | customgpt.api.sources.delete | destructive | 删除数据源及其全部文档。[DESTRUCTIVE · IRREVERSIBLE] |
sources.update的能力在 schema/database.ts 的CustomGPTSourceSettings中有完整刻画:data_refresh_frequency取值never / daily / weekly / monthly / advanced,refresh_existing_pages取值never / always / if_updated,还包含executive_js(是否执行 JS)、create_new_pages、remove_unexist_pages、image_extraction_type(none / sync_from_sitemap)等开关。
4. licenses:许可证管理
许可证用于向最终用户分发 Agent 访问权。
| Operation | Operation ID | Risk | 说明 |
|---|---|---|---|
licenses.list | customgpt.api.licenses.list | read | 列出项目全部许可证,返回含 ID、类型、状态与时间戳的数组;项目无许可证或未启用该功能时返回空数组 |
licenses.get | customgpt.api.licenses.get | read | 按许可证 ID 获取单个许可证详情 |
licenses.update | customgpt.api.licenses.update | write | 更新许可证名称。前置条件:项目套餐需启用许可证、项目 ID 与许可证 ID 有效。本操作只改名称,其余属性不可修改 |
licenses.delete | customgpt.api.licenses.delete | destructive | 删除许可证,需要数字型项目 ID 与许可证 ID。操作是幂等的——即使许可证不存在(404)也视为成功;项目套餐需启用许可证功能。[DESTRUCTIVE · IRREVERSIBLE] |
5. settings:Agent 配置
| Operation | Operation ID | Risk | 说明 |
|---|---|---|---|
settings.get | customgpt.api.settings.get | read | 读取 Agent 配置:聊天头像、背景、默认提示词、示例问题、回答来源、语言与品牌偏好。注意:部分新建项目尚未初始化设置,会返回 404 |
settings.update | customgpt.api.settings.update | write | 更新 Agent 配置:人设指令、回答格式、引用风格、品牌与部署设置。只传要改的字段,未传字段保持原值 |
6. personas:人设版本管理
| Operation | Operation ID | Risk | 说明 |
|---|---|---|---|
personas.list | customgpt.api.personas.list | read | 列出 Agent 的人设版本历史。每次人设更新都会自动保存快照,结果分页。需要 Custom 套餐 |
personas.activate | customgpt.api.personas.activate | write | 恢复历史人设版本为当前生效版本。回滚会在历史中新增一条版本记录(不覆盖),保留完整审计轨迹。需要 Custom 套餐 |
7. conversations & messages:会话与消息
conversations.create是会话入口,消息操作全部挂在会话之下。
| Operation | Operation ID | Risk | 说明 |
|---|---|---|---|
conversations.create | customgpt.api.conversations.create | write | 为 Agent 创建新会话,返回 session ID 用于后续发送消息;可传name便于识别 |
messages.list | customgpt.api.messages.list | read | 读取会话全部消息(用户提问与 AI 回答),用于查看完整聊天历史;会话不存在或无消息时返回空列表 |
messages.get | customgpt.api.messages.get | read | 获取单条消息完整详情:用户提示、Agent 回答、时间戳、引用(citations)与附加元数据 |
messages.getTrustScore | customgpt.api.messages.getTrustScore | read | 获取消息的验证信任分:按回答主张被源文档支持的程度计算,分数越高表示回答越有据可依 |
messages.verify | customgpt.api.messages.verify | write | 触发事实核查流程,逐条比对消息主张与源文档,报告每条主张是支持、部分支持还是不支持的 |
messages.submitFeedback | customgpt.api.messages.submitFeedback | write | 为消息提交点赞/点踩反馈,记录用户满意度信号;可重复提交新值来更改反馈 |
从 packages/customgpt/endpoints/conversations.ts 可看到消息域的路由细节:messages.getTrustScore对应GET /projects/{projectId}/conversations/{sessionId}/messages/{promptId}/trust-score,messages.verify对应POST .../verify,messages.submitFeedback对应PUT .../feedback(请求体为{ reaction })。每个消息端点都会把结果镜像写入messages缓存,conversations.create的结果则按session_id写入conversations缓存。
8. reports:分析报告
| Operation | Operation ID | Risk | 说明 |
|---|---|---|---|
reports.getAnalysis | customgpt.api.reports.getAnalysis | read | 获取图表时间序列数据,支持按天/周聚合的会话数、查询数、每会话查询比等指标。用于生成使用报告、跟踪项目参与度、可视化聊天机器人趋势 |
reports.getConversations | customgpt.api.reports.getConversations | read | 获取会话分析:总会话数、平均每会话查询数等参与度统计 |
reports.getTraffic | customgpt.api.reports.getTraffic | read | 获取流量分析:独立访客数、会话数、地理分布与设备类型 |
reports.getIntelligence | customgpt.api.reports.getIntelligence | read | 获取 AI 分析的用户洞察:常见意图、情绪倾向、高频主题与新兴趋势 |
reports.exportLeads | customgpt.api.reports.exportLeads | read | 导出会话中捕获的线索:邮箱、姓名、电话与自定义字段,支持分页与日期范围过滤。用于同步 CRM 或营销工具 |
schema/database.ts中的CustomGPTCustomerIntelligence类型揭示了getIntelligence返回的丰富字段:除user_intent、user_emotion、language外,还包含risk_fidelity、risk_jailbreak、risk_prompt_leakage、risk_profanity、accuracy等风险与准确性标注字段。
9. limits & user:配额与账户
| Operation | Operation ID | Risk | 说明 |
|---|---|---|---|
limits.getUsage | customgpt.api.limits.getUsage | read | 获取账户用量限额:已用/上限对比(项目数、存储额度即索引字符数、API 查询数)。用于监控配额消耗 |
user.getProfile | customgpt.api.user.getProfile | read | 获取当前用户资料,用于登录后展示或校验认证用户信息 |
user.updateProfile | customgpt.api.user.updateProfile | write | 更新当前用户资料(显示名、邮箱、头像 URL)。所有字段可选,只更新传入字段 |
user.searchTeamMembers | customgpt.api.user.searchTeamMembers | read | 按邮箱或用户 ID 搜索团队成员,用于分配权限或管理团队访问。需要 Owner 或 Admin 角色 |
风险分级与权限控制
README 为每个操作标注了三种风险级别,这在 Corsair 的权限体系中直接生效(见 docs/concepts/permissions.mdx):
| 风险级别 | 含义 | 示例操作 |
|---|---|---|
read | 只读,安全放行 | projects.list、reports.getAnalysis、limits.getUsage |
write | 会写入或修改数据 | projects.create、messages.verify、sources.add |
destructive | 不可逆的破坏性操作 | projects.delete、pages.delete、sources.delete、licenses.delete |
Corsair 的permissions.mode把每个风险级别映射到策略:readonly模式(allow / deny / deny)只放行读操作;cautious模式(allow / allow / require_approval)允许读写、破坏性操作需人工审批;standard模式(allow / require_approval / deny)连写操作也要审批。对 Agent 工作负载,cautious是常用默认。还可以用overrides对单个端点收紧或放宽:
customgpt({ permissions: { mode: 'cautious', overrides: { 'projects.delete': 'deny', // 收紧:禁止删除 Agent 'pages.delete': 'require_approval', // 收紧:删文档需人工审批 }, }, });overrides的键是插件端点树的点号路径,路径写错会在编译期报错——projects.delete、pages.delete、sources.delete、licenses.delete这些键正是来自 packages/customgpt/index.ts 中customGPTEndpointsNested的实际嵌套结构。
底层实现:REST 客户端、错误处理与本地缓存
请求管线与统一错误类型
所有端点共用makeCustomGPTRequest(packages/customgpt/client.ts):
- base URL 固定为 CustomGPT 官方 REST API,路径前缀
/api/v1已折叠进常量,各端点模块只传裸资源路径(如projects/1/pages); - 认证采用 HTTP Bearer Token,即账户的 API Key;
- 数组查询参数序列化为重复键(
filters=queries&filters=conversations),与官方 OpenAPI 文档中style: form, explode: true的声明一致; - multipart 端点故意不设置 Content-Type,让 fetch 依据 FormData 实例自动生成 boundary;
- 任何失败的调用都会包装成
CustomGPTAPIError,并携带上游 HTTPstatus、statusText、body与retryAfter,供错误处理器决策,无需重新解析错误字符串。
错误处理与重试策略
插件的默认错误处理器(packages/customgpt/error-handlers.ts)覆盖了完整的失败分类:
| 错误类别 | 匹配依据 | 重试策略 |
|---|---|---|
RATE_LIMIT_ERROR | HTTP 429 或消息含 rate limit / too many requests 等 | 最多 3 次,指数退避 + 抖动,尊重Retry-After |
AUTH_ERROR | HTTP 401 或消息含 unauthorized / token 等 | 0 次重试 |
PERMISSION_ERROR | HTTP 403 或消息含 permission / forbidden | 0 次重试 |
NOT_FOUND_ERROR | HTTP 404 或消息含 not found | 0 次重试 |
BAD_REQUEST_ERROR | HTTP 400 或消息含 invalid | 0 次重试 |
SERVER_ERROR | HTTP 5xx 或消息含 server error | 最多 2 次,指数退避 |
DEFAULT | 兜底 | 0 次重试 |
所有重试策略都从CustomGPTAPIError携带的结构化字段判断,而不是依赖字符串匹配。你也可以在构造插件时通过errorHandlers选项覆盖个别类别(源码中会用你的实现替换对应类别,DEFAULT兜底则保持二选一)。
本地实体缓存
插件通过 zod schema 定义了一套持久化实体(packages/customgpt/schema/index.ts):
export const CustomGPTSchema = { version: '1.0.0', entities: { projects: CustomGPTProject, pages: CustomGPTPage, sources: CustomGPTSource, conversations: CustomGPTConversation, messages: CustomGPTMessage, licenses: CustomGPTLicense, leads: CustomGPTLead, }, };每次 API 调用成功后,返回数据会被镜像写入对应实体表(ctx.db.<entity>.upsertByEntityId),并附带syncedAt时间戳。缓存写入是尽力而为的——存储失败只会打印告警,绝不会让一次成功的 API 调用失败(见 endpoints/shared.ts 的cacheEntity)。所有 schema 都用.loose()声明,上游新增字段会被原样保留而不是被丢弃,同时所有非标识字段均为可选,以适应官方规范"未标注任何响应属性为必填"的情况。数据建模与 CustomGPT 官方术语一致:API 称 Agent 为"项目"(project)、文档为"页面"(page),实体命名跟随 API 而非 UI。
测试验证:40 个操作的全部请求映射
插件附带完整的 Jest 测试(packages/customgpt/api.test.ts),测试名即"CustomGPT Endpoint Handlers — All 40 Operations Request Mapping"。测试用 spy 拦截corsair/http的request函数,逐一对 40 个操作断言三件事:
- URL 与方法:例如
projects.list应发出GET /projects,查询参数原样透传({ page: 2, order: 'asc' }); - 缓存写入:响应中的实体应按正确主键写入 mock 数据库(如项目按
String(id)upsert); - 事件记录:每个操作成功后都会通过
logEventFromContext记录形如customgpt.projects.list的完成事件。
该测试同时印证了认证注入:请求配置中的BASE指向 CustomGPT API 根地址,TOKEN为传入的 API Key。
关于 Webhooks 与许可证
README 明确说明本插件无 Webhooks(No webhooks)。源码也验证了这一点:customGPTWebhooksNested = {} as const,插件对象中webhooks与pluginWebhookMatcher均为空/未定义。因此,需要实时接收 CustomGPT 事件的应用无法依赖本插件内置 webhook,应通过主动轮询(如projects.stats、reports.*、pages.list)来获取状态变化。
插件以Apache-2.0协议开源(见 package.json 的license字段)。完整的包说明、端点参考与类型导出以 packages/customgpt/README.md 和 packages/customgpt/index.ts 的导出声明(含全部CustomGPTEndpointInputs/Outputs与各响应类型)为准。
【免费下载链接】corsairConnect your users to their apps项目地址: https://gitcode.com/GitHub_Trending/corsa/corsair
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考