api2business · diff
git:20261003.98b281f to git:20261003.81286dd
2 added, 2 removed. Audit A to A.
---
name: api2business
description: >-
Api2Business 开发、配置、部署和运行维护技能。用户要求安装、部署、升级、验证、
排查 Api2Business,或操作账号、评分、上游、成本和经营核算时使用。
---
# Api2Business
- 本技能遵循 Skill(cli-spec)。
## 当前 Sub2API 架构
- 唯一 Sub2API 运行面是 NC01 的 `sub2api-nc01-native`。
- 唯一 Sub2API 业务数据库是 NC01 本地专用 PostgreSQL
`127.0.0.1:55432/sub2api`。
- `api.pikapython.com`、`api.hwpod.com` 和 `sub.api2business.com` 只是入口或代理,
不代表数据库 authority。
- 禁止将旧 PK01 或 `NC01-DOCKER` 的数据库地址写入配置、Secret、CLI 参数或示例。
## Api2Business L1 唯一运行面
- `https://api2business.hwpod.com` 是 Api2Business 唯一 L1 实例、唯一业务入口和唯一验收入口。
- CLI 的唯一 HTTP target 使用该公网地址;不得再配置或交付 `native-api`、`production`、`local` 等并列业务 target。
- 本机监听地址、Docker Compose/native profile 和 worker 内部回环地址只是唯一 L1 实例的实现细节,不构成第二个实例。
- `localhost`、`127.0.0.1` 和嵌入式 CLI 只能用于受控故障诊断或构建检查,不得用于业务结果、截图验收或邮件交付。
- L1 的 API、Web、worker、Temporal、数据库和账本必须由同一 owning 配置和同一公网入口关联;发现数据不一致时先修复入口映射,禁止创建并列实例。
## 工作区
- 新部署先克隆 `https://github.com/api2business/api2business.git`,再从克隆后的仓库加载本 skill。
- 从当前 Api2Business 仓库根目录执行命令。
- 使用 `config/api2business.yaml` 保存唯一 L1 的运行配置;该文件不得提交。
- 使用 `skills/api2business/scripts/api2business-cli.ts` 执行业务和生命周期操作。
## 从零部署(Bootstrap)
1. 准备 Git、Bun、PostgreSQL、Temporal 和可访问的 Sub2API 管理面。
2. 克隆仓库并进入工作区:
```bash
git clone https://github.com/api2business/api2business.git
cd api2business
```
3. 从克隆后的仓库加载 `skills/api2business/SKILL.md`,再读取
`docs/reference/deployment.md`;不得从其他仓库或运行容器复制部署逻辑。
4. 安装依赖并创建不提交的本机配置:
```bash
bun install --frozen-lockfile
cp config/api2business.example.yaml config/api2business.yaml
```
5. 在仓库外准备 Secret 和持久化状态目录:
- Secret 文件仅允许 owner 读取;
- 配置只保存 `sourceRef`、环境变量名或挂载路径;
- PostgreSQL 经营数据、账本、缓存和采样不得写入 Git 工作区。
6. 根据目标环境填写 `config/api2business.yaml`,再执行:
```bash
bun skills/api2business/scripts/api2business-cli.ts \
--config config/api2business.yaml \
config validate
bun run deploy:validate
bun skills/api2business/scripts/api2business-cli.ts \
--config config/api2business.yaml \
native start --component all
bun skills/api2business/scripts/api2business-cli.ts \
--config config/api2business.yaml \
native status --component all --json
```
7. 按“验收”章节完成检查:
- 检查登录、主要数据页和至少一个异步作业;
- 检查重启后的账本、缓存、采样和作业状态;
- 任一步失败时停止在首个断点,不跳过配置或 Secret 校验。
## 部署
- 先读取 `docs/reference/deployment.md`。
- 确认当前目录是已克隆的 Api2Business Git 工作区,不从运行容器或其他仓库拼装部署资产。
- 根据目标环境选择 Compose、Kubernetes、systemd、托管容器或其他部署方式。
- 不假定特定 CI/CD、代码托管、集群、主机名或网络入口。
- 发布前执行 `bun run deploy:validate`。
- 使用镜像摘要和配置摘要确认运行版本,禁止使用运行容器作为配置真相。
## Secret
- Secret 只保存在仓库外。
- 通过配置中的 `sourceRef`、环境变量、只读文件或外部 Secret 管理器注入。
- 只输出 presence、fingerprint 和有界摘要,不输出值。
## 生命周期
```bash
bun skills/api2business/scripts/api2business-cli.ts --config config/api2business.yaml native start --component all
bun skills/api2business/scripts/api2business-cli.ts --config config/api2business.yaml native status --component all
bun skills/api2business/scripts/api2business-cli.ts --config config/api2business.yaml native logs --component all --tail 100
bun skills/api2business/scripts/api2business-cli.ts --config config/api2business.yaml native stop --component all
```
- `native` 是唯一 L1 实例的生命周期入口,实际运行方式由配置选择;生命周期操作不得创建第二个业务实例。
- API 应快速返回作业 ID,长流程由 worker 执行。
- 数据库读取使用应用内排队读取通道,不从外部脚本直接连接业务数据库。
## 领域操作
- 账号导入、生命周期和空闲探活读取 `references/account-operations.md`。
- 账号导入可用历史参数名 `--rate-multiplier <正整数>` 调整负载因子;该参数在导入
payload 中必须写入 Sub2API 原生 `load_factor`,不得写入计费倍率
`rate_multiplier`。省略时读取 `operations.accountImportDefaults.rateMultiplier`,普通导入与
BugTeam 购买导入共用该字段。
- 普通 OpenAI OAuth 导入若未提供有效的 `credentials.model_mapping`,自动写入当前 OpenAI
模型白名单并排除 `gpt-5.6-luna`;已有显式映射保持不变。
- 已有 OpenAI OAuth 账号可用 `accounts models disable-luna --accounts <id-or-range,...>
--confirm --over-api` 通过 Sub2API runtime 批量写入不含 Luna 的模型白名单;命令先校验
全部目标均为 OpenAI OAuth,校验失败时不写入任何账号。
- 该默认限制只作用于普通 OAuth 导入;API-key、Grok OAuth 和
`cutoffTrigger=public-recovery` 的复活导入不套用该策略。
- OAuth 退役计划可用 `--plan-type` 限定账号类型:
- 默认 `--selection dead` 选择错误账号;`free`、`plus` 和 `team` 的限流账号也按死亡处理,`k12` 限流账号保留;
- 显式 `--selection all` 选择指定单一类型的全部当前账号,且只允许用于整池范围。
- 退役清理边界:
- 用户说“清理账号”或“退役账号”时,只允许处理 `platform=openai` 且 `type=oauth` 的账号。
- API-key 账号禁止进入退役结算、删除或清理流程,即使它们属于同一业务池。
- API-key 账号只能通过独立的上游管理流程处理,不得使用 OAuth 生命周期入口替代。
- 对缺少采购成本记录的整池账号,先用 `--scope pool --plan-type <type> --unit-cost-cny <CNY>`
显式声明本批结算单价;该模式只支持单一账号类型,并在计划与确认回读中固定成本。
- 退役删除按 `operations.accountLifecycle.deleteBatchSize` 分批调用原生批量接口;单批失败会跳过并继续,终态只以排队回读为准,失败且有剩余账号时复用原计划恢复。
- 上游、评分、优先级、定时稳定性观察和截图报错归因读取 `references/upstream-scheduling.md`。
- - API-key 切号模板由 owning YAML 的 `operations.upstreamManagement.templateFiles` 管理:
- `codex.yaml` 只给 OpenAI,`claude.yaml` 只给 Anthropic;Grok 不套模板。
+ - API-key 切号模板的唯一规则和平台边界见
+ [上游与调度](references/upstream-scheduling.md)。
- 多轮号池优化先读取该参考的“评分、容量与冷却联动评估”:
- 分开核对滚动分、固定时间段业务记录、账号容量和会话绑定;
- 模板及排序变更必须独立回读运行态,不以工作流成功代替业务恢复。
- 池级质量调查使用 `scores pool-quality --over-api`,该查询只读。
- 账号评分只有一条计算路径。
- `scores get` 只读取账号评分快照,不重新计算。
- `scores rank --calls <N> --over-api` 先按这 N 次刷新同一份快照,再读取刚写入的快照。
- 单账号质量评分将绑定该账号的专用探活样本纳入评分:
- 用户请求不足时,用探活补充可靠性、切号和延迟证据;
- 探活失败属于该账号的有效质量信号,不得笼统视为评分污染。
- 池级 `scores pool-quality` 仍排除内部 monitor 和 `api2business-probe-*` 探活:
- 池分只反映真实用户业务;
- 比较账号分与池分时必须同时报告样本范围。
- 优先级计划采用严格线性加权:可靠性、TTFT、证据、探索、余额加分,实际人民币成本扣分;不得使用置信度乘总分、池分与账号分相乘、动态质量反馈或新增硬门槛。
- `scores rank` 对 TTFT 样本不足的账号输出固定 `ttftPriorScore` 与 `latencyEvidence=prior`;`scores priority-plan` 单独输出 `evidenceScore`、成本锚点来源及线性分项。
- 切号质量同时输出原始、已恢复、未恢复和有效切号率;有效率按 `未恢复 + 0.25 × 已恢复` 计入账号评分。
- `scores pool-quality` 输出错误归因完整度;未归属错误只作为池级数据质量事实,不得扣入任一账号。
- 立即刷新池质量样本使用 `scores pool-quality-refresh --over-api`;命令立即返回 workflow ID。
随后用 `workflow status --id <workflow-id> --over-api` 回读,再查询 `scores pool-quality --over-api`。
- 充值候选使用 `upstreams recharge-candidates --over-api`。
- 欠费、低余额和查询超时的判定见 `references/upstream-scheduling.md`。
- 充值使用 `upstreams recharge --base-url <https-url> --recharge-cny <CNY> --confirm --over-api`;同一规范化 `base_url` 是共享钱包,只记账一次并统一恢复该站点全部 API-key 账号。
- 充值确认后 CLI 立即返回异步 workflow ID,并做一次非阻塞只读状态与账号快照核验;最终一致性使用 `upstreams recharge-status --id <workflow-id> --over-api`。
- 核验状态为 `pending`、`snapshot_mismatch` 或 `unavailable` 时,只表示作业未完成或读模型暂未追上,不代表充值失败;必须继续查询原 workflow。
- 充值请求超时重试时必须复用相同的 `--idempotency-key`,禁止生成新 key 重复提交同一笔充值。
- CLI 在提交传输异常时会回显本次幂等键和“结果未知”提示;只有复用该键重试,不能把传输异常当成未提交而生成新键。
- 精确错误链使用 `errors diagnose --request-id <request-id> --over-api`。
- 按模型定位使用 `errors diagnose --model <exact-model-id> --limit <N> --top <N> --over-api`。
- 单请求排障使用 `errors inspect --request-id <request-id> --over-api`。
- 切号是否命中、候选是否耗尽、正文是否缺失,只以 `references/upstream-scheduling.md` 为准。
- 切号模板的匹配、近义短语、热加载、分组口语、同步范围和新增上游收口,只以该参考为准。
- 新增上游省略 `--rate`;占位费率与最终费率回读也只以该参考为准。
- 已有上游改分组使用 `upstreams update --id <account-id> --groups <id,id,...> --confirm --over-api`。
- `--groups` 整表替换全部分组,并重写切号模板。
- 私有探活分组必须列入;隔离后的收回顺序只见 `references/upstream-scheduling.md`。
- 多个同钱包 API Key 只对实际充值动作记一笔充值;创建、模板和探活隔离作业按账号 ID 幂等回读。
- 收入、采购、充值、退款和毛利读取 `references/accounting.md`。
- 手工收入明细使用 `cash ledger --period YYYY-MM --over-api`,汇总使用 `profit daily`。
- BugTeam 客户 API 使用 `bugteam` CLI 命令组,配置中的 `bugTeam.customerToken`、`customerAccount`、`customerPassword` 只能引用仓库外 Secret:
- 只读:`bugteam login`、`balance`、`inventory --product <id> --quantity N`、`shelves --product <id>`、`pickup order-status --id <id>`、`recoveries list`。
- 实时成本:`bugteam cost-monitor get --over-api` 读取最新摘要,显式增加 `--include-records` 才展开 6 小时历史;`bugteam cost-monitor sample --over-api` 提交一次采样,并用返回的 workflow ID 查询原作业。
- 订单:`pickup order-create --product <id> --quantity N [--idempotency-key <key>]`;创建必须 `--confirm`,超时不得重复下单。
- 履约:`pickup download --id <id> --format sub2|cpa --output <path>`、`pickup push --id <id> --hub-id <id> --confirm`、`pickup take --id <id> --confirm`。
- 401 修复:`recoveries claim --id <id> --ticket-stdin --output <path> --confirm`,Ticket 从 stdin 读取,必须复用同一 `--idempotency-key` 进行重试。
- 余额兑换:`redeem --code-stdin --confirm`,CDK 不得出现在 argv、日志或输出中。
- 一键购买导入:先用 `bugteam purchase-import options --over-api` 回读默认值;
再用 `bugteam purchase-import create --quantity N --confirm --over-api` 提交,
并只用 `bugteam purchase-import status --id <job-id> --over-api` 跟踪原作业。
- 下载和领取只输出路径、字节数、SHA256 与版本摘要,绝不输出账号 JSON、Token 或 Ticket。
- 30d.team 公开兑换找回使用独立的 `bugteam public-recovery` 命令组,不读取或发送 BugTeam 客户 Token:
- 健康检查:`bugteam public-recovery health --base-url https://30d.team --card-code-stdin`。
- 401 找回:先不带 `--confirm` 查看计划,再追加 `--confirm` 和 `--mode 401` 执行;兑换码只能经 stdin 输入。
- 状态查询:`bugteam public-recovery status --base-url https://30d.team --card-code-stdin`,只输出脱敏状态,不输出下载 Token。
- 下载:`bugteam public-recovery download --base-url https://30d.team --card-code-stdin --output <path>`;先查询可下载任务,成功后原子写入并返回字节数与 SHA256,已存在目标文件会拒绝覆盖。
- `--base-url` 必须是无凭据、无路径、无查询和无片段的 HTTPS origin;该公开服务与 Api2Business 客户 API、Sub2API 本体均保持边界分离。
- 完整复活作业使用 `start --account-id <Sub2API账号ID> --confirm` 创建并冻结原 OpenAI OAuth 账号配置,不读取兑换码、不启动 worker;原账号不删除,新复活账号固定按 `¥0.01` 成本导入。
- 后续每次 `continue --id <job-id> --confirm` 只推进一个阶段;`health`、`reclaim`、`status` 和 `download` 阶段才追加 `--card-code-stdin`。
- 新副本继承冻结的优先级、并发、负载因子、计费倍率、分组、代理、过期暂停、状态和调度开关;`verify` 只核对新副本,任一字段不一致即失败。
- 已有下载文件需要补导入时使用 `import --account-id <原OAuth账号ID> --file <JSON> --plan-type <type> --confirm`;该入口保留原账号并创建独立复活副本。
- 作业 ID、阶段、错误和脱敏日志保存在 `.state/public-recovery/<job-id>.json`;使用 `status` 查看摘要,使用 `logs --id <job-id> --limit N` 查看最近日志。
- 作业失败后使用 `continue --id <job-id> --confirm` 从失败阶段继续,或使用 `retry --id <job-id> --stage <stage> --confirm` 单步重试;需要公开接口的阶段再次使用 `--card-code-stdin`,兑换码不落盘。
- 完整复活导入显式使用 `cutoffTrigger=public-recovery` 和独立重复导入语义,保留原 OAuth 账号并创建新的复活账号;不会触发 OpenAI OAuth 导入后的 API-key 上游切断。
- 错误聚合与诊断:
- `--group` 按错误记录的实际请求分组筛选;
- 默认排除内部 monitor 用户和 `api2business-probe-*` 探活流量;
- 返回 `groupFilterBasis=request-group` 与 `probeNoiseExcluded=true` 供调用方核对口径。
- 页面普通读取只返回已有缓存,刷新先写缓存再读回:
- 普通 GET 只读 `api2business_api_cache`,不重新计算;
- 显式刷新请求携带 `x-api2business-refresh: 1`,先重算并写入该缓存,再读出刚写入的响应;
- 排队 SQL 的普通读取只返回未过期缓存;
- 显式刷新或缓存不存在时先查询并写入读取缓存,再返回这份缓存;
- 不把查询结果直接返回给调用方;
- 读取不先返回旧缓存,再在后台刷新;
- 快照型 API 不叠加第二份通用 HTTP 响应缓存;
- 评分表账号余额读取 `usage-cache` 快照,按评分账号 ID 查询,不依赖上游列表 HTTP 缓存是否命中;
- API 与 Worker 按稳定快照键共享成功载荷;
- 快照成功后原子替换,失败保留上一份成功快照;
- 账号评分快照另由 worker 每 5 分钟刷新,进程重启后仍读取持久化快照。
- Sub2API 业务查询统一通过 Api2Business 排队 broker 读取 NC01 本地专用库;
CLI、Web、worker 和人工脚本不得直连旧 PK01 数据库。
- 账号级代理默认策略:OAuth 导入、Plus/Team 账号和 API-key 上游默认直连,不绑定
Sub2API Proxy;配置中的 `sourceProxyId: 0`、`proxyId: 0` 表示无代理。
- 只有用户显式选择并且 owning 配置允许时才启用账号级代理;这不影响 NC01 host-Docker
的出网代理配置。
- 账号导入成功后异步触发一次 OAuth 实时成本采样;该采样独立于导入作业,不延长导入终态,失败只作为采样作业失败记录。
- 账号导入成功后不再自动提交 API-key 切断作业;API-key 切断仅保留显式手动入口。
- 手动验证同一采样路径使用 `accounts oauth-runtime-sample --over-api`,返回独立 Temporal workflow ID。
- 上游智商评测:
- 提交:`upstreams benchmark --id <account-id> --model <model> --confirm --over-api`;
- 进度与日志:`upstreams benchmark-status --id <benchmark-run-id> --over-api`;
- 账号历史:`upstreams benchmark-history --id <account-id> --limit 20 --over-api`;
- 评测只复用持久化探活专用 API Key,不读取供应商原始 Key,也不轮换探活 Key。
- 评分与产出分母继续使用 `total_cost`。
- 额度监控的供应商实际支出按逐条销售倍率折回后乘实时有效倍率,唯一公式和缺失处理见
[额度监控](references/quota-monitoring.md)。
- 额度监控的状态、可用比例、钱包合并、刷新轮询和截图验收口径见 [额度监控](references/quota-monitoring.md),不得在页面或其他文档另建第二套口径。
## 验收
- 验证 `/health`、Web 登录、主要数据页和至少一个异步作业。
- 页面截图使用正式 CLI 取得临时 session,再交给受控 WebProbe:
```bash
bun skills/api2business/scripts/api2business-cli.ts \
--config config/api2business.yaml \
--over-api \
web screenshot \
--profile scores-layout
```
- CLI 通过 `/api/login` 获取 Cookie,并只在内存中传给 WebProbe;WebProbe 不填写登录表单,Cookie 不进入 argv、日志、报告或磁盘。
- 验证重启后账本、缓存、采样和作业状态仍可读取。
- 失败时按配置、Secret、网络、数据库、worker 和外部 API 的顺序定位首个断点。