aider 实战:用自然语言会话从零打造一个 Flask Web 应用(Hello World Flask 全流程解析)
2026/9/9 13:32:02 网站建设 项目流程

aider 实战:用自然语言会话从零打造一个 Flask Web 应用(Hello World Flask 全流程解析)

【免费下载链接】aideraider is AI pair programming in your terminal项目地址: https://gitcode.com/GitHub_Trending/ai/aider

导读

本篇基于 aider 官方「Example chat transcripts」中的 hello-world-flask.md 会话实录,逐段还原一段真实的、几乎零手写代码的结对编程过程:在一个空白的app.py上,通过连续四条自然语言指令,让 aider 自动创建 Flask 应用、逐步追加路由、并完成一次代码删除重构。读完你将掌握 aider 的核心交互范式——命令行启动、Edit Block(搜索/替换编辑块)的语法结构、自动应用编辑与 Git 自动提交机制,从而在自己的项目里复现这套“下达需求 → AI 改码 → 自动提交”的高效工作流。

会话背景:一行命令,从空文件开始

这段实录的开头,用户仅执行了一条命令,便启动了一个面向app.py的 aider 会话:

$ aider app.py Creating empty file app.py Added app.py to the chat

其背后对应的是 aider「把文件加入会话」的机制:通过命令行参数或在会话内使用/add命令,把相关源码文件“加入聊天”。只有加入会话的文件,模型才能读取并编辑;examples/README.md 中明确说明了这一点:

The LLM can only see and edit files which have been "added to the chat session". The user adds files either via the command line or the in-chat/addcommand.

当目标是尚不存在的文件时,aider 会先创建空文件(Creating empty file app.py),再加入会话(Added app.py to the chat),后续模型的所有改动都落在这个被监管的文件里。这一机制决定了后续每个需求都聚焦于同一个app.py,也方便演示 aider 如何对同一文件反复做增量修改与删除。

第一步:从空文件到第一个/hello接口

自然语言需求

会话中的第一条用户消息只有一句自然语言:

make a flask app with a /hello endpoint that returns hello world

没有框架选择讨论、没有工程脚手架命令、没有目录规划——需求被直接、完整地交给了模型。

模型返回的 Edit Block

模型没有像“聊天机器人”那样只给一段供你复制的代码,而是直接返回了一个结构化的Edit Block(搜索/替换编辑块),指定改动目标文件和精确的替换内容:

app.py <<<<<<< ORIGINAL ======= from flask import Flask app = Flask(__name__) @app.route('/hello') def hello(): return "Hello, World!" if __name__ == '__main__': app.run() >>>>>>> UPDATED

注意这段实录所使用的编辑块标记为<<<<<<< ORIGINAL/=======/>>>>>>> UPDATED(这是该实录录制时期 aider 使用的 diff 标记形式),其语义是:ORIGINAL=======之间是需要被搜索到的原文件片段,=======UPDATED之间是替换后的新内容。由于app.py当时是空文件,所以 ORIGINAL 段为空,等价于“创建文件并写入以下内容”。

关于 Edit Block 在当代 aider 中的精确约束,可以从源码中看到更正式的定义:editblock_prompts.py 中的 system_reminder 要求模型必须遵守:

  1. 完整的文件路径单独占一行;
  2. 开头围栏与语言标识(如 ```python);
  3. <<<<<<< SEARCH标记搜索段的开始;
  4. 在已有源码中精确匹配的连续内容片段;
  5. =======分隔线;
  6. 替换进去的新内容;
  7. >>>>>>> REPLACE结束标记;
  8. 闭合围栏。

同时要求 SEARCH 段必须“字符级精确匹配”现有文件,并且一条块只替换首次匹配的位置(see editblock_coder.py 中用于解析块头的HEADDIVIDERUPDATED正则)。这种“只交差额”的格式非常省 token:模型不需要像 whole 格式那样回传整个文件,只需给出发生变化的片段。

自动应用与自动提交

消息正文之后紧跟两条带>前缀的工具输出,这是 aider 自身的状态回显:

> Applied edit to app.py > Commit 414c394 aider: Added a `/hello` endpoint that returns "Hello, World!" to the Flask app.

这正是该会话工具链的“三件套”闭环:

  1. 自动应用:模型输出 Edit Block 后,aider 解析并把它直接写回app.py,无需用户手工复制粘贴;
  2. 自动提交:每次成功应用改动后,aider 自动为这次改动创建一次 Git commit;
  3. 描述性提交信息:提交信息由模型基于 diff 与上下文自动生成(如Added a/helloendpoint that returns "Hello, World!" to the Flask app.),并默认以aider:前缀标识。在源码中,自动提交的入口是 base_coder.py 的auto_commit(),它调用 repo.py 的commit();若为 aider 生成的改动,提交信息会被自动加上前缀(见 repo.py 中的commit_message = "aider: " + commit_message)。

app.run()的使用也说明这一版模型生成的代码是“开发服务器”形态的 Flask 应用,同时模型在回答中提醒用户运行前需在环境中安装依赖(pip install flask)。

第二步:利用 URL 参数新增/add/3/5求和接口

第二条用户需求同样是口语化的功能描述:

add an endpoint like /add/3/5 which returns the sum of the 2 numbers

模型理解了“路径中的两个数字是参数”,并给出第二个 Edit Block——这次不是从空文件创建,而是对已有代码做精准定位替换。它将新增的add路由插入到现有hello路由之前,保持=======两侧内容一一对应:

app.py <<<<<<< ORIGINAL @app.route('/hello') def hello(): return "Hello, World!" ======= @app.route('/add/<int:num1>/<int:num2>') def add(num1, num2): return str(num1 + num2) @app.route('/hello') def hello(): return "Hello, World!" >>>>>>> UPDATED

这里体现了 Edit Block 的高效性:ORIGINAL 段只需要包含足以唯一定位的几行上下文(这里是整个hello路由),REPLACE 段则是改写后的完整片段。模型使用 Flask 的<int:num1>转换器把两个路径段转成整型参数,并用str()包裹返回值以符合 HTTP 响应为字符串的要求。

应用与提交再次自动完成:

> Applied edit to app.py > Commit 0872c51 aider: Added an endpoint `/add/<int:num1>/<int:num2>` that returns the sum of the two numbers.

模型在文字说明里也直接给出了可验证的运行结果:访问/add/3/5将返回两者之和8

第三步:实现/fibonacci/X——在已有文件中追加新函数与新路由

第三条需求把难度提升到“新增业务逻辑”级别:

add /fibonacci/X

模型在同一个app.py内完成了两处内容的协调:新增一个独立的fibonacci(n)辅助函数,以及对应的/fibonacci/<int:x>路由视图。Edit Block 一次性地把两段新代码都安放在hello路由之前:

app.py <<<<<<< ORIGINAL @app.route('/hello') def hello(): return "Hello, World!" ======= def fibonacci(n): if n <= 0: return "Invalid input. Please enter a positive integer." elif n == 1: return 0 elif n == 2: return 1 else: a, b = 0, 1 for _ in range(n - 2): a, b = b, a + b return b @app.route('/fibonacci/<int:x>') def fibonacci_x(x): return str(fibonacci(x)) @app.route('/hello') def hello(): return "Hello, World!" >>>>>>> UPDATED

这段代码本身还展示了模型不错的工程细节处理:对非法输入(n <= 0)返回友好提示;按约定采用「第 1 项为 0、第 2 项为 1」的序列定义;用迭代而非递归计算,避免深栈;视图函数把整形结果str()化后返回。回答末尾给出验证样例:访问/fibonacci/5应返回3

随后照例自动应用并提交:

> Applied edit to app.py > Commit 163fba8 aider: Added a `/fibonacci/X` endpoint that returns the Xth number in the Fibonacci sequence.

一个值得注意的细节:此刻文件里已经同时存在helloaddfibonacci三个路由及其函数,而前文 add 路由引入时顺序为add → hello,本次块只定位了hello片段并前插新代码,最终顺序演变为fibonacci → add → hello(各次 Edit Block 依次叠代)。这也印证了“每个 SEARCH 片段只需足够唯一即可精确落点”的设计。

第四步:需求驱动的删除——移除/hello路由

四条需求里最“反直觉”的一条是删除既有功能:

remove the hello endpoint

模型的 Edit Block 把 ORIGINAL 段设置为待删除的完整路由,而 REPLACE 段为空——用“把一段内容替换成空”来表达删除:

app.py <<<<<<< ORIGINAL @app.route('/hello') def hello(): return "Hello, World!" ======= >>>>>>> UPDATED

对应到 editblock_prompts.py 的规则,模型同样可以用空 SEARCH + 非空 REPLACE 来创建新文件;删除则反过来(非空 SEARCH + 空 REPLACE)。虽然回答中没有像前几步那样包含完整的“演进后文件”,但工具日志证实删除被成功落盘并提交:

> Applied edit to app.py > Commit eab6620 aider: Removed the `/hello` endpoint from the Flask app.

至此,经过四条自然语言指令的连续对话,app.py从空文件演进为包含addfibonacci两个可用接口的 Flask 应用,且每一步都有独立的 Git 提交可回溯。

如何读懂与复现这类“会话实录”?

仓库里的 examples/README.md 对阅读此类 transcript 给出三条背景说明,恰好概括了本段实录的全部语法要素:

  1. 每次模型提出改动,aider 都会自动应用到源文件——对应每轮Applied edit to app.py
  2. 应用后 aider 会以描述性提交信息自动 commit——对应每轮Commit <hash> aider: <描述>
  3. 模型只能看到被加入会话的文件——用户在启动时(aider app.py)或会话内(/add)指定,若模型希望查看更多文件,aider 会先征求用户许可再加入会话。

另外注意格式符号约定:以>开头的是 aider 工具的输出,以####开头的是用户输入的消息,其余正文(蓝字)是模型回复。这与仓库 CSS/渲染体系中的.chat-transcript样式(见 recording.css 等)对应。

需要提醒的是:本段实录是较早版本aider 的产物,其编辑块写作<<<<<<< ORIGINAL/>>>>>>> UPDATED;当前版本统一采用<<<<<<< SEARCH/>>>>>>> REPLACE标记(见 editblock_prompts.py 示例与 editblock_coder.py),语义完全一致,理解时可无缝迁移。关于 aider 支持的多种编辑格式(whole、diff、diff-fenced、udiff、editor-diff/editor-whole 等)与--edit-format强制切换,可参考 edit-formats.md。

如果你想亲自复现这段对话,推荐这样操作:

  1. 准备一个 Git 仓库目录(aider 依赖 Git 完成自动提交);
  2. 安装 Flask 运行环境;
  3. 按顺序执行以下启动命令与需求(需求完全复刻自本实录):
    • $ aider app.py
    • make a flask app with a /hello endpoint that returns hello world
    • add an endpoint like /add/3/5 which returns the sum of the 2 numbers
    • add /fibonacci/X
    • remove the hello endpoint
  4. git log查看自动生成的数次提交,或用 aider 内置的/undo撤销任意一步自动提交。

由于当前版本与实录录制时代存在模型与格式差异,具体生成的代码风格可能略有不同,但“自然语言下达需求 → Edit Block 精准改码 → 自动提交”的核心交互闭环完全一致。

小结:从这段实录得到的四个可迁移认知

  1. “以文件为粒度”的协作模型:先aider app.py把文件纳入会话,之后所有编辑请求都锁定在该文件内,模型不会擅自改动未被加入的文件(examples/README.md)。
  2. Edit Block 是 AI 与文件之间的“结构化协议”:全路径 + SEARCH/REPLACE 段落 + 精确字符匹配 + 只改首处匹配,让“改哪、怎么改”对用户完全透明、可审阅、可追溯(editblock_prompts.py)。
  3. 安全网由 Git 提供:每次自动应用后紧跟着自动提交,提交信息自带aider:前缀,既能快速 diff 每一步,也能配合/undo逐条回退(base_coder.py、repo.py)。
  4. 增量式需求开发完全可行:从空文件起步,创建 → 追加 → 扩展算法 → 删除,全程无需用户手写一行代码,模型通过连续 Edit Block 在同文件上完成平滑演进。

延伸阅读(仓库内)

  • 完整会话原文:hello-world-flask.md
  • 更多示例会话总览:examples/README.md
  • Edit Block 格式的完整规则与示例:editblock_prompts.py
  • 编辑块解析实现:editblock_coder.py
  • 各编辑格式对比:edit-formats.md
  • 安装与使用指南:install.md 与 usage.md

【免费下载链接】aideraider is AI pair programming in your terminal项目地址: https://gitcode.com/GitHub_Trending/ai/aider

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

立即咨询