解密工程中的 AI
Source: Dev.to
在谈论软件工程中的 AI 时,我经常听到类似的说法:
“我不信任它。”
“它真的能节省时间吗?”
“我为什么要用它,我自己可以完成啊?”
“它不过是一个统计模型。”
“它只会写出烂代码。”
这些担忧并非全然错误。实际上,现代 AI 确实是一个统计模型——但这并不意味着它没有用处。
我的目标不是向你推销 AI,也不是写一篇学术论文。我想给你一个清晰、实用的视角,让你了解当今模型的真实工作方式,从而更好地判断它们何时有价值,何时没有价值。
为此,了解这些怀疑来源的背景会很有帮助。
Source: …
昨天的 AI
让我们回到大约十年前的 2010 年代中期,那时 机器学习 是当时的流行词。我们开始把一些东西称作 “AI”,但我们拥有的大多数都是狭窄、专用的模型。
当时的思路很直接:计算机擅长处理数字,所以如果我们能把文本、图像以及其他杂乱的数据转换成数字,就可以在其上训练模型。像 word2vec 之类的工具所推广的 向量嵌入 技术,使得通过将词语或图像表示为保留一定意义的数值向量成为可能。
在此基础上,我们使用大规模标注数据集来训练模型。你会向模型展示示例:
- “这是一个松饼。”
- “这不是一个松饼。”
随着时间的推移,它学会了统计模式,从而能够判断一张新图像是否可能是松饼。
局限性
- 监督式、狭窄、任务特定:模型被训练来做好一件事(例如图像分类、文本标注、垃圾邮件检测)。
- 一次只接受单一输入:它们在高度受限的问题空间中运行。
- 脆弱且训练缓慢:一个擅长识别松饼的模型对检测癌症或翻译文本毫无用处。
- 规模小:“大”模型的参数量只有几百万(有时是几千万),且只能达到它们所训练数据的水平。
鉴于这段历史,许多工程师对 “AI” 产生不信任也就不足为奇了。
Source: …
发生了什么变化
那么我们是如何从那个时代走到今天使用的生成模型的呢?有几件事发生了变化,但最关键的有三点。
1. Transformer(转换器)
最重要的转折是 Transformer 架构的引入。
在 Transformer 之前,模型主要以顺序方式处理语言——一次一个词,对长程依赖的理解能力有限。
示例:“The bank can guarantee deposits will eventually cover future tuition.”
要判断 “bank” 是指金融机构还是河岸,需要查看后面出现的词:“deposits”、“cover”、“tuition”。顺序模型会因为在处理这些后续词时已经忘记了 “bank” 周围的上下文而表现不佳。
Transformer 通过 注意力(attention) 机制解决了这个问题:它不再一次处理一个词,而是让模型同时查看所有词,并学习哪些词彼此相关。当处理 “bank” 时,模型可以直接关注到 “deposits” 和 “tuition”,不受距离限制。
- 多层注意力堆叠在一起,学习越来越复杂的关系。
- 较低层可能会把 “bank” → “deposits” 关联起来,而更深层则会把 “deposits” → “cover future tuition” 关联起来,从而构建对整句的丰富理解。
这一单一改变极大地扩展了模型的理解和生成能力,使机器学习从狭窄的分类任务跃迁到通用语言模型。
2. 模型原生上下文
十年前,上下文主要由 应用代码 管理。如果你想对客户评论进行情感分析,需要:
- 将每条评论预处理成模型所需的精确格式(例如,几十个词,去除多余信息)。
- 对每条评论单独进行一次预测。
- 手动汇总结果。
模型 没有记忆,不了解之前的评论、产品本身,也不掌握客户的历史。每次预测都是孤立的,实际的 token 限制通常只有几百。模型是无状态的,调用之间会“忘记”所有信息。
如今,上下文大多由模型本身管理,并且可以跨越更大的窗口——通常是 数十万 token。
- 你可以一次性把整套产品文档、客户反馈集合、最近的支持工单以及当前的功能路线图 全部喂给模型。
- 模型能够识别出客户对结账流程的不满是因为你上个月下线的某个功能本来解决了他们的工作流问题,而你之前并未意识到这一点。
- 当你询问客户痛点时,模型会动态加权相关上下文,连接不同渠道的投诉,发现不同用户群体对同一问题的描述模式,并且降低一次性或无关反馈的权重。
正因为如此,模型现在可以帮助完成 综合用户研究、生成涵盖多种使用场景的文档 等任务。限制因素已经从“模型能看到多少?”转变为“模型能否有效推理它看到的内容?”。
3. 规模与通用性
一旦 Transformer 证明了注意力机制的高效性,随后出现了两条互补趋势:
- 模型规模的巨幅扩张——从几百万参数增长到 数千亿参数。
- 在多样且海量的数据集上训练——包括网络文本、代码、图像以及多模态数据。
这些趋势催生了 通用基础模型,它们可以 通过提示(prompt) 来执行各种任务,而无需针对每个任务进行专门的微调。同一个模型既能写代码,又能起草邮件、翻译语言或生成单元测试,只需更改提示即可。
结论
- 现代 AI 仍然是统计模型,但 Transformer 架构、模型原生上下文 与 大规模 已将其转变为多功能、通用的工具。
- 理解这三大转变有助于你判断 何时 信任模型、何时 它能带来真实价值,以及 何时 传统的确定性解决方案仍是更好的选择。
使用这种视角来评估项目中的 AI 提案:思考模型被要求完成 什么,它将如何获取上下文,以及其规模和通用性是否适合手头的问题。
Scaling Up: From Curated Datasets to Massive, Diverse Corpora
我们可以进行规模化,于是开始在更广泛的数据集上训练模型:公开可用的文本、代码、文档、书籍和研究资料。
旧的做法是为特定任务精心策划数据集。你会收集成千上万封标记好的垃圾邮件来构建垃圾邮件过滤器,或收集成千上万张医学影像来检测肿瘤。每个模型都是专门的专家。
新的做法则颠倒了这一点。我们不再为不同任务训练不同模型,而是对单一模型使用庞大且多样的数据集,让它在全部数据中学习通用模式。
这很重要,因为这些模式只有在大规模下才会显现。
- 在一百个 Python 脚本上训练模型 → 它学会基本语法。
- 在数百万个跨越数十种语言的代码库上训练 → 它学会更深层的模式:架构决策如何导致特定的 bug、不同生态系统的测试策略有何差异、命名约定如何传递意图。
这就是为什么你可以让现代模型编写 Rust 代码,即使你自己从未写过 Rust,或让它“像对朋友解释一样”解释复杂算法。模型已经见过足够多的例子,能够对从未遇到过的请求进行概括。
我们从数百万参数迈向数十亿参数。其回报是一种根本不同的工具——它可以跨领域工作,而不再局限于单一任务。
为什么今天的 AI 感觉不同
这些变化并没有把统计模型变成魔法。它们所做的是让它们 广泛有用。
- 现代模型可以摄取代码库的大部分内容,并在多个文件之间进行推理。
- 它们能够以旧系统从未做到的方式,综合文档、测试和错误输出中的信息。
是的,它们仍然在预测最可能的下一个 token。不同之处在于它们以以下方式进行预测:
- 更大量的上下文,
- 更好的表示,且
- 显著提升的性能。
这就是为什么大型语言模型(LLM)常常能帮助你在几分钟内定位棘手的 bug 或草拟出合理的实现草图。曾经需要数小时手动搜索和上下文切换的任务,现在可以被加速完成。
模型擅长的领域与不足之处
优势
- 在大范围上下文中进行模式识别和综合。
- 生成代码、测试或文档的初稿。
局限
- 往往带有主观倾向,推动你采用常见模式,而这些模式可能不符合你的架构。
- 在处理复杂变更时容易迷失,尤其是当测试以意想不到的方式失败时。
在很多方面,它们的表现像是一个过于积极的实习生:真诚有帮助,出乎意料地能干,但有时也会因过度自信而出现问题。
工程师应如何对待它们
-
Start Small – 使用低风险任务,便于轻松验证输出。
- 示例:让模型为你刚写的函数生成测试。提供函数代码以及你关心的边界情况的简要描述。
- 验证测试是否真的覆盖了你的需求,还是仅仅看起来合理。
-
Craft Precise Prompts
- 模糊:“make this better” → 结果模糊。
- 具体:“refactor this function to handle the case where the user list is empty” → 更好的结果。
- 记住:模型只能依据你提供的上下文工作,所以要明确说明约束、需求或关注点。
-
Watch for Drift – 如果在对复杂改动进行迭代时,建议开始偏离你的需求,这就是信号。
- 提供更多上下文,将问题拆分为更小的步骤,或自行处理该部分。
-
Experiment Across Task Types
- Works well: 生成样板代码、起草文档、解释不熟悉的代码、建议测试用例。
- Hit‑or‑miss: 进行系统架构设计、做细致的权衡决策、调试微妙的并发问题。
-
Treat Output as Drafts, Not Final Solutions
- 即使输出看起来正确,也要仔细阅读。
- 模型即使错误也会表现得很自信;它可能生成能够编译但行为错误的代码,或使用不适合你代码库的模式。
-
Integrate Thoughtfully into Your Workflow
- 了解模型擅长的领域和薄弱环节,并相应调整你的流程,以发挥其优势。
轮到你了
如果你正在尝试这些工具,我很想了解你的发现。
- 有哪些方法有效?
- 有哪些方法无效?
- 哪些地方让你感到惊讶?
分享你的经验,让我们一起学习。