文章摘要
七月末某代码大模型推出正式版 API 服务。作者利用其完成两个开源项目任务,花费 0.31 元。一是修复 mypy 冗余类型转换告警问题,模型先调整出错,后精准一行代码解决;二是为 mypy 新增 JUnit 报告拆分功能,4 分 51 秒完成从设计到测试全流程。测试体现模型能力,成本低、缓存效率高。

七月末,一款代码大模型推出了正式版API服务,同期同行也调整了模型服务的定价策略。用户只需修改模型名称即可调用该服务,新版本原生支持Responses API,还提供了详细的开发工具链接入文档。作者此前预留了账户余额,借助这份文档将模型接入开发工具,完成了两个真实的开源项目任务,全程花费不足四毛钱。

接入该模型的配置流程并不复杂,只需在开发工具中添加对应的服务提供商配置,核心参数包括模型名称、接口地址、认证方式等。作者使用的配置代码示例如下:

model = "deepseek-v4-flash"
model_provider = "deepseek"
[model_providers.deepseek]
name = "deepseek"
base_url = "https://api.deepseek.com/"
wire_api = "responses"
env_key = "DEEPSEEK_API_KEY"

API密钥建议存放在环境变量中,避免直接写入配置文件带来的安全风险。作者为了不影响日常的开发工作,单独创建了临时运行环境,关闭了联网搜索、多智能体等额外功能,仅保留代码读取、命令执行和测试日志查看的基础能力。

成本与任务概况

第一个任务完成后,后台显示累计84次请求,超过303万Token,扣费0.21元。为了进一步测试模型的能力,作者又选择了一个无评论、无关联合并请求的功能需求,两个任务全部完成后,总请求次数达到125次,累计Token数超过435万,总账单金额为0.31元。

修复冗余类型转换告警问题

第一个任务来自开源静态类型检查工具mypy的Issue #21796,该工具是Python生态中最常用的类型检查工具之一,可以在代码运行前根据类型标注排查错误。该Issue在发布当天无人评论,也没有关联的合并请求,问题在于当开启`--warn-redundant-casts`参数时,明明完全多余的类型转换没有触发告警。

一个典型的复现代码如下:

T = TypeVar("T")
def identity(xs: list[T]) -> list[T]:
    return xs
def f(xs: list[int]) -> list[int]:
    reveal_type(identity(xs))
    return cast(list[int], identity(xs))

在这个示例中,`cast()`函数本应向类型检查器说明返回值的类型,但上一行已经通过泛型函数推断出了正确的类型,这次转换完全多余,理应触发告警。作者仅向模型提供了Issue描述、现有代码和验收要求,没有给出源码位置或现成的补丁。

模型顺着调用链定位到了`mypy/checkexpr.py`文件中的`visit_cast_expr()`函数,发现问题出在Any类型上下文的处理上:当检查cast内部的表达式时,模型原本意图不限制类型,但遇到泛型函数时,Any类型提前参与了推断,将泛型参数T替换为Any,导致原本的`list[int]`被转换为`list[Any]`,类型检查器因此无法识别出这次转换是冗余的。

模型最初的修改方案调整了公共泛型推断入口,在遇到Any类型上下文时跳过处理,虽然通过了原始的测试用例,也没有出现误报,但在运行更大规模的`testcheck`测试集时,破坏了另一个依赖Any上下文的正常场景,导致第2208个测试用例失败。

发现回归问题后,模型没有选择修改旧的测试用例,而是重新评估了修改范围,撤销了最初的公共修改,仅在`cast()`函数的入口处做了一行简单的调整:

- type_context=AnyType(TypeOfAny.special_form)
+ type_context=None

这次调整既解决了原始的冗余类型转换告警问题,又没有影响其他正常的类型检查逻辑。最终所有测试用例全部通过,包括8195个通过、33个跳过、7个预期失败的主测试集,以及作者额外准备的6个隐藏测试用例,其中3个需要告警的场景全部触发,另外3个场景没有出现误报,`git diff --check`也顺利通过。

新增JUnit报告拆分功能

第二个任务同样针对mypy,这次是新增一个JUnit报告格式。目前mypy生成的JUnit报告会将一个文件中的所有错误合并为一个失败项,当一个文件中存在多个错误时,开发者很难快速定位到具体的错误位置。新的需求希望将每条错误和提示拆分为独立的测试项,实现从“3条诊断→1个失败项”到“3条诊断→3个失败项”的转变。

作者仅向模型提供了Issue的两段描述,没有给出接口设计或代码位置,要求模型兼容旧格式、补齐测试和用户文档,同时不允许联网搜索。模型首先确认了旧版报告的输出格式,随后顺着调用链完成了7个文件的修改:

  • 为命令行参数添加`per_diagnostic`选项
  • 统一INI和TOML配置的校验逻辑
  • 修改XML生成器,将每条错误和提示拆分为独立的测试项
  • 更新两处文档,补充新的格式说明
  • 编写测试用例,覆盖多文件、引号、尖括号、`&`和严重错误等场景

模型没有使用简单的编号作为测试项名称,而是将完整的诊断信息作为测试项名称,这样在CI界面中可以直接查看文件、行号和错误内容。当诊断信息中包含双引号时,模型也按照XML属性规则进行了正确的转义。

从接收到需求到完成开发,整个过程只用了4分51秒。相关的单元测试全部通过,真实的命令行和配置文件入口都能生成可解析的XML格式报告,作者额外准备的3组隐藏验收用例也全部通过。更大规模的命令行测试套件中,119个用例通过、22个跳过,仅有4个与本地构建服务相关的用例未通过,与本次修改无关。

成本与缓存效率

第二个任务的输入Token超过129万,其中126万命中缓存,输出Token约2.4万,这一轮花费约1毛钱。将两个任务和初始的接入测试汇总后,总输入Token约428万,缓存命中超过419万,输出Token约7.6万,总Token数435万,总花费0.31元,缓存命中率达到了98.1%。由于智能体需要反复读取同一批源码、对话和日志,长任务中的大部分输入都复用了缓存,最终四百多万Token的总花费仅三毛多。

测试总结

本次测试仅通过两个任务,不足以全面评估模型的整体性能,且本次测试的结果是模型结合开发工具链的整体表现,其中工具链负责上下文管理、工具调用和测试执行,不能完全将成果归功于底层模型。

第一个任务展示了模型读取旧代码、定位问题并调整修改范围的能力:模型最初的修改方案虽然解决了原始问题,但引入了回归问题,随后能够自主撤销过宽的修改,最终找到精准的解决方案,仅用一行代码就完成了修复。

第二个任务则展示了模型根据简短需求完成完整功能开发的能力:仅根据两段文字的需求描述,模型就能完成从接口设计、代码实现到文档和测试的全流程开发,并且主动优化了测试项的命名方式,没有停留在“代码能跑”的基础层面。

最终的成本和缓存效率也体现了该模型的性价比优势,四百多万Token的总花费仅三毛多,且缓存命中率极高。本次测试的两个改动并未提交到mypy开源项目,仅作为模型能力的验证。关于这款模型的实际性价比,欢迎有相关测试经验的用户在评论区分享交流。

以上内容不代表本平台立场,仅供读者参考