Vibe Coding 是最近两年在 AI 应用开发领域频繁出现的一个词。它描述的是一种以自然语言为核心输入、以大模型为执行引擎的编程方式:开发者把需求、边界条件和验收标准写清楚,模型负责生成代码、修改代码甚至解释报错。吴恩达和 DeepLearning.AI 围绕 Vibe Coding 推出的系列课程,正好把大模型入门到进阶这条路上的零散知识点整理成了一条可以照着走的学习路径。
课程是否真的“全网公认最好”,这里不做过多的榜单式评价,但有一点是确定的:如果你刚开始接触大模型应用开发,又不想一上来就陷入深度学习原理、分布式训练、RAG、Agent 这些庞杂话题,这套课程提供了一条更贴近工程实践的顺序。下面会以这套课程为主线,讲清楚 Vibe Coding 到底在解决什么问题、入门阶段需要准备什么环境、一个最小实践案例应该怎么做,以及进阶到 Agent 和本地部署时容易踩到哪些坑。
1. 先理解 Vibe Coding:从自然语言到可运行代码的协作方式
1.1 Vibe Coding 到底是什么
Vibe Coding 的核心不是“随便让 AI 写代码”,而是一种“意图驱动”的开发方式。传统编程中,人类要把业务逻辑翻译成精确的语法、类型、函数调用和异常处理;Vibe Coding 中,这部分工作被拆成了两层:人负责描述意图和校验结果,大模型负责把意图转换成代码。
技术定义上,Vibe Coding 是一种相对新的编码范式,它依赖大模型对自然语言和代码的理解能力,通过对话式迭代生成或修改程序。它不等同于“自动生成完整项目”,而更像是一个人机协作的代码生产方式。
容易误解的地方有两个。第一,Vibe Coding 不等于“不用懂编程”,如果完全读不懂生成代码,后续几乎无法判断模型是否在胡说。第二,Vibe Coding 不等于“一次生成全部正确”,它本质上是一个快速试错循环:写提示词、看输出、运行、发现错误、继续修改提示词。
1.2 与提示词工程、传统编程的关系
提示词工程研究的是如何设计输入文本,让模型稳定输出期望结果。Vibe Coding 可以看成提示词工程在代码生成领域的落地场景,但范围更宽:它不只关心一次生成的文本质量,更关心生成结果能不能被运行、能不能被测试、能不能被版本管理。
传统编程中的调试、单元测试、代码审查和重构,在 Vibe Coding 里并没有消失,只是位置发生了移动。开发者仍然需要看懂报错,需要决定哪些模块应该拆开,需要判断生成的代码是否满足性能要求。区别是,过去大部分代码由人手写,现在很多样板代码、测试代码、数据清洗代码可以由模型快速产出。
这里有一个比较实用的判断标准:如果一段代码是重复性、模板化的,比如解析 CSV、写 SQL、做列表转换、配置 Dockerfile,交给模型生成通常能节省时间;如果一段代码涉及复杂的业务规则、安全边界和难以表述的隐性约束,就不能直接让模型自由发挥,而是要把约束一条一条写进提示词里。
1.3 为什么用吴恩达和 DeepLearning.AI 的课程做入口
吴恩达在机器学习和深度学习领域的课程非常多,很多人最早是从《Machine Learning》和《Deep Learning Specialization》开始接触的。DeepLearning.AI 近年来的课程方向更偏向大模型应用,Vibe Coding 相关教程正是这一类。
选择这套课程作为入口,优势在于课程结构通常比较完整,从大模型基础概念、提示词写法到 Agent 应用都有安排,并且很多章节会带配套 Notebook 或代码示例。新手可以先在浏览器里跑通示例,再回头理解代码细节,这种“先看到结果,再学习原理”的方式比只看文档更容易坚持。
需要注意,课程作者和机构会持续更新内容,课程目录、模型版本和平台功能都可能与早期截图不同。学习时不要纠结于某个版本号,而要把注意力放在两个地方:第一,每一课解决的痛点是什么;第二,课件里的代码在去除无关细节之后,剩下的核心结构是什么。
2. 从大模型基础到进阶应用:一条可执行的学习路线
2.1 第一阶段:把大模型的基本概念先拉齐
开始动手写提示词之前,至少要把几个核心概念对齐。大模型本质上是根据给定文本预测下一个 Token 的概率模型,Token 是文本切分后的基本单位,可以是一个词的一部分、一个完整单词或一个标点。上下文窗口决定模型一次能“看到”的文本量,会直接影响你能给模型多少背景资料。温度参数控制输出随机性,温度越高回答越发散,代码生成场景通常使用较低的温度。
下面这张表可以用来做快速对照。
| 概念 | 含义 | 常见影响 |
|---|---|---|
| Token | 文本切分后的基本单位 | 影响输入输出长度和计费 |
| 上下文窗口 | 模型一次能处理的 Token 数上限 | 超过后会出现截断或需要做摘要 |
| 温度 | 采样随机性 | 代码生成通常设为 0 到 0.3 |
| System Prompt | 系统级指令 | 定义角色、约束和回答格式 |
| User Prompt | 用户输入 | 描述本次任务的具体要求 |
学习这个阶段时,不要只看概念,可以打开一个模型对话页面,输入一个简单的代码生成任务,然后调整提示词里的角色设定和输出格式要求,观察结果变化。这个直观体验比背概念图表有用得多。
2.2 第二阶段:提示词工程与结构化输出
提示词工程的核心是“把模糊需求变成模型能理解、能执行的指令”。一个合格的代码生成提示词通常包含四个部分:任务目标、输入输出格式、约束条件、错误处理要求。
例如:
请写一个 Python 函数,输入是一个列表,输出是去重后的列表,保持元素原始顺序。 要求不能使用 set 进行去重,因为需要保留顺序。 请包含类型注解和简单的 doctest。这个提示词里,任务目标、输出要求、约束和验证方式都写清楚了,模型生成的代码会比只写“帮我写个去重函数”稳定得多。
结构化输出是另一个重点。很多应用需要模型返回 JSON,然后在程序里继续处理。为了避免模型输出多余文字,建议在提示词中明确“只返回 JSON,不要添加任何解释”,并在代码层面对 JSON 解析做异常处理。如果模型仍然不稳定,可以给一个 few-shot 示例,或者使用支持 JSON Mode 的接口参数。
2.3 第三阶段:从单次生成到 Agent 与工具调用
入门阶段最常见的疑问是:大模型明明能写代码,为什么不能自己去执行代码、读取文件、调用 API?原因是大模型本身只是概率模型,输入输出都是文本,没有主动访问外部世界的能力。Agent 模式把大模型和工具调用结合起来,让模型在需要时生成“调用某个工具”的指令,程序负责真正执行,再把结果送回模型继续推理。
这个阶段是学习路线中性价比最高的一部分。理解 Function Calling 的原理后,就能明白为什么一个“查天气的助手”不能只靠提示词完成,需要天气 API 配合。DeepLearning.AI 的相关课程通常会在这个位置安排 Agent 的基础实验,建议把示例里的工具函数画成一张输入输出表,再自己新增一个工具,比如查询数据库、读取本地文件,体会“工具扩展”是怎么发生的。
2.4 第四阶段:本地部署、评估与工程化
从入门到进阶,很多人会卡在“在线 API 很灵活,但生产环境不能这么简单”这一关。本地部署大模型的意义不只是省 API 费用,更是为了数据隐私、离线环境和定制优化。
常见的本地部署路径是先装一个推理框架,然后下载开源模型权重并启动服务。以 Ollama 为例,安装完成后只需要执行ollama pull qwen2.5:7b这类命令,就可以把模型拉下来,再用ollama serve启动一个兼容 OpenAI 接口的本地服务。实际模型名要以官方仓库为准,这里只是说明流程。
工程化层面至少还要关注:模型评估集怎么准备、请求日志怎么记录、结果延迟和成本怎么统计、模型输出被错误使用时的降级方案是什么。这些内容在很多课程里不会展开,但在真实项目里是决定能否上线的关键。
2.5 课件代码应该怎么用,而不是只下载
课件代码是这类课程价值最高的部分,但很多人的使用方式只是“下载下来,从上到下运行一遍,看到输出就关掉”。这样做的问题在于,一旦换一个数据集、换一个模型,或者把代码从 Notebook 迁移到后端服务,可能立刻就不会写了。
更推荐的做法是:先不看答案,只看课程的作业要求,自己写一版;写完后再对照课件代码,记录三处差异,包括别人为什么这样组织函数、为什么这样处理边界条件、为什么这样解析模型返回值。然后把同一段逻辑从 Notebook 里抽出来,改成一个命令行工具或一个 HTTP 接口,才算真正学会了。
3. 环境准备:用最小成本搭建一个能跑的实验环境
3.1 先确认你需要的三样东西:Python、Git、API Key
学习 Vibe Coding 类课程,常见的软件环境是 Python、Git 和一个可用的模型 API Key。Python 用于运行课程里的 Notebook 和脚本,Git 用于保存练习代码并查看每次修改的差异,API Key 用于调用大模型接口。
如果你暂时不想申请 API Key,也可以使用本地开源模型,但推理效果和稳定性可能不如云端商用模型。实际选择取决于你的目的:只是想跑通示例,本地模型够用;想验证 Agent、Function Calling 这类能力,建议使用支持工具调用的云端 API。
下面的表可以当作参考:
| 依赖 | 最低建议 | 用途 | 常见注意点 |
|---|---|---|---|
| Python | 3.9 或更高 | 运行代码、Notebook | 不同项目建议用虚拟环境隔离 |
| Git | 2.x | 保存代码、查看 diff | 初始化后先提交一版原始代码 |
| API Key | 按平台申请 | 调用模型接口 | 密钥要放在环境变量,不要提交到仓库 |
| Notebook | Jupyter 或 VS Code | 交互式实验 | 运行顺序错了会导致变量不一致 |
3.2 选择在线环境还是本地环境
课程平台通常会提供浏览器端 Notebook,适合第一遍跟学:不需要安装任何东西,打开网页就能跑,出现环境问题概率低。本地环境则适合之后做自己的实验,因为可扩展性更强,可以安装自己的依赖、连接私有数据、部署成服务。
对于零基础用户,建议第一遍用在线环境,第二遍再在本地把相同代码跑一遍。这样既能快速建立信心,也能尽早暴露本地环境差异。
3.3 安装依赖:Notebook 与本地命令行两种方式
在本地创建虚拟环境时,推荐使用以下命令:
python -m venv .venv source .venv/bin/activate # Windows 使用的命令是 .venv\Scripts\activate pip install --upgrade pip pip install openai python-dotenv jupyter.venv是虚拟环境目录,用它隔离项目依赖,避免和系统 Python 环境互相污染。python-dotenv用来读取.env文件,方便管理 API Key。
创建.env文件,内容模板如下:
OPENAI_API_KEY=你的密钥 # 如果使用本地 Ollama,可以设置自定义模型名 LOCAL_MODEL=qwen2.5:7b写代码时,通过load_dotenv()加载环境变量:
import os from dotenv import load_dotenv load_dotenv() api_key = os.getenv("OPENAI_API_KEY")如果使用本地 Ollama,安装并拉取模型后,服务一般默认监听http://localhost:11434,然后通过 OpenAI SDK 的base_url参数指向本地地址,具体接口细节以 Ollama 官方文档为准。
3.4 环境检查清单
在开始跑课程代码前,可以按下面这个清单检查一遍:
- Python 版本满足要求,
python --version能看到 3.9 或更高。 - 虚拟环境已激活,命令行提示符前面出现
.venv。 - 已安装 openai、python-dotenv、jupyter 等依赖,
pip list中能看到。 - API Key 已配置到环境变量,且没有被提交到 Git 仓库。
- 如果使用在线 Notebook,确认已经连接内核,并能正常导入依赖。
- 如果使用本地模型,确认服务已启动,并能通过本地接口完成一次最简单的对话。
环境检查是 Vibe Coding 里最枯燥但最必要的环节。很多后续报错其实都来自这一步没做完整。
4. 最小 Vibe Coding 实践:用自然语言生成一个卡片生成器
4.1 先写清楚需求,再让模型生成代码
这里用一个非常常见的数据处理需求来做例子:读取一个 CSV 文件,统计每一列的缺失值数量和缺失率,并按缺失率排序。这个需求很小,但足以体现 Vibe Coding 的完整循环。
先在对话里输入下面这段提示词:
请写一个 Python 脚本,文件名为 analyze_csv.py。 脚本接收一个命令行参数:CSV 文件路径。 程序读取 CSV 文件,统计每一列的缺失值数量和缺失率,缺失率用百分比表示,保留两位小数。 输出按缺失率从高到低排序,使用 tabulate 库以表格形式打印。 包含 main 函数,文件读取失败或参数缺失时要给出友好提示。这个提示词的关键点在于:给出了文件名、参数、输出格式、排序方式、依赖库、错误处理要求。模型不需要猜测需求,生成的代码也更容易直接运行。
4.2 生成第一版代码
遵循这类提示词,通常可以得到类似下面这样的代码。实际模型输出可能有变量名差异,但整体结构会非常接近。
import sys import pandas as pd from tabulate import tabulate def analyze_missing(file_path: str) -> pd.DataFrame: df = pd.read_csv(file_path) total_rows = len(df) missing_count = df.isna().sum() missing_rate = (missing_count / total_rows * 100).round(2) result = pd.DataFrame({ "column": missing_count.index, "missing_count": missing_count.values, "missing_rate": missing_rate.values, }) return result.sort_values("missing_rate", ascending=False) def main() -> None: if len(sys.argv) != 2: print("用法: python analyze_csv.py <csv文件路径>") sys.exit(1) csv_path = sys.argv[1] try: summary = analyze_missing(csv_path) print(tabulate(summary, headers="keys", tablefmt="grid", showindex=False)) except Exception as exc: print(f"处理失败: {exc}", file=sys.stderr) sys.exit(1) if __name__ == "__main__": main()这段代码里值得关注的地方有几个。df.isna().sum()是 pandas 统计缺失值的标准方法;round(2)让缺失率更易读;tabulate负责把 DataFrame 渲染成表格;main函数负责命令行参数和异常处理。生成代码之后,不要急着信任,先运行,再检查。
4.3 保存、运行和验证
把生成的代码保存到analyze_csv.py,准备一个测试文件sample.csv:
name,age,city Alice,30, Bob,,Shanghai Carol,,运行命令:
python analyze_csv.py sample.csv预期输出大致如下:
+-------+-----------------+---------------+ | column| missing_count | missing_rate| +-------+-----------------+---------------+ | city | 1 | 33.33 | | age | 1 | 33.33 | | name | 0 | 0.00 | +-------+-----------------+---------------+这里的数据只有三行,所以缺失率只有 0 和 33.33 两种。重要的是验证两件事:程序能按缺失率从高到低输出;当路径不存在时,会打印友好提示而不是堆一长串 Traceback。
如果路径不存在,可以运行:
python analyze_csv.py not_exist.csv预期输出:
处理失败: [Errno 2] No such file or directory: 'not_exist.csv'这说明异常处理生效了。
4.4 继续用自然语言迭代:加参数、加错误处理
第一版跑通之后,可以继续用自然语言提新需求。比如:
请给 analyze_csv.py 增加一个可选的 --top 参数,只显示缺失率最高的前 N 列。 如果没有传入 --top,就显示全部列。 要求使用 argparse 代替 sys.argv 处理参数。模型会修改代码,把argparse引入,并调整传参逻辑。这个过程就是 Vibe Coding 的核心循环:给需求、生成代码、运行、提新需求、继续生成。每一次循环都在训练同一个能力:如何把模糊想法拆成可执行的、可验证的指令。
4.5 这个练习背后训练的是什么能力
这个最小案例看起来简单,但它背后其实是三条能力。
第一条是需求拆解能力。你必须能说出“我要统计缺失值,按缺失率排序,输出表格”,而不是“帮我处理一下数据”。
第二条是验证能力。模型给出的代码不能直接上线,必须通过真实数据、边界条件来验证。
第三条是迭代能力。第一版不一定完美,你要能发现不足,并把不足继续转成下一轮提示词。
这三点就是 Vibe Coding 对开发者提出真正要求的地方。
5. 从提示词到 Agent:理解工具调用与大模型应用形态
5.1 为什么单次问答不够用
前面的 CSV 统计脚本,本质上是一次性生成代码后交给 Python 执行。实际应用中,你更希望模型能够根据当前问题自己决定调用哪个工具。比如用户问“帮我查一下订单表里最近七天的数据,然后画一张柱状图”,模型如果只能生成文本,就无法真正读取数据库和生成图片。要让模型具备行动能力,就需要把大模型和应用环境通过工具连接起来。
这种连接方式最早被概括为 Agent 模式:模型循环执行“思考-调用工具-观察结果-再思考”的过程,直到完成目标或达到停止条件。Vibe Coding 课程中的 Agent 部分,通常就是围绕这个循环展开的。
5.2 工具调用的工作原理
目前的商用模型普遍支持 Function Calling,也叫工具调用。模型并不真正执行外部功能,它只是基于对话内容输出一个“我希望调用某个函数,并传入这些参数”的结构化指令,真正执行由你的程序完成。
一个典型的工具调用 JSON 指令长这样:
{ "name": "get_weather", "arguments": "{\"city\": \"上海\"}" }你的程序解析这个 JSON 后,调用真实的get_weather("上海")函数,并把返回结果作为新的消息交给模型继续推理。在这个过程中,模型不会直接访问天气服务,所有 API key、鉴权、错误处理都发生在你的代码里。
5.3 一个极简 Agent 示例
使用 OpenAI 风格 SDK 时,先定义工具:
from openai import OpenAI client = OpenAI() # 需要提前设置 OPENAI_API_KEY 环境变量 tools = [ { "type": "function", "function": { "name": "get_weather", "description": "查询指定城市的天气情况", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名,例如上海"} }, "required": ["city"] } } } ] messages = [{"role": "user", "content": "上海今天天气怎么样?"}] response = client.chat.completions.create( model="gpt-4o-mini", messages=messages, tools=tools, )调用完成后,需要检查返回内容里是否有tool_calls。如果有,就取出函数名和参数,执行本地函数,再把结果通过role: "tool"的消息追加到messages,最后再次调用模型获取最终回答。
if response.choices[0].message.tool_calls: tool_call = response.choices[0].message.tool_calls[0] city = tool_call.function.arguments weather_result = fake_get_weather(city) messages.append(response.choices[0].message) messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": weather_result, }) # 再次调用模型得到最终回复这个展示是结构性的,忽略了很多细节,比如参数解析、异常处理、多工具调用、循环上限。实际项目中,你还需要考虑工具白名单、操作审计、用户确认机制以及成本控制。
5.4 生产环境的 Agent 还需要什么
学习环境的 Agent 只要能在 Notebook 里跑通一次对话就够了,但生产环境要复杂得多。至少要解决下面几个问题:
- 工具权限:模型能调用的工具不能是无限集合,必须按场景和用户角色收窄。
- 审计日志:谁在什么时间让模型调用了什么工具,参数是什么,结果是什么,都要