提供方与模型
bingo 自带的提供方、凭据如何进来、为额外端点准备的具名实例,以及模型是怎么选出来的。
自带什么
三个提供方插件被编译了进来。
| 插件 | 提供方 id | 凭据 |
|---|---|---|
bingo-provider-anthropic | anthropic | 一个 API key |
bingo-provider-openai | openai、codex | 一个 API key;codex 通过 OAuth 使用 ChatGPT 订阅 |
bingo-provider-fake | fake | 不需要——给测试用的脚本化装置 |
fake 提供方只在 BINGO_FAKE_SCRIPT 指明了一个脚本时才注册,所以打包好的二进制既不会
列出它,也绝不会退回到它。
--provider <id> 为一次运行挑一个;不给的话,bingo 取设置里的 provider,再不行就
取第一个注册的。--model <id> 挑模型;不给的话取设置里的 model,再不行就取该提供方
的默认值。
登录
bingo login codex # opens a browser
bingo login codex --device
bingo login anthropic # paste a key
bingo logout codex
三种流程,而一个提供方只提供它能履行的那些(ADR-0012、ADR-0017):
- 浏览器 —— 走 loopback 回调的 PKCE。bingo 绑定
127.0.0.1:1455,遇到冲突时最多 往上爬二十个端口,打开你的浏览器,校验state并交换 code。BINGO_NO_BROWSER阻止它打开浏览器,这样你可以把 url 贴到别处去。 - 设备(
--device)—— 一个码,拿到另一台机器的浏览器里输入。bingo 为它轮询, 最多十五分钟。 - 粘贴(
--paste)—— 一份在别处签发的凭据,从 stdin 读入。这是每个基于 key 的 提供方所用的流程;浏览器和设备流程对它们一律拒绝,因为根本没有签发方可谈。
不管哪种流程,凭据都落在 ~/.bingo/data/auth.json,权限位 0600,一个提供方 id 一条。
设置文件里绝不放秘密:项目那一层是要提交的,而提交上去的 key 就是泄露了的 key。
同样这些命令在会话内是 /login <provider> [browser|device|paste] 和
/logout <provider>。
key 到哪里去找
对于内置的 openai 和 anthropic 提供方,按这个顺序:
- 粘贴登录写在该提供方 id 下的那条
auth.json记录; OPENAI_API_KEY/ANTHROPIC_API_KEY;- 该提供方自己的
apiKey设置。
auth.json 排在最前,是为了让 /login 和 /logout 在一个已经导出了 key 的 shell
里仍然有意义。OPENAI_BASE_URL 和 ANTHROPIC_BASE_URL 挪动端点的方式和 baseUrl
设置一样。
令牌自己刷新:订阅的 access token 会在过期前 300 秒续期,或者在收到 401 时续一次, 且在同一把锁下——所以同时跑的两个回合只会刷新一次。签发方说 refresh token 已经没了 时,那条记录会被移除而不是重试,此后该提供方一直读作已过期,直到你重新登录。
具名实例
一个 wire 形状对应的一个设置键只装得下一个端点,这对有两个代理或两份订阅的人是不够
的。instances 可以加更多,每个都以自己的名字注册(ADR-0017):
{
"openai": {
"instances": {
"work": { "baseUrl": "https://proxy.internal/v1" }
}
},
"codex": {
"instances": {
"personal": {}
}
}
}
一个名字就是一个身份:--provider work、/model work/gpt-5.4 和 bingo login work
指的都是那个实例,而它的凭据在 auth.json 里也以那个名字为键——所以两份 ChatGPT
订阅可以并排放着。一个与内置 id 冲突、或与另一个实例冲突的名字,会在启动时被拒绝,
而不是注册到一半。
环境变量只喂默认实例。OPENAI_API_KEY 属于 openai,绝不属于 work:一把随手
放着的 key 不该悄悄喂饱每一个代理。
bingo provider add 会替人写下那条本来要手动编辑的记录。它会问名字、wire 形状
(openai 或 anthropic)、base url,以及一把 key——输入时隐藏,且可以不填;实例进
你的用户设置层,key 进 auth.json,最后它会告诉你现在可用的 bingo --provider <name>。
注册发生在启动时,所以这个实例下一次运行就生效。
模型目录
bingo 带着一份 models.dev 的快照,裁剪到它真正会读的那些事实:上下文窗口、最大输出、 这个模型会不会推理,以及它收不收图像(ADR-0004)。这些事实每个会话解析一次——先是 声明的设置,然后是从一次溢出中学到的窗口,然后是目录,最后是一个默认值,它在猜错会 被拒绝的那一侧保守取值。
/model 不用发网络请求就能从那份目录里补全,而 /model anthropic/claude-x 在一个
字符串里同时给出提供方和模型。这里没有 /provider:登录指明提供方,/model 指明
模型。
模型自己也能读这份目录。ListModels 工具会把每个已注册的提供方连同它的认证状态、
以及每个提供方的模型连同它们的事实都渲染出来,于是编排者可以有意识地挑一个能看图或
长上下文的模型,而不是猜一个 id(ADR-0026)。
声明目录搞错了什么
内核的 models 设置键按名字覆盖一个模型的事实:
{
"models": {
"openai/gpt-5.4": { "contextWindow": 400000, "maxOutput": 64000 }
}
}
每个字段都是可选的。bingo 从某个提供方自己的溢出消息里学到的窗口,会被记在
~/.bingo/data/learned-windows.json,并在下一次针对该模型打开会话时钳住目录里的值。