Lex's Blog

AI Code

AI 辅助编程

本文主要分享当下节点(2025-01)我对 AI 编程在实际工程中的一些尝试和想法

主要分为以下几部分

  1. 简单过下大模型的发展和原理,了解提示词的重要性
  2. AI 编程工具的发展,模型自身能力的重要性
  3. 简单过下 Cline 的源码,再次展示提示词的重要性(提示词工程)

声明:文章中很多数据是由 AI 生成而来,只为了便于理解概念,不保证数据的准确性

重要的技术突破

2022 年 11 月 ChatGPT 3.5 发布,对普通大众而言,AI 这个概念从影视作品,直接变成了每个人都可以实际使用的工具

AI 的能力好像突然从 1 涨到了 100,是什么引起了这种变化?

Q: 从 Transformer 发布之后,大模型都经历哪些关键的技术突破点和里程碑

A: 自从Transformer架构于2017年发布以来,大型语言模型(LLMs)经历了多个关键的技术突破和里程碑。以下是一些重要的发展阶段:

1.  **Transformer 架构的引入**

- **2017年**:Google提出了Transformer模型,利用自注意力机制解决了 RNN 在并行处理上的限制,使得模型能够更有效地处理大规模数据集[5][6]。

2.  **预训练模型的兴起**

- **2018年**:BERT(Bidirectional Encoder Representations from Transformers)的发布标志着预训练语言模型时代的到来。BERT通过在大量文本上预训练,然后在特定任务上微调,显著提升了多项NLP任务的性能[2][4]。
- **2019年**:OpenAI推出GPT-2,进一步推动了生成式预训练模型的发展,参数量达到15亿,展示了强大的文本生成能力[1][3]。

3.  **大型模型的发展**

- **2020年**:GPT-3发布,参数量达到1750亿,成为当时最大的语言模型,展现出卓越的生成和理解能力[1][2]。
- **2021年**:Meta发布LLaMA,进一步推动开源大型语言模型的发展,使得更多研究者能够使用和改进这些技术[7][8]。

4.  **多模态能力的探索**

- **2022年**:随着DALL-E和CLIP等模型的推出,多模态学习开始兴起,这些模型能够处理文本和图像数据,扩展了AI的应用范围[1][4]。

5.  **生成式AI的元年**

- **2023年**:ChatGPT及其后续版本引起全球关注,展示了大语言模型在对话生成、知识检索等方面的强大能力。此时,模型参数量已达到万亿级别,算法优化使得模型能够处理更复杂的任务[2][4]。

6.  **技术与伦理的双重挑战**

- 随着LLMs的发展,对隐私、偏见和能耗等问题的关注也日益增加。研究者们正在探索如何在保证性能的同时,提高模型的道德标准和可持续性[6][9]。

这些里程碑不仅展示了技术的进步,还反映了AI在自然语言处理领域的广泛应用潜力。随着研究不断深入,未来的大型语言模型将更智能、更个性化,并能更好地理解上下文和人类需求。

Citations:
[1] https://www.hangyan.co/charts/3127711516401337641
[2] https://blog.csdn.net/a_pjx_z/article/details/139183665
[3] https://www.processon.com/view/6755412923bb5e5f8d1c4a15
[4] https://www.rongpm.com/column/llms-history-1sbd-ai.html
[5] https://zh.wikipedia.org/wiki/Transformer%E6%A8%A1%E5%9E%8B
[6] https://www.cnblogs.com/edisonchou/p/-/llm-foundation-part2
[7] https://pdf.dfcfw.com/pdf/H3_AP202304171585498509_1.pdf
[8] https://www.51cto.com/aigc/1368.html
[9] https://www.huxiu.com/article/1590543.html

总结:

  1. 自注意力机制,使训练可以并行处理
  2. 并行处理使得训练参数和数据量开始增加:GPT-1: 1.17亿 -> GPT-2: 15亿 -> GPT-3: 1750亿 -> GPT-4: 1.76万亿
  3. 量变引起质变,发生了「涌现」现象
GPT涌现(Emergence)是指大型语言模型在达到一定规模后,展现出一些在较小模型中并不存在的新能力。这一现象引发了研究者们的广泛关注,尤其是在理解和利用这些能力方面。

## 涌现的定义

涌现是一个复杂系统的特性,指的是系统整体表现出的行为与其组成部分简单相加的行为有显著不同。在语言模型中,当模型的参数量达到某个临界点时,它们可能会展现出新的能力,例如更复杂的推理、运算能力或对话生成能力,这些能力在较小的模型中无法实现[1][2][3]。

## 关键特点

- **非线性增长**:研究表明,语言模型的表现并不是随着参数数量的增加而线性提升,而是在达到特定规模后,会突然涌现出新的能力。例如,GPT-3展示了执行两位数乘法等任务的能力,即使没有专门训练过这类任务[2][4]。
- **Zero-shot和Few-shot学习**:涌现能力使得大型语言模型能够在未见过或很少见过的问题上进行有效解答,这种能力被称为零样本学习(Zero-shot learning)和少样本学习(Few-shot learning)[1]。

## 研究与应用

研究者们正在努力理解涌现现象的机制,以便更好地利用这些新能力,同时也关注其潜在风险,例如偏见和不准确性[1][4]。随着模型规模的不断扩大,涌现行为的探索和记录成为了当前AI研究的重要方向之一。

总之,GPT涌现是大型语言模型发展的一个重要特征,揭示了AI在处理复杂任务时的潜力与挑战。

Citations:
[1] https://wallstreetcn.com/articles/3685167
[2] https://swarma.org/?p=39717
[3] https://www.woshipm.com/ai/5841389.html
[4] https://m.36kr.com/p/2210585582301824

GPT 是怎么回答问题的?

它真的像人一样「理解」输入和输出了吗?

当然不理解,一切都是概率统计

  • 模型训练过程中,通过海量数据对文本在多维向量空间中进行归类,相似概念的文本会靠拢归类
  • 在输出时不停的在多维向量空间中搜索概率最大的文本进行输出

在大模型的预训练过程中,相关词在向量空间中靠近的机制主要依赖于以下几个关键技术和方法:

  1. 嵌入向量(Word Embeddings)
  • 词向量表示:在预训练阶段,每个词被映射到一个高维向量空间中。通过使用词嵌入技术(如 Word2Vec、GloVe 等),相似意义的词会被映射到相近的向量位置。这是因为这些模型通过分析词与词之间的上下文关系来学习它们的语义特征。
  1. 自监督学习
  • 掩码语言模型(Masked Language Modeling, MLM):例如,BERT 等模型在训练时会随机遮盖输入句子中的一些词,并要求模型预测这些被遮盖的词。通过这种方式,模型学习到不同词之间的关系,从而使得语义相近的词在向量空间中靠近。
  • 下一个句子预测:这种任务要求模型判断两个句子是否相连,进一步增强了对上下文和语义关系的理解。
  1. 大规模数据预训练
  • 海量文本数据:大模型通过在大量文本数据上进行预训练,捕捉到丰富的语言现象和上下文信息。这种学习过程不仅涉及单词级别,还包括短语、成语等多层面的语义知识,使得相似意义的词能够在向量空间中靠近。
  1. 向量空间几何
  • 稠密性与高维度:大语言模型生成的词向量通常具有较高的维度(如 768 维或 1024 维),这使得每个词在高维空间中有独特且密集的表示。相似意义的词在几何上会形成较小的距离,而语义差异大的词则相距较远。
  • 余弦相似度:在高维空间中,可以使用余弦相似度等方法来衡量不同向量之间的相似性,这对于理解和捕捉语言中的细微差别至关重要。
  1. 微调与知识注入
  • 微调过程:预训练完成后,模型可以针对特定任务进行微调。在这个过程中,模型会进一步调整其参数,使得相关任务中的相关词更加接近。
  • 知识库增强:一些模型还会结合外部知识库,通过结构化信息进一步优化其嵌入,使得相关概念在向量空间中靠得更近。

示例

假设我们有以下几个相关词:

初始向量
[1, 12.2, ..., 22.3]
动物[10, 78.25, ..., 111.35]
宠物[56.12, 90.22, ..., 889.32]

在经过上述预训练和优化过程后,这些词可能在向量空间中的位置如下:

向量表示
[0.1, 0.2, ..., 0.3]
动物[0.1, 0.25, ..., 0.35]
宠物[0.12, 0.22, ..., 0.32]

可以看出," 猫 "、" 动物 " 和 " 宠物 " 在向量空间中彼此接近,反映了它们之间的语义关系。

通过以上机制,大语言模型能够有效地将相关词在向量空间中靠近,从而提升其在各种自然语言处理任务中的表现。

Citations:
[1] https://blog.csdn.net/xw555666/article/details/138338252
[2] https://blog.csdn.net/chaishen10000/article/details/132904203
[3] https://cloud.baidu.com/article/3332456
[4] https://www.chenk.top/%E5%A4%9A%E6%A8%A1%E6%80%81%E5%A4%A7%E6%A8%A1%E5%9E%8B%E5%8F%8A%E4%B8%8B%E6%B8%B8%E4%BB%BB%E5%8A%A1%E7%A0%94%E7%A9%B6/
[5] https://developer.volcengine.com/articles/7386867366527041587


以下是一个示例,展示了 GPT 模型如何根据输入预测输出的过程,包括向量空间的技术细节:

示例输入

假设我们有以下输入:

输入: " 人工智能的未来将 "

预测过程

  1. Token 化:
    输入句子会被分解为 token(词元)。例如:

    • 输入 token: [" 人工 ", " 智能 ", " 的 ", " 未来 ", " 将 "]
  2. 嵌入向量:
    每个 token 被映射到一个高维向量空间中,形成嵌入向量。假设每个 token 的嵌入维度为 768,得到如下向量:

    $$ \text{embedding} = \begin{bmatrix} \text{e}_1 \ \text{e}_2 \ \text{e}_3 \ \text{e}_4 \ \text{e}_5 \ \text{e}_6 \ \text{e}_7 \end{bmatrix}

    \begin{bmatrix} 0.1 & 0.2 & ... & 0.3 \ 0.4 & 0.5 & ... & 0.6 \ ... & ... & ... & ... \ 0.7 & 0.8 & ... & 0.9 \end{bmatrix} $$

  3. 位置编码:
    为了保留 token 在序列中的位置信息,位置编码(Positional Encoding)会与嵌入向量相加。位置编码通常使用正弦和余弦函数生成,确保不同位置的向量具有独特性。

  4. 自注意力机制:
    在 Transformer 中,自注意力机制用于计算每个 token 与其他 token 之间的关系。通过计算注意力权重,模型可以聚焦于与当前 token 最相关的上下文信息。例如,对于“未来”,模型可能会更关注“人工智能”。

  5. 输出预测:
    模型会生成一个包含所有可能下一个 token 的概率分布。例如,假设模型输出如下概率分布:

    • 输出概率:
      • [" 将 ", 0.2]
      • [" 会 ", 0.5]
      • [" 变得 ", 0.3]
  6. 选择下一个 token:
    根据概率分布,模型选择概率最高的 token 作为下一个输出。在这个例子中," 会 " 的概率最高(0.5),因此选择 " 会 "。

  7. 迭代生成:
    将 " 会 " 添加到输入序列中,然后继续预测下一个 token。新的输入序列为:

    • 新输入: " 人工智能的未来将会 "
  8. 重复步骤: 重复上述步骤,直到达到预定的输出长度或遇到结束符。

最终输出

经过多次迭代后,模型可能生成以下完整句子:

输出: " 人工智能的未来将会是更加智能和人性化的技术。"

向量空间技术细节

  • 向量表示:每个 token 在高维空间中的表示使得模型能够捕捉到语义上的相似性。例如,“人工智能”和“科技”可能在向量空间中相对接近。
  • 距离度量:在高维空间中,可以使用余弦相似度等方法来衡量不同向量之间的相似性,这对于理解上下文非常重要。

通过这个示例,可以看到 GPT 通过逐步接收输入并根据上下文生成下一个 token 的概率分布,从而实现了文本生成
虽然模型生成的文本看起来连贯且有逻辑,但它并不具备真正的理解能力,而是基于统计模式和训练数据生成响应。

Citations:
[1] https://blog.csdn.net/chenjianghua_5/article/details/143591839
[2] https://www.milliman.com/en/insight/concepts-building-customized-private-gpts-cn
[3] https://www.showapi.com/news/article/672b23ab4ddd79f11a006ad5
[4] https://www.cnblogs.com/LittleHann/p/17303550.html
[5] https://www.cnblogs.com/justLittleStar/p/17925108.html
[6] https://baoyu.io/translations/transcript/attention-in-transformers
[7] https://www.aizws.net/news/detail/1812
[8] https://docs.feishu.cn/v/wiki/GI85wfUaBiUUPtkVpeic66EWnsc/ak

模型输出的质量

由上可以知道 LLM 的输出原理就是根据输入的文本进行成语接龙,逐步进行概率分析,生成出下一个最可能的文本

输入的质量直接决定了输出的质量

这也是为什么我们如果简单的与模型对话,它的输出结果往往是不尽人意的

而且随着模型的训练量变大,模型学习到的东西越多,输出的多样性也会增加。在没有提示词的情况下,它的回答也会变的越来越不可预测

提高模型的输出质量

一、模型微调

直接将相关信息(比如整个项目的代码)丢给模型进行训练,让模型从内部理解我们简单话语背后隐藏的上下文

但是微调一个是费用太高了,其次微调也不是把东西喂给模型就完事了,是需要有高质量的训练集和不停的尝试调整的

Q: 使用 chatGPT 的微调 API,微调一个项目大概需要花费多少钱?

A: 使用ChatGPT的微调API进行项目微调的费用主要由以下几个部分构成:

## 微调费用

1. **API使用费用**

   - 微调的费用加上使用微调模型的费用通常会比原本的GPT-3.5模型成本增加6到7倍[1]。具体费用取决于所选择的基础模型。例如,微调Davinci模型的训练费用为每1000个tokens约为$0.0300,而使用时则为$0.1200/1K tokens[8]。

2. **人力成本**
   - 微调过程通常需要团队协作,包括模型团队、产品团队和业务团队,涉及的人员如资深客服和产品经理等,这部分人力成本可能会根据项目规模有所不同[1]。

## 估算总成本

- **基础计算**

  - 假设你微调一个使用Davinci模型的项目,若训练数据和请求总共消耗了100,000个tokens,那么:
    - 微调费用 = $$100,000 \times 0.0300 = 3,000$$ 美元
    - 使用费用 = $$100,000 \times 0.1200 = 12,000$$ 美元
    - 总成本 = 微调费用 + 使用费用 = $$3,000 + 12,000 = 15,000$$ 美元

- **增加倍数**
  - 如果考虑到微调成本增加6到7倍,最终成本可能会在90,000到105,000美元之间,具体取决于项目需求和实际情况。

## 总结

因此,微调一个项目的总费用可能从几千美元到十几万美元不等,具体取决于所选模型、tokens消耗量以及人力资源投入等因素。

Citations:
[1] https://www.explainthis.io/zh-hans/ai/fine-tuning-gpt
[2] https://juejin.cn/post/7268105250455404555
[3] https://developer.volcengine.com/articles/7387287027072368703
[4] https://apifox.com/blog/2-steps-calculate-calling-chatgpt-api-cost/
[5] https://github.com/Logistic98/chatgpt-fine-tuning
[6] https://cloud.baidu.com/article/1191605
[7] https://docs.feishu.cn/v/wiki/ZyQZwPU0vidzt8kKFmuc8OB2nxh/al
[8] https://www.cnblogs.com/taoshihan/p/17108345.html

二、提示词

在输入中明确提示模型,我们想要做的事情以及示例,就可以极大的提高输出的质量

但是写提示词是一件很麻烦的事情

对于那些有明显规律/规则,可以长期受益的场景,当然值得花大量时间调整提示词来达到预期

  • 根据后端技术方案生成 API 相关代码(API 请求、TS 类型、MOCK 数据等等
  • 根据埋点文档生成埋点代码(大量简单的重复工作
  • 根据设计稿生成代码(重点取决于模型的多模态能力,或者像 v0 那样直接接入 figma)
  • ...

面向 AI 编程:比如说某些模块,业务上会「频繁但简单」的变化。那我们就可以把代码变的(重构)更加的有规律(模板化/配置化等),进而把规律告诉 AI 帮助我们进行代码开发

但是对于很多业务需求,往往不能简单的写出高质量的提示词,且即使写好了提示词,也没有下一次使用的机会

也出现了多数人的吐槽「有写提示词的时间,我自己都写完了」

那有没有可能不输入提示词,也能让模型的输出符合我们预期呢?

RAG(Retrieval-Augmented Generation)

可以把 RAG 看作是一个高级的搜索功能(具备模型的理解能力)

从上面可以知道,模型通过输入生成输出,是通过向量计算的方式进行的

RAG 的核心思想是我们将项目的代码进行向量化并存储起来(向量数据库),之后每次像大模型提问前

我们先把问题转换为向量在向量数据库中搜索相关的内容,然后再将问题和找到的内容一起发送给大模型

进而使得我们可以在不主动添加提示词和上下文的情况下,也可以让模型获取到上下文信息

其工作流程通常包括以下几个步骤:

  1. 知识准备
  • 数据收集与预处理:首先,收集相关知识文档并将其转换为文本格式,进行分词、去除停用词等预处理,以便后续检索和生成。
  1. 嵌入与索引
  • 文本嵌入:使用嵌入模型(如 BERT、GLM 等)将文本转换为向量表示。这些向量会存储在向量数据库中,以便后续快速检索。
  • 向量索引:将所有文本块的向量化内容存储在一个高效的索引中,便于进行相似度计算。
  1. 查询检索
  • 用户查询处理:当用户提出查询时,首先将查询转换为向量形式。
  • 相似度检索:利用向量搜索技术(如 FAISS、Milvus 等)从数据库中检索与查询向量最相似的文档或段落。
  1. 提示增强
  • 构建增强提示:结合检索到的信息与用户查询,构建一个增强提示模板,以提供给生成模型。
  1. 生成回答
  • 文本生成:利用大语言模型(如 GPT、Transformer 等)根据增强提示生成最终回答。生成过程会综合考虑上下文信息与检索结果,从而输出更准确和自然的文本。
  1. 后处理
  • 结果优化:对生成的文本进行后处理,例如去除重复内容、修正语法错误等,以提高输出质量。

但 RAG 也有它的问题,比如

  • 可能搜索出大量的相关内容,进而导致模型对话上下文太大
  • 搜索结果依赖于向量化时选择的模型能力,结果可能并不是我们想要的
  • 只能根据我们的问题文本进行相关度检索,还是无法「理解」问题本身背后的含义

但不管怎么说,RAG 的确可以使模型的输出质量有所提高

比如 cursor 就会对我们的项目代码进行 RAG 处理,当我们使用 @codebase 时,它就会对整个代码库进行嵌入搜索,进而提升对话质量

总而言之,目前提升模型输出质量最靠谱的方式仍然是手写提示词

所以对于某个场景下是否要 AI 辅助编程,提示词所占的工作量是一个重点要考虑的问题


使用 AI 时,我们的付出:

  • 金钱:模型、工具的使用
  • 时间:编写、调整提示词
  • 精力:理解、核对 AI 的输出结果
  • ...

回报:

  • 代码

简单的提示词大纲

  1. 背景(上下文)描述
  2. 要做的事情
  3. 额外的要求
  4. 输入/输出示例(很重要,直接影响输出结果)

AI 编程工具的发展

  1. web:chatGPT/v0/bolt..
  • 形式:网页,手动输入上下文
  • 输入:将提示词、上下文文件复制粘贴到网页中
  • 输出:从网页回复中复制粘贴
  • 限制:上下文长度
  • 输入改进:上传文件、知识库(Library)

用起来很麻烦,且早期大模型编码能力也不好,所以多数场景帮助有限

这也是大家都会经历的心理历程,刚开始觉得 AI 好像很牛,但实际用下来之后发现其实也就那样,帮不上多少忙

  1. auto complete: Copilot/codeium/supermaven/tabnine...
  • 形式:编辑器插件,自动读取上下文
  • 输入:自动读取当前打开的文件、tab,配合插件预置的提示词
  • 输出:编辑器的虚拟文本
  • 限制:无法「方便的」自定义提示词、上下文,无法多文件操作、以及更多工具的使用

首先,可以通过注释之类的方式,对 copilot 进行提示词补充,但还是有些问题:

  1. 早期模型能力不行,写了提示词,也不见得能生成多好的代码。

这就有了一个普遍的吐槽:「有写提示的时间,我自己都写完了」

  1. 真正开发时,通常会涉及到多个文件、甚至终端命令的执行。编辑器虚拟文本的交互,太受限了

我对 copilot 的态度是:当它不存在,正常写自己的代码,能提示正确就赚,提示错误也不亏

  1. Agent: copilot edit/cline / cursor/windsurf
  • 形式:编辑器插件/独立编辑器,在编辑器中对话形式
  • 输入:自动读取当前打开的文件,自定义加入提示词、文件等
  • 输出:使用大量工具,直接进行文件操作(增删改),可以终端命令执行、操作浏览器等等

整个交互体验已经很完善了,剩下就是一些细节的打磨(diff/缓存/codebase)

但光有交互,没有模型的能力,还是玩具

模型的能力

Q: cursor 是什么时候发布的

A: Cursor 是由 Anysphere 公司推出的 AI 代码编辑器,正式发布于2023 年 1 月。该工具集成了 OpenAI 的 GPT 技术,旨在提升编程效率,支持多种编程语言,并提供代码生成、编辑、Bug 修复等智能功能

Q: cursor 是什么时候火起来的

A: Cursor 在 2024 年末开始迅速走红,特别是在 12 月时引起了广泛关注。其受欢迎程度部分归功于知名人士如 Andrej Karpathy 的推荐,他称赞 Cursor 在编程效率上的表现,认为其体验已超过 GitHub Copilot

Q: cursor 为什么发布近两年后才火起来?

A: Cursor 在 2023 年发布后,最初并未立即引起广泛关注,主要原因包括其功能尚处于起步阶段和市场竞争激烈。

尽管 Cursor 具备 AI 编程助手的潜力,但在发布初期,其 AI 编程功能主要限于单一文件的代码生成和自动补全,这使得其吸引力相对有限 [1][2].

随着时间推移,Cursor 经历了多次重大版本更新和功能迭代,特别是在 2024 年,推出了 3.0 版本,引入了更强大的 Claude 模型,大幅提升了响应速度和整体性能

这些更新使得 Cursor 的功能逐渐成熟,包括智能代码提示、错误检测和多文件操作等,使其在开发者中逐渐获得认可 [2][4]。

Q: Claude 3.5 什么时候发布的?

A: Claude 3.5 系列的首个模型,Claude 3.5 Sonnet,于2024 年 6 月 21 日正式发布。此后,Claude 3.5 Haiku 在2024 年 10 月 22 日推出,进一步增强了该系列的功能和性能 [1][4].


不光 cursor,你会发现现在 copilot edit / windsurf 默认用的也是 claude 3.5 sonnet

甚至 avante.nvim(类似 nvim 中的 cline ) 在 README 中说:

Important

由于其他模型性能较差,avante.nvim 只推荐使用 claude-3.5-sonnet 模型。所有功能只能保证在 claude-3.5-sonnet 模型上正常工作。
我们不接受更改代码或提示以适应其他型号。否则,将会大大增加我们的维护成本。希望大家能够理解。谢谢你!

提示词工程 - Cline

Cline/Cursor 是如何实现的呢?从上文中我们知道其背后仍然使用的是大模型,那这些工具在大模型之上又做了哪些事情呢?

AI Agent

AI Agent(人工智能代理)是一种能够自主感知环境、进行决策和执行动作的智能实体。与传统人工智能不同,AI Agent 具备独立思考的能力,能够在接收到目标或任务后,通过规划和调用工具逐步完成复杂任务,而无需人类的逐步指示

工作原理

AI Agent 的工作流程通常包括以下几个关键环节:

  1. 感知(Perception):通过传感器或其他输入设备收集外部信息。
  2. 信息处理(Reasoning):利用内置的知识库和算法处理感知到的信息,进行分析和推理。
  3. 决策(Decision-making):基于处理结果制定行动计划。
  4. 行动(Action):执行决策,完成具体任务,并根据反馈调整未来行为

Cline

Cline System Prompt


问题:代码上下文

觉得有帮助?给个 Star 支持一下吧!

Star on GitHub

On this page