项目密钥
项目密钥放的是云端运行要用、而 review.yaml 里绝不能写的值,比如 Agent 的模型密钥、测试账号的令牌、镜像仓库的登录凭证。本页说明要加哪些、怎么保护、最后到了哪里。按 OpenAI 接口写的 Agent 也可以不给密钥(见 Agent 的模型)。不是秘密的值,比如仓库自带测试后端的测试账号,可以写进 review.yaml(见密钥还是 runner_env)。
项目密钥用于连 GitHub 仓库和自带镜像的项目。本地测试机从它自己的机器上读值,网页直连的对话 AI 的密钥保存在它自己的连接上。
加一个密钥
- 打开项目的目标,在仓库那一行点「密钥」(或者打开这种接法的向导)。
- 在向导的「密钥」一节,填名称(比如
OPENAI_API_KEY)和值。 - 点「加上」。
列表里显示每个密钥的名称、「末四位」和「更新时间」。要换值,用同一个名称再加一次。要删掉,点它旁边的垃圾桶。只有在浏览器里登录的人能加、删密钥;CLI 令牌和助手不能。
要加哪些
运行要读的每个变量都加一个密钥;不是秘密、review.yaml 已经在 runner_env 里给了值的除外(见密钥还是 runner_env)。不用自己对照下表:沙盒项目的「密钥」一节会列出平台从 review.yaml 和确认过的测试里找到的名字、每个由谁给、还缺哪个。
| 谁要用 | 名字写在哪里 |
|---|---|
| 你们的 Agent(模型密钥、接口设置) | review.yaml 的 agent.env_passthrough。没有 OPENAI_API_KEY 时由平台模型应答(见 Agent 的模型) |
| 你们的数据服务 | backend.state.reader.base_url_env |
| 重置或读取用的 SQLite 数据库 | backend.reset 或 backend.state.reader 的 url_env |
| 测试用户的令牌 | 每个测试给它的用户写的 env:NAME |
| 需要某个值的安装命令(比如私有包仓库) | environment.setup 读的那些 |
| 平台不提供的评审模型 | 见评审模型的密钥 |
attach.base_url_env 不用加密钥:测试机每次执行都把它设成工具代理。
密钥还是 runner_env
运行要读的变量不一定都是秘密。不是秘密的,可以写进 review.yaml 的 runner_env(测试机变量),跟着仓库走,不用在平台上加。
| 放在哪里 | 什么时候 | 例子 |
|---|---|---|
| 项目密钥 | 这个值能打开东西:模型密钥、接口令牌、数据库密码、共享测试系统上的账号 | OPENAI_API_KEY、PAYMENTS_API_KEY |
review.yaml 的 runner_env | 这个值不是秘密:仓库自己起的服务的地址、仓库自带测试后端的测试账号 | EXPENSE_STATE_BASE: http://127.0.0.1:47591、EXPENSE_TOKEN_ALICE: tok-e_alice |
- 同名的项目密钥优先:不改仓库也能换掉仓库里的值。
runner_env里的值,能看仓库的人都看得到,日志和报告里也不打码。runner_env里的值看起来像真的凭证(sk-…、ghp_…这类密钥格式,JWT,私钥,或一长串随机字符)时,review.yaml读不进来,报错里会写明是哪个变量。这样的值要加成项目密钥。
命名规则
- 只用大写字母、数字和下划线,以字母开头,最长 64 个字符。
review.yaml只能引用这样写的变量名。 - 值是 1 到 4,000 个字符。
- 值至少 8 个字符:更短的在日志里不会被遮住(见下)。
密钥怎么密封、怎么送达
- 值经 TLS 传到平台,一到就密封:用一把新生成的密钥做 AES-256-GCM 加密,这把密钥再用平台的公钥以 RSA-OAEP(SHA-256)包起来。
- API 只存密封后的值和末四位。它手里没有私钥,所以谁都没法通过它把值读回来,你们自己也不行。
- 运行开始时,沙盒用一次性的引导令牌换一个只对这个任务有效的会话令牌,把它出示给平台执行器。平台执行器是唯一持有私钥的组件,它打开这个项目的密钥,交给这台沙盒。
- 在沙盒里,这些值是测试机的环境变量。Agent 本身只拿到
agent.env_passthrough里的那些;没有OPENAI_API_KEY时,还有平台模型的地址和占位密钥。安装命令、重置和评审模型也能看到其余的。会话令牌只留在测试机里,Agent 拿不到。 - 运行结束,虚拟机删除,值也随之消失。
见安全说明里的加密。
日志和报告里的脱敏
- 沙盒传回的每一行日志,不管来自测试机、你们的 services 还是 Agent,离开虚拟机之前都会把每个密钥的值(8 个字符以上)换成占位符。
- 运行包的过程记录和报告里,测试用户的令牌,以及
env_passthrough里名字含KEY、TOKEN、SECRET、PASSWORD、PASSWD、CREDENTIAL或AUTH的变量的值(8 个字符以上),都换成[REDACTED:名称]。看起来像密钥的字符串(Bearer …、sk-…、ghp_…、Slack 令牌、JWT)也一样。给密钥变量起能看出用途的名字,比如PAYMENTS_API_KEY。 - 运行包上传前,平台还会再扫描一遍。哪个文件里还有这些值或像密钥的字符串,就停止上传,不会把它传上去。
运行包只记环境变量的名字,从不记密钥的值。runner_env 里写的值不是密钥:在运行日志和运行包里那份 review.yaml 里照原样保留。
镜像仓库的拉取凭证
私有镜像要一个镜像仓库的登录凭证。在自带镜像的项目里,填「拉取凭证」(镜像仓库、用户名和只读令牌),点「保存凭证」。它保存为一个 registry 类的项目密钥,按镜像仓库命名(比如 REGISTRY_GHCR_IO),和其他密钥一样密封。它的值是 JSON:
{ "server": "ghcr.io", "username": "acme-bot", "password": "ghp_…" }server 只写主机名和端口,不带 https:// 和路径。页面上显示镜像仓库、用户名和令牌的末四位。平台执行器用它读镜像的清单,沙盒拉取前用它登录,结束时退出登录。公开镜像不用填。
克隆 GitHub 仓库不用加密钥:每台沙盒都会拿到一个一小时有效、只覆盖你们所选仓库的 GitHub 安装令牌。
Agent 的模型
连仓库或自带镜像的项目可以不给模型密钥。项目密钥里没有 OPENAI_API_KEY 时,Agent 的模型调用由平台应答,按用量计费:
- 沙盒给 Agent 两个变量:
OPENAI_BASE_URL,指向沙盒本机上的一个地址;OPENAI_API_KEY,值是platform-model,一个什么也打不开的占位值。不管agent.env_passthrough里写了什么,都会给。 - 读这两个变量的 Agent(OpenAI 的各个 SDK 都读)不用改:chat completions 和 Responses API 都行,流式和非流式都行,带工具调用也行。
- 测试机把每次调用转给平台,带上这次运行自己的会话令牌,Agent 看不到它。平台用自己的账号调用模型,平台的密钥不进虚拟机。
由哪个模型应答:
| Agent 要的模型 | 由谁应答 |
|---|---|
按名字要平台的模型之一:gemini-4-argon、gpt-6.1-sol、gemini-3.8-flash 或 gpt-6-luna | 就用它 |
| 其他模型 | 项目的模型,在项目页头选(见模型) |
换了模型时,运行日志会写明,报告的测试条件检查「Agent 有没有用模型做决定」也会记下由哪些模型应答。
GPT-6.1 Sol 和 GPT-6 Luna 不接受某些请求参数,平台会替 Agent 调整:
- 把
max_tokens改成max_completion_tokens发出。Agent 要的是别的模型时,给模型的思考多留出长度。 - 去掉不是 1 的
temperature和top_p,以及这两个模型不接受的其他采样参数。 stop由平台在回复上照样截断,按Observation:截断的 Agent 照它要的读到那里为止。
应答的不是 Agent 要的那个模型时,平台还会把换上的模型不收的参数改成它收的(2026 年 10 月 20 日起)。比如 openai-agents SDK 给 gpt-5.2 发推理强度 none,GPT-6.1 Sol 不收:
- 模型不收的推理强度(
reasoning.effort,chat completions 里是reasoning_effort)改成它收的、往高取最接近的那个:none改成minimal,minimal也不收时改成low。从不往低改。 - 模型根本不收的参数(比如
verbosity)去掉。只改这类参数,从不动消息、工具和回复格式。 - 模型不收什么,从它自己的报错里记下,之后不再发给它。运行日志里每种改动写一次,比如「平台换上的模型 gpt-6.1-sol 不收 Agent 请求里的 reasoning.effort=none:平台改成了 low(往高取最接近的,不降低)」。
- Agent 按名字要的就是这个模型时,请求原样发出:它不收的值是 Agent 自己的问题。
模型还是不收,或者回了限流、服务器错误时,这是平台的问题,不是你们 Agent 的:这次执行不会判成 Agent 的结果,平台自动重跑一次,不收费(见平台自动重跑)。限流时模型给的 retry-after 会转给 Agent,它的 SDK 照模型要的时间等。
Responses API(/v1/responses,openai-agents SDK 默认用它)每个模型都能用。Gemini 3.8 Flash 自己没有 Responses API,项目的模型是它时,平台用 Gemini 的 chat completions 应答这类调用,请求和回复两头都由平台转换,流式和非流式都行:
instructions、文字和图片输入、函数工具和它的调用与结果、tool_choice、parallel_tool_calls、结构化输出(text.format)、max_output_tokens、temperature、top_p,和 GPT 模型上一样能用。previous_response_id在它指的那次回复之后 6 小时内能用,期间平台重启过就不行了。store: false的回复不留。openai-agents SDK 本来就每次发整段对话。- Agent 带回来的 OpenAI 推理项会去掉:Gemini 自己思考。
- Agent 要的是别的模型时,低于
low的推理强度(none、minimal)按low发出,Gemini 不收的text.verbosity去掉。运行日志里会写明,和 GPT 模型一样。 - Gemini 的安全过滤拦下请求或回复时,这次回复以
incomplete结束,原因是content_filter,和 OpenAI 的内容过滤一样。 - 只有 OpenAI 的服务器才有的东西,会收到一个写明是哪一样的 HTTP 400 错误:托管工具(网页搜索、文件搜索、代码解释器、电脑操作、图片生成、远程 MCP)、按
file_id给的文件、存着的提示词模板、conversation和后台模式。
费用和上限:
- 按「平台模型(被测 AI)」的用量计费,价格见平台的模型。Agent 会用掉多少,运行前算不出来。
- 每次运行的费用上限约 $6.50。套餐的额度和余额、花费上限或先充值的余额剩下的更少时,按剩下的算。到了上限,Agent 之后的模型调用会收到 HTTP 402 错误,代码是
agent_model_budget_exhausted,这次运行在当时那次执行结束后停下,出部分报告。 - 只应答
POST /v1/chat/completions和POST /v1/responses。其他接口(比如 embeddings)回 404,要用这些接口的 Agent 得用自己的密钥。 - 由 GPT 模型应答时,用 Azure 默认的内容过滤器,被它拦下的回复会如实写明(见内容过滤)。
要用你们自己的密钥,把 OPENAI_API_KEY 加成项目密钥,并写进 agent.env_passthrough。这样费用由你们的模型提供方收,调用不经过平台。向导的「密钥」一节会写明这次运行用的是哪一种。用平台的模型时,这一节、「开始测试」前的检查和费用上限,都按上表写明由哪些模型应答,不会只写一个模型。用其他提供方(Anthropic、你们自己的 Azure 接口)的 Agent,照旧要那个提供方的密钥。
评审模型的密钥
评审模型为需要它的判断标准评审回复。要不要你们的密钥,看运行在哪里跑:
| 在哪里跑 | 评审模型 | 密钥 |
|---|---|---|
| 沙盒(连仓库或自带镜像) | judge.model 写的是平台提供的模型时,用项目的模型(见模型) | 不用。沙盒通过平台调用它,平台的密钥不进虚拟机。按评审模型用量计费。 |
| 沙盒(连仓库或自带镜像) | judge.model 里的其他模型 | 把提供方的变量加成项目密钥:OPENAI_API_KEY(openai:)、ANTHROPIC_API_KEY(anthropic:)、OPENAI_COMPAT_BASE_URL 和 OPENAI_COMPAT_API_KEY(openai-compatible:)、AZURE_AI_BASE_URL 和 AZURE_AI_API_KEY(azure:)。费用直接付给提供方。 |
| 本地测试机 | 这台机器有评审模型的密钥时,judge.model 里的任何模型;没有时,judge.model 写的是平台提供的模型,平台用项目的模型评审 | 有密钥时:同样的变量,设在测试机上,或者写在 review.yaml 旁边的 .env 里。没有时不用:测试机用自己的令牌经平台的评审代理调用,平台的密钥不离开平台,按评审模型用量计费。 |
| 网页直连对话 AI | 项目的模型 | 不用:平台的评审模型。 |
评审模型的密钥不会给 Agent:你们透传的 OPENAI_API_KEY 仍然是 Agent 自己的。
平台评审模型的花费
平台提供的评审模型每次运行有费用上限(见费用控制)。到了上限,剩下的不再评审。没评审的不算通过,结论也就不会是通过。
下一步
- review.yaml 参考:哪些字段写的是变量名。
- 沙盒与上限:沙盒还能访问什么。
- 安全说明:加密、隔离和保留期。