The Evolution of Coding in the AI Era

文章翻译: The Evolution of Coding in the AI Era 人工智能时代的编码演变 2024 年 8 月 23 日 · Arvid Kahl 阅读时间:约 8 分钟 几年前,我还是一个完全不同的程序员。巅峰时我能轻松浏览文档并主要写出能用的代码;状态差的时候,我会为了一个笔误或古怪的 bug 折腾好几个小时,毫无结果。 那时我从来不会想到用 AI 来帮我 —— 因为它还不存在。 但现在情况变了。 我们生活在这样一个世界:不使用 AI 工具(AI tooling)来写代码的软件开发者,正逐渐变得少见。现在可用的技术要么极其便宜、要么免费,其实用性和影响力如此普遍,以至于过去五年或十年那种编程方式很可能被彻底替代。 代价也是存在的。 这种转变在生产力和速度上带来了若干好处,但也激发了很多恐惧,并暴露出值得探讨的潜在问题。 作为一个使用 AI 工具来构建软件产品的人,我想思考我们为何走上这条路径、存在哪些风险,以及如何缓解这些风险。我也想探讨,这对那些刚开始学习编程并要在一个把 AI 视为软件开发常态的世界里构建产品的人意味着什么。 AI 在编码中的力量 使用 AI 最大的明显优势很简单:它比你打字快。AI 生成代码的速度远超人类。即便是最近那些非 AI 的、高度复杂的代码编写工具,也比不上开源 AI 目前能做的速度与效率。这里所说的 AI 指的是专门以写代码为训练目标的大型语言模型(large language models,LLMs),或是通用到足以为用户生成代码的模型。像 ChatGPT、Claude 等都能写出代码,其中有些在产出能真正运行的软件方面表现更好。 作为软件创业者,我必须在解决有趣技术挑战的意愿和业务需求之间找到平衡。任何能让我更快地写出高质量、可靠代码的方法,我都必须去尝试。当第一批 AI 编码助手进入市场时,我很快就注意到它们的威力。对于有经验的开发者来说,这些工具非常有用——它们能生成我可以快速审阅并决定接受或拒绝的代码。 这就是关键:你必须懂得什么是好代码,才能批准好代码。 有经验的编程背景会让这些工具变得更有价值。你实际上是在外包“写逻辑”这一过程,而你所做的则是持续不断地进行代码审查(code review)。AI 做的一切就像给你发来一个拉取请求(pull request)供你审阅。这带来两点含义: 对有经验的开发者而言,这些工具对工作质量的影响是巨大的。 对于正在学习编程的人来说,仍然有必要理解编码的核心原理,才能有效评判 AI 给出的结果。 学习曲线与 AI 这是我看到人们最关心的核心问题:如果你靠 AI 学编程,你可能永远不会真正理解那些你需要用来评判代码的解决方案。你需要知道“配方”的原材料和工作原理,才能下厨;否则你只是把食物弄坏。对代码也是如此——你需要理解语法、语义、求值和执行的过程。 ...

September 11, 2025 · 1 min · 192 words · Starslayerx

Dealing With Grabage in Python

Grabage Collection In Python 本篇文章介绍 Python 中的 Grabage Collection (GC) 机制介绍 What’s Python Object? Python 对象中有三样东西: 类型(Type)、值(value)和引用计数(reference count), 当给变量命名时, Python 会自动检测其类型, 值在定义对象时声明, 引用计数是指该对象名称的数量. 首先来看一个类 class Person: def __init__(self, name, unique_id, spouse): self.name = name self.unique_id = unique_id self.spouse = spouse def __del__(self): print( # !r: 调用 repr() 来获取该对象的字符串表达式 # !s: str() # !a: ascii() f"Object {self.unique_id!r} is about to be removed from memory. Goodbye!" ) 该 Person 类有以下3个属性: name: 人名 unique_id: 唯一性 id spouse: 将为 None 或者将存储另一个 Person 对象 有一个特殊方法 __del__(), 这个特殊方法有一定的误导性. 该方法并不像 __len__() 与 len() 或者 __iter__() 与 iter() 那样与 del 关键字相关联. __del__() 特殊方法并不定义当对对象引用时 del 会发送什么, 相反, __del__() 是一个终结器 finaliser: 它在对象被消毁之前从内存中移除之间被调用. 因此, __del__() 中 print() 调用的字符串仅在 Python 即将从内存中移除对象时显示. ...

September 8, 2025 · 2 min · 241 words · Starslayerx

How AI Assistants Make Precise Edits to Your Files

之前的文章介绍了如何制作一个基本的 AI 编程助手, 今天更近一步, 探讨 AI 助手如何对文件进行精确的修改. 实际的 AI Agent 不会读取所有的项目代码, 一般只会读取当前文件的代码, 当需要时才会去读取相关的代码文件. 然而, 输出也不会输出要修改的整个文件的代码, 因为这样输出不仅很慢, 同时成本也很高, 会有大量重复代码导致浪费(以 deepseek 为例, 输出 token 的价格是输入 token 价格的3倍, 是缓存命中输入 token 价格的24倍!), 因此一般是让模型输出要修改的代码和修改后的代码. 既然不能一次输出文件的所有代码, 这就引出了一个问题: 如何精确的修改代码文件? 首先要确定一种让模型准确地描述修改的格式, 并且提供健壮的格式匹配与错误重试机制(模型输出代码可能少个空格或者Tab), 这篇文章对这个问题做了探讨. 将 AI agent 生成的代码直接修改到文件中是一项核心能力, 然而实际上这常常出乎意料的困难, agent 可能会提出一个代码修改方案, 但实际修改却失败, 例如"找不到匹配的上下文"之类的错误, 需要手动干预. 许多 AI 编程助手的开发者都遇到过这种情况, 虽然 AI 理解代码的意图, 但将这种理解转化为精确的文件修改却带来了重大的技术挑战. Why Precise File Editing Matters 为什么精确的文件编辑至关重要 有效的文件编辑是编程助手的价值核心, 如果其不能可靠的修改文件, 需要人为手动修改, 就退化成了 AI 聊天引擎, 相比之下, 一个能够可靠自动化编辑的助手可以为开发者节省大量时间和认知负担. 根本的挑战在于, LLM 缺乏直接的文件系统访问权限, 他们必须通过专门的工具来描述预期的修改, 然后这些工具或 API 解释指令并尝试执行, LLM 的描述与文件系统状态之间的这种交接是常见的问题来源. 使用 GitHub Coplit、Aider、RooCode 或 Cursor 等工具的用户可能已经观察到这些问题: 编辑器无法找到正确的插入点、缩进不正确, 或者工具最终请求手动应用. ...

September 2, 2025 · 7 min · 1373 words · Starslayerx

Make an AI Coding Agent in python

这篇文件介绍如何使用 Python 制作一个基础的 AI 编程助手 Minimal AI Coding Agent 下面是一个 AI Coding Agent 至少需要的功能 Chat loop 对话循环 Call an LLM 调用大语言模型 Add tools to call 增加工具调用 Handle tool request 处理工具调用请求 Step 1: Chat Loop 首先, 聊天循环一直循环等待用户输入, Python 的 “input” 方法可以获取用户输入 print("Type q to quit") while True: user_message = input("You: ") if user_message == "q": break ai_message = f"You said {user_message}... so insightful" print(ai_message) 目前主流的 LLM 都是无状态的, 所以需要我们手动的去管理对话上下文, 这里使用一个 fake_ai 函数模拟真实的 LLM 调用, 并包含 role 和 content 内容 ...

September 1, 2025 · 11 min · 2265 words · Starslayerx

Asyncio vs Gevents in Python

python 中 asyncio 和 gevent 是两种协程(在一个线程内实现并发)的实现, 这篇文章对比介绍这两者实现. 下面先介绍一下基础概念: Coroutines 协程 在 Python 中, 协程是可以暂停和继续运行的函数, 使得其是否适合并发编程. 定义使用 async def 语法, 协程运行编写非阻塞的操作. 在协程内, await 关键字用于暂停执行, 直到给定的任务完成, 从而运行其他协程在此其间并发运行. Event Loop 事件循环 事件循环是一种控制结构, 它不断地处理一系列事件, 处理任务并管理程序的执行流程. 等待事件发生, 处理后再等待下一个事件. 这种机制确保程序能够以高效有序的方式响应事件, 例如用户输入、计时器或者消息. 下面是事件循环如何管理协程: 任务提交: 当向事件循环提交一个协程时, 其被封装在一个 Task 对象中, 然后任务被安排在事件循环上运行. 内部队列: 事件循环使用几个内部数据结构来管理和调度这些任务 就绪队列 (Ready Queue): 包含可以立即运行的任务. I/O 选择器 (I/O Selector): 监控文件描述符, 并根据 I/O 准备情况调度任务 计划回调 (Scheduled Callbacks): 管理计划在一定延迟后运行的任务. 调度: 事件循环不断检查这些队列和数据结构, 以确定哪些任务已准备好执行. 然后它运行这些任务, 在遇到 await 语句时, 根据需要暂停和恢复它们. 并发管理: 通过交错执行多个协程, 事件循环无需多个线程即可实现并发. 在任何时候, 只有一个任务会运行, 但如果一个任务是 I/O 密集型的, 它会切换到另一个任务, 给人一种并行的错觉. ...

August 29, 2025 · 4 min · 694 words · Starslayerx

Prompt Organization

这篇文章旨在介绍 Python 中常用的提示词组织方式 f-string 使用 f 字符串填充变量得到提示词 def get_prompt(query: str) -> list[dict]: SYSTEM_PROMPT = f"""... ... 多行提示词, 也可以填充变量 """ USER_PROMPT = f"""INPUT: {query} .... """ return [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": USER_PROMPT}, ] 这种方法实现简单, 速度快, 但是: 多行字符串由于填充变量的需要, 需写在函数内, 导致代码格式混乱 # 实际上, 多行字符串还可以这样实现, 但也不太时候提示词太多的时候, 但这样代码格式会更加优雅 system_prompt = ( f"你是一名{role}负责...\n" f"具体规则:\n" f"1. ...." f"2. ...." ) 上面这种方法会将多行字符串合并, 注意不要加逗号, 不然就变成元组了 通过代码构造提示词, 任何修改都需要修改代码, 扩展性差 string.Template 使用 Python 元素字符串模板 SYSTEM_PROMPT = string.Template("""你是一名$role 多行提示词... """) USER_PROMPT = string.Template("""INPUT: $query """) def get_prompt(role: str, query: str) -> list[dict]: system_prompt = SYSTEM_PROMPT.subtitute(role="助手") user_prompt = USER_PROMPT.subtitute(query="问题...") return [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}, ] 使用模板字符串, 模板则不必写在函数内, 且模板字符串可以选择替换部分变量, 使用 .safe_substitute()方法传入一个字典, 例如 {"query": "问题..."}, 对没有传入的变量解析为 $var 对比 f-string, 模板字符串更加灵活, 且可以只传入部分值 ...

August 28, 2025 · 2 min · 305 words · Starslayerx

From Python to Go

From Python to Go: Why We Rewrote Our Ingest Pipeline at Telemetry Harbor 我们将 Telemetry Harbor 的摄取管道从 Python FastAPI 重写为 Go,原因是遇到了严重的性能瓶颈。迁移后,效率提升了 10 倍,数据完整性因严格类型检查而得到加强,系统也拥有了稳定、可扩展的高并发时间序列数据摄取基础。 背景:打造一个时间序列数据平台 Telemetry Harbor 源自我们在汽车行业积累的经验。几乎每个项目都要重复搭建相同的基础设施:数据库、后端、数据摄取管道、可视化界面。每次都要花费数周时间,这让我们萌生了打造一个开箱即用平台的想法。 当时的市场方案并不理想。InfluxDB 的商业化策略让许多关键特性被锁在付费墙后,版本迁移成本高且在大数据负载下表现不佳。TimescaleDB 与 ClickHouse 技术上更强大,但依旧需要用户自行构建后端与摄取管道。我们看到了缺口——需要一个极简、可靠、可直接使用的平台。 Python FastAPI:原型开发的正确选择 MVP 阶段,我们在开发速度与运行性能之间权衡。最终选择了 Python FastAPI,因为它允许我们: 快速验证市场假设 迅速收集客户反馈并迭代 在低成本下尝试多种方案 尽快上线以抢占市场 早期架构非常直接:HTTP API(避免防火墙问题)、Redis + RQ 队列、TimescaleDB。测试效果良好,但很快暴露了性能隐患——RQ 的同步处理方式无法支撑高吞吐场景。 性能瓶颈:Python 无法跟上增长 随着数据量上升,性能问题逐渐浮现: 空闲 CPU 占用:10% 中等负载:约 40% CPU 高负载:120–300% CPU(峰值 800%),频繁崩溃 问题不仅在于 RQ 的同步限制,而是整个 Python 架构在常规负载下都难以维持稳定。这迫使我们考虑全面重写。 迁移决策:为什么选择 Go? 我们评估了 Rust 和 Go: ...

August 27, 2025 · 1 min · 148 words · Starslayerx

Documenting REST APIs with OpenAPI

本章介绍如何使用 OpenAPI 来为 API 编写文档. OpenAPI 是描述 RESTful API 最流行的标准, 拥有丰富的生态系统, 可以用于测试、验证和可视化 API. 大多数编程语言都支持 OpenAPI 规范的库. OpenAPI 使用 JSON Schema 来描述 API 的结构和模型, 因此首先介绍 JSON Schema 的工作原理. JSON Schema 是一种用于定义 JSON 文档结构的规范, 包括文档中值的类型和格式. Using JSON Schema to model data 使用 JSON Schema 对数据建模 JSON Schema 是一种规范标准, 用于定义 JSON 文档的结构及其属性的类型和格式. JSON Schema 规范通常定义一个具有特定属性或特性的对象, 由键值对的关联数组表示, 如下面这样: { "status": { "type": "string" } } 在 JSON Schema 规范中, 每个属性都以键值对的形式出现, 其中值是该属性的描述符 一个属性最基本的描述符就是 type, 上面例子中, 指定类型为字符串 JSON Schema 支持以下基本数据类型: ...

August 25, 2025 · 9 min · 1727 words · Starslayerx

Rust Alternaitve Tools

常用工具的 rust 替代品. Introduction 在 Unix 生态中, 许多命令行工具都是用 C 编写的, 经过几十年的优化, 性能和稳定性都非常优秀. 然而, 近年来, Rust 以其安全性、内存管理优势和现代化开发体验, 成为系统级工具开发的理想选择. 首先更新 cargo, 不同系统都可以使用 cargo 安装, 当然也可以使用系统的包管理器安装 rustup update stable 有需要的话修改源, 一般在 ~/.cargo/config.toml, 下面是科大源 [source.crates-io] replace-with = 'ustc' [source.ustc] registry = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/" [registries.ustc] index = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/" Filesystem & Archiving 文件系统与归档 exa 替代 ls: 彩色支持 Git 状态的 ls 替代品 常用参数: -1: 一行显示一个文件 -l: 显示文件细节信息 -F: 在目录文件名末添加斜杠符号 -T: 树状显示 -R: 递归显示所有文件 --icons: 显示图标 zoxide 替代 cd: 基于访问频率的快速目录跳转工具 常用参数: z foo # 匹配 foo 的路径 z foo bar # 匹配 foo & bar 的路径 z - # 回到之前目录 zi foo # fzf File & Text Processing 文件与文本处理 bat 替代 cat: 具备语法高亮、行号显示、Git 集成等功能, 让查看文件内容更加美观 ripgrep 替代 grep: 使用 Rust 编写的极速文本搜索工具, 支持递归搜索、正则表达式、忽略规则(.gitignore)等 fd 替代 find: 提供简单直观的语法、更快的搜索性能, 并默认支持彩色输出和忽略 .gitignore 文件 System Monitoring & Management 系统监控与管理 bottom 替代 top / htop: 一个现代化的系统资源监控工具, 支持 CPU、内存、磁盘、网络等多种指标显示, 并提供交互式界面 procs 替代 ps: 更人性化的进程信息显示, 支持彩色输出、树状显示、搜索与过滤 Wrapping up Rust 的安全性和高性能使其成为编写现代 Linux 工具的理想选择. 这些替代品不仅提供了更好的用户体验, 还利用 Rust 的并发优势和零成本抽象提升了性能. 其他一些 rust 工具: ...

August 23, 2025 · 1 min · 160 words · Starslayerx

Tokei

Tokei 介绍 Tokei是一款 Rust 编写的开源工具, 用于统计项目代码行数, 支持上百种语言, 能够扫描整个代码库, 包括: 语言 文件数量 代码行数 注释行数 空行数 得益于 Rust 的高性能实现, Tokei 即使在超大规模代码库中也能保持极快的统计速度 (Rust 轮子真不错) 安装 brew install tokei 或者 cargo install tokei 使用 在项目根目录执行 tokei . 输出类似下面这样 =============================================================================== Language Files Lines Code Comments Blanks =============================================================================== Dockerfile 1 25 9 8 8 Python 52 2914 2372 96 446 TOML 1 65 58 0 7 YAML 2 49 45 0 4 ------------------------------------------------------------------------------- Markdown 1 194 0 158 36 |- BASH 1 13 13 0 0 (Total) 207 13 158 36 =============================================================================== Total 57 3247 2484 262 501 ===============================================================================

August 22, 2025 · 1 min · 93 words · Starslayerx