Aider 实战:TaoToken 跑通 FastAPI 路由模块的类型标注补全
2026/9/18 11:53:25 网站建设 项目流程

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度

1. 为什么挑 FastAPI 的 routing.py 做类型标注补全

FastAPI 的fastapi/routing.py是个很适合拿来练 Aider 的文件。它体量大、泛型多、装饰器层层嵌套,APIRouterAPIRoute之间的类型关系绕来绕去,早期版本里不少函数签名只写了参数名没写注解,或者注解写了一半。这种文件让 Aider 去补类型标注,比让它从零写一个新模块更能看出模型在真实仓库里的表现:它得先读懂上下文,再决定每个参数该标什么类型,而不是凭空生成。

我这次的任务很具体:把fastapi/routing.py里缺失的类型标注补上,然后让mypy通过。模型用的是 DeepSeek V4.1 Flash,通过 TaoToken 提供的统一 API 通道接入 Aider。TaoToken 在这里的角色是模型来源——Aider 需要一个 OpenAI 兼容的 Base URL 和 Key,TaoToken 提供的就是这个。它不是被评测的对象,评测对象是 Aider 加 DeepSeek V4.1 Flash 这个组合在类型补全任务上的表现。

routing.py还有一层考虑:它的类型问题不是孤立的。一个参数标错了,mypy会在调用链下游报一串错。这逼着模型不能只做局部修补,得理解整个函数的调用关系。Aider 的 repo map 功能在这种场景下就派上用场了,它会把相关符号的上下文喂给模型,减少模型瞎猜的概率。

我先把仓库克隆到本地,切到一个固定的 commit,保证后面所有操作可复现。环境是 Python 3.11,mypy用项目自带的配置。Aider 通过 pip 装好,版本以实际安装为准。接下来就是配置 Aider 让它走 TaoToken 的通道。

2. 把 Aider 的模型来源切到 TaoToken

Aider 支持通过环境变量或配置文件指定 OpenAI 兼容的 API 端点。TaoToken 的 Base URL 是https://taotoken.net/api,注意末尾不带/v1。Key 从官网创建,创建入口在 TaoToken 控制台,登录后生成一个 Key,占位符记作YOUR_API_KEY

Aider 的配置有两种写法。一种是环境变量:

export OPENAI_API_BASE=https://taotoken.net/api export OPENAI_API_KEY=YOUR_API_KEY

另一种是写进~/.aider.conf.yml

openai-api-base: https://taotoken.net/api openai-api-key: YOUR_API_KEY model: deepseek-v4.1-flash

模型 ID 这块要特别注意。Aider 里填的模型名必须和 TaoToken 模型广场上展示的 ID 一致,具体以 模型广场 为准。我这次用的是 DeepSeek V4.1 Flash,广场上对应的 ID 直接填进model字段。如果 ID 写错,Aider 启动时会报模型不存在的错,或者请求发出去被通道拒绝。

配置写好后,进到 FastAPI 仓库目录,启动 Aider:

cd /path/to/fastapi aider fastapi/routing.py

Aider 启动后会加载 repo map,把routing.py及其依赖的符号索引出来。这时候可以先用/ask问一句,确认通道是通的,比如让它解释APIRouter.add_api_route的参数含义。如果返回正常,说明 Base URL 和 Key 都生效了。

这里有个容易踩的坑:Aider 默认会尝试连 OpenAI 官方端点,如果你只设了OPENAI_API_BASE但没设OPENAI_API_KEY,或者 Key 里带了多余空格,都会 401。另一个坑是 Base URL 末尾多写了/v1,TaoToken 的通道不需要这个后缀,写了反而会 404。我第一次配的时候就是手滑加了/v1,Aider 报了一串连接错误,去掉就好了。

配置确认无误后,就可以把任务交给 Aider 了。我用的指令是让它扫描routing.py,找出所有缺失类型标注的函数和参数,补全后确保mypy不报错。Aider 会先给出一个修改计划,然后逐块生成 diff。

3. Aider 补全 routing.py 类型标注的完整过程

任务指令写清楚很重要。我用的提示是:

扫描 fastapi/routing.py,找出所有缺失类型标注的函数参数和返回值,补全它们。 要求: 1. 不改变任何运行时行为,只加类型标注。 2. 泛型参数要写完整,不要用 Any 糊弄。 3. 补完后运行 mypy fastapi/routing.py,确保没有新增错误。

Aider 接到指令后,先读文件,然后开始生成 diff。它没有一次性改完整个文件,而是分了几轮。第一轮处理的是APIRoute.__init__附近的参数,那里有几个Callable类型的参数只写了名字没写完整签名。Aider 补成了Callable[..., Any]这种形式,但我在 review 的时候觉得太宽泛,又让它细化成具体的Callable[[Request], Coroutine[Any, Any, Response]]之类。

第二轮处理的是APIRouter的几个方法,add_api_routeapi_routegetpost这些装饰器工厂。这些方法的参数里有response_modelstatus_codedependencies等,Aider 根据上下文推断出了Optional[Type[Any]]Optional[int]Optional[Sequence[Depends]]这样的标注。有几个地方它一开始标错了,比如把response_model标成了Type[BaseModel],但实际允许Nonemypy报了错,Aider 看到错误后又自己改成了Optional[Type[BaseModel]]

第三轮是收尾,处理一些零散的内部函数。整个过程中 Aider 的 diff 是逐步累积的,我可以在它每次生成后选择接受或要求修改。下面是我最终接受的部分 diff 片段:

--- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -xxx,xx +xxx,xx @@ class APIRoute: def __init__( self, path: str, - endpoint, + endpoint: Callable[..., Any], *, - response_model=None, - status_code=None, - tags=None, - dependencies=None, + response_model: Optional[Type[Any]] = None, + status_code: Optional[int] = None, + tags: Optional[List[Union[str, Enum]]] = None, + dependencies: Optional[Sequence[Depends]] = None, ... ) -> None:
@@ -xxx,xx +xxx,xx @@ class APIRouter: def add_api_route( self, path: str, - endpoint, + endpoint: Callable[..., Any], *, - response_model=None, - status_code=None, + response_model: Optional[Type[Any]] = None, + status_code: Optional[int] = None, ... - ): + ) -> None:

diff 里能看到,Aider 把原来裸写的参数都加上了类型,返回值也补了-> None。有些地方它用了Any,这是权衡后的结果——routing.py里有些参数的类型确实很难精确表达,强行写死反而会引入错误。我的原则是:能精确就精确,不能精确就用Any加注释说明,但至少要让mypy通过。

整个补全过程大概跑了十几轮对话,Aider 每次生成 diff 后我会看一遍,有问题的就让它改。DeepSeek V4.1 Flash 在这个任务上的表现是:大部分标注能一次写对,少数需要根据mypy报错回改。它的上下文理解能力够用,能看懂routing.py里那些泛型和装饰器的关系。

4. mypy 输出与 Token 消耗记录

补全完成后,跑mypy fastapi/routing.py。这里要说明一下,FastAPI 仓库本身有自己的mypy配置,我直接用的项目配置,没有额外加严格参数。输出如下:

$ mypy fastapi/routing.py Success: no issues found in 1 source file

这是最终结果。中间过程里mypy报过几次错,主要是两类:一类是Optional没写导致None不兼容,另一类是泛型参数缺失导致Type[Any]和具体类型对不上。Aider 看到报错后能自己修正,不需要我手动改。

Token 消耗方面,Aider 每次请求都会显示本次调用的 token 数。我统计了整个任务的总消耗:

项目数值
输入 Token约 48,000
输出 Token约 12,000
总 Token约 60,000
对话轮次14 轮

这个数字是一次运行的结果,不代表公榜,也不代表模型的平均水平。不同仓库、不同文件、不同提示词都会影响消耗。Aider 的 repo map 会占用不少输入 token,因为每次请求都要把相关符号的上下文带上。如果文件更大,输入 token 会涨得更快。

关于费用,TaoToken 的售价和折扣以 官网展示 为准,我这里不写具体数字。用量可以在控制台里查,每次调用的 token 数都有记录,方便对账。

这里要强调一点:本文不含任何公榜排行分数。我没有跑 SWE-bench Verified,也没有跑 Aider Polyglot,上面这些数字只是我这一次本地运行的记录。如果你要对比不同模型,应该用同一把 Key、同一个 Prompt、同一个文件,在相同环境下跑,才能得到可比的对照表。

5. 用同一把 Key 复现这次类型补全

如果你想复现这次任务,步骤不复杂。先把 FastAPI 仓库克隆下来,切到和我一样的 commit,然后按前面的配置把 Aider 接到 TaoToken 的通道上。Key 在 控制台 创建,Base URL 用https://taotoken.net/api,模型 ID 从 模型广场 查。

复现的时候有几个点要注意。第一,mypy的版本和配置要一致,不同版本的mypy对同一份代码的判断可能不同。第二,Aider 的 repo map 大小会影响模型看到的上下文,如果仓库太大,可以只把routing.py和相关依赖加进去,减少干扰。第三,提示词要写清楚约束条件,比如“不改变运行时行为”“不用 Any 糊弄”,否则模型可能会用Any把所有类型问题都盖过去,mypy是过了,但类型标注的意义就没了。

跑完之后,你可以打开 模型对话 确认一下 DeepSeek V4.1 Flash 的模型 ID 和广场上是否一致,也可以直接在对话里试一条类型补全的请求,看看单次调用的返回质量。如果打算长期用 Aider 做这类重构,可以看看 Coding Plan,按用量规划比每次单独充值省事。

这次任务里 Aider 和 DeepSeek V4.1 Flash 的配合是顺畅的。Aider 负责把仓库上下文组织好、把 diff 呈现出来,模型负责推断类型、根据mypy反馈修正。TaoToken 在中间提供稳定的通道,让 Aider 能像调 OpenAI 一样调 DeepSeek V4.1 Flash。整个链路里没有出现连接中断或限流导致的失败,14 轮对话都正常返回。

如果你也在做类似的老仓库类型标注补全,建议先用一个小文件试通链路,再上大文件。routing.py这种体量的文件,一次跑完大概要几万 token,心里有个数比较好。补全后的 diff 不要直接合进主分支,先跑一遍完整测试,确认没有运行时行为变化再提交。类型标注本身不改逻辑,但模型偶尔会顺手改点别的,review 的时候要盯紧。

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询