模型接口返回了 HTTP 200,后面的程序却没法继续:JSON 少了字段,修改计划指向项目里不存在的文件,或者答案在输出上限处被截断。
如果应用只检查请求是否成功,这些结果就可能进入后续流程。把请求重试一次,也没有回答一个更关键的问题:什么样的结果才可以被接受?
10 月 28 日,GitHub 正式推出 Copilot Fusion。它会在运行时选择模型和执行方式,其中 Cascade 的思路是先让一个模型给出草稿,再判断是否需要升级。这个发布值得开发者研究的地方,是把模型选择与结果验收连接起来。GitHub 官方发布
本文把其中的级联思路拆成一个能本地运行的 Python 示例:先尝试第一种模型,按明确规则验收,失败后再调用第二种。先把控制流程验证清楚,再接真实接口。
验证范围:2026 年 10 月 29 日,在 Python 3.14.3 环境运行了 6 种离线构造场景,并通过 10 项自动检查。离线响应由代码预设,不是两款模型的实测输出。本文没有测试 Copilot 产品本身,也没有得出节省费用或提升模型准确率的结论。
一、先分清三个容易混在一起的机制
|
机制
|
判断依据
|
解决的问题
|
| --- | --- | --- |
|
接口故障重试或渠道切换
|
连接失败、超时、错误码等
|
请求能否完成
|
|
按任务选择模型
|
任务类型、复杂度、可用模型等
|
先交给谁处理
|
|
结果验收后的模型级联
|
第一轮输出是否满足验收条件
|
已经返回的答案是否需要升级处理
|
这里讨论第三行。即使 API 已返回有效响应,应用仍可能拒绝其中的内容。反过来,鉴权失败也不能直接解释为“第一种模型能力不足”,再盲目花钱调用第二种。
GitHub 文档列出了 Single、Cascade 和 Critique 三种执行方式。实际的 Copilot Fusion 还会考虑模型能力、可用性和上下文缓存等因素。下文只实现一个固定两阶段的应用侧级联流程,使用程序规则验收,不包含它的模型评审、动态编排或运行时选型能力。Copilot Fusion 官方文档
二、示例:代码修改计划进入后续流程前,先检查什么
假设一个开发工作流让模型生成修改计划,再交给工程师查看。为了让示例边界清楚,我们构造一个只包含两个文件的项目清单:
任务是为“流式请求中断后的错误提示”给出修改建议。模型需要返回修改项、验证方法和撤回方案。
这个阶段不执行修改,也不执行模型生成的命令。
程序只检查的确定性条件
JSON 能否解析,且不存在重复字段。
必要字段、列表和字符串是否符合约定。
修改目标是否在已知文件清单中,动作是否为允许的
modify。是否给出非空的验证方法和撤回方案。
响应是否正常结束,而不是触及输出上限后被截断。
例如,下面的 JSON 在语法上成立,但文件路径不存在,应当被拒绝:
这就是把业务约束放在 JSON 解析之后的意义。格式正确和符合当前项目约束,是两道不同的检查。
三、完整示例:最多尝试两次,每次都经过同一套验收
把以下代码保存为 cascade_demo.py。代码只使用 Python 标准库,要求 Python 3.10 或以上;默认运行离线场景,不需要 API Key。
代码中的 economy、strong 只是离线角色名,不对应真实模型,也不表示已经测量过价格或能力。文件清单同样属于演示场景,接到真实项目时应由应用提供。
示例源码
运行离线示例
先执行离线示例:
每行输出一条 JSON 记录,包含最终状态、计划和各阶段的验收理由。usage 在离线模式下为空,不会伪造 token 用量。
四、这次运行得到了什么
本地运行得到以下结果。表中的“尝试次数”是离线回调次数,并非真实模型请求次数。
|
构造场景
|
验收记录
|
尝试次数
|
最终状态
|
| --- | --- | --- | --- |
|
valid_first
|
passed
|
1
|
accepted
|
|
broken_json
|
invalid_json → passed
|
2
|
accepted
|
|
missing_rollback
|
invalid_fields → passed
|
2
|
accepted
|
|
unknown_path
|
unknown_path → passed
|
2
|
accepted
|
|
truncated_response
|
incomplete_response → passed
|
2
|
accepted
|
|
both_rejected
|
invalid_json → invalid_json
|
2
|
manual_review
|
第一条记录只尝试了一次,说明通过验收后没有继续调用备用阶段。中间四条在首轮失败后升级一次,第二轮通过才返回计划。最后一条在两轮均失败后返回 manual_review,并将 plan 置空。
这里的 manual_review 只是返回状态,尚未接入工单队列或人工审核系统。它至少使调用方能区分“通过当前规则的草稿”和“本轮未得到可接受草稿”,避免把最后一次失败内容当作兜底答案。
其中一个容易遗漏的场景是 truncated_response:即使内容恰好能解析为 JSON,只要响应标记为 length,本示例仍不接受。格式碰巧完整,不代表模型已经完成任务。
配套检查还覆盖了首轮通过不调用备用阶段、第二轮仍需验收、两轮失败停止、鉴权类异常不触发内容升级,以及重复 JSON 字段等边界;HTTP 适配部分使用模拟响应验证,没有发出真实请求。全部 10 项检查通过,验证记录随示例保存。
这些结果证明的是这段程序在所列场景中的控制行为。它们不能证明第一种模型适合哪些任务,也不能证明第二种模型更强。
五、接到真实 API 时,保留哪些边界
示例的 call_api() 已提供非流式 Chat Completions 请求方式,默认使用 Genvis 作为统一 API 入口示例。实际调用前,应从自己的账号中确认两种模型的准确 ID、访问权限和接口兼容性;代码没有预填未经核验的型号。
开启真实调用
在终端设置自己的测试 Key,再显式开启真实调用:
真实模式下,本程序最多发出两次模型 HTTP 请求;每次请求设置 30 秒超时,没有额外的应用侧重试。网关内部是否重试、最终如何计量,应以实际调用记录为准。
第二阶段继续使用原始任务重新生成计划,不把失败草稿直接当作事实。两阶段使用相同验收规则;即使换成能力更强的模型,也不能绕过文件范围和字段检查。
还有一个边界需要说清:accepted 仅表示通过了本文列出的规则。一个计划可能路径合法、字段完整,却仍然无法修复流式断连;撤回方案写得不空,也不代表撤回操作确实可用。这些问题还需要代码审查和真实回归测试。
真实工程任务应当把“计划可交给人查看”“代码通过测试”“可以发布”作为不同阶段。本文停留在第一个阶段。
六、多一次调用是否划算,应该怎样记账
级联会增加首轮调用,以及升级任务的第二次调用。是否节省费用,取决于实际通过比例、两种模型的用量、重试和缓存行为,不能只比较价格表上的输入单价。
两种记账口径
最直接的统计方式是:
第二个指标要把失败任务已经消耗的费用也计入。否则,一个流程即便大量失败,也可能因为只统计成功请求而显得很便宜。若样本没有任何任务通过,第二个指标不可计算。
记录时至少保留任务 ID、模型 ID、验收理由、响应结束原因、用量、实际费用与完整耗时。若要比较“全部使用高能力模型”和“级联”,两种路径必须处理同一批任务,使用一致的最终验收标准,并将人工检查发现的误放行单独记录。
官方发布页给出的效果属于 GitHub 自己报告的评测条件,不能直接搬成自建级联程序的效果。本文的离线记录也没有真实费用数据。
Copilot Fusion 提供了一个值得借鉴的思路:模型选择可以发生在工作流中,结果验收也可以成为升级依据。对于自己的 API 应用,可以先用本文示例跑通拒绝、升级和停止,再用真实任务验证验收规则是否有效。通过 Genvis 复现时,先选两个账号已支持的模型完成一条任务,并查看两阶段的调用记录,比一开始就批量切换生产任务更容易定位问题。