Vibe Coding 最近真的很火。第一次让 AI 用自然语言生成一段能跑的代码时那种感觉确实很妙你描述需求AI 给出实现你还没来得及读完它生成的函数屏幕上已经跑出了结果。我见过不少开发者用这种方式快速搭原型、写脚本、做内部工具甚至有人把一个重复了几周的手工操作在一个周末里用 Vibe Coding 自动化掉了。但问题也恰恰出现在“跑通之后”。demo 很顺接入真实数据和真实业务后系统就开始变得不可理解。AI 生成的代码能运行却很难被解释出了问题你不知道是输入变了、模型抽风了还是下游解析逻辑错了。这种时候真正决定 Vibe Coding 是“玩具”还是“工程”的变量已经不再是代码量而是可观测性也就是 Observability。它才是把 Vibe Coding 变成 AI Engineering 的那道分水岭。1. Vibe Coding 的真正价值不是“不用写代码”很多人把 Vibe Coding 理解成“以后可以不用写代码了”。我觉得这是一个危险的方向。它真正的价值不在替代写代码而是把一个想法快速变成可运行的雏形把大量机械性、试探性的编码工作交给模型让人把精力留在“想清楚要什么”和“判断结果对不对”上。1.1 为什么 Vibe Coding 让人上瘾Vibe Coding 的体验和传统开发很不一样。传统开发是先设计、再实现、再调试每一步都要你亲自维护心智模型。Vibe Coding 则是“期望 → 生成 → 验证”模型把大部分编码工作一次性完成哪怕结果不对修正成本也远低于从零开始写。这种方式让人上瘾的核心原因是反馈极快。你说“写一个脚本把 CSV 按某个字段分组输出 Markdown 表格”几秒钟后代码就出来了跑一下结果基本符合预期。这种即时成就感会让人产生一种错觉AI 已经把这件事解决了。但这里藏着一个误区产出速度不等于理解深度。代码是 AI 生成的但你要对它负责。如果你不知道它在边界情况下会怎么处理不知道哪个分支会被走进不知道异常路径为什么这样设计那么这个代码对你来说就是一个“亮着灯的黑箱”。快速生成只能提高起点并不能替代对行为的理解。1.2 但“demo 能跑”和“系统可信”之间隔着什么“能跑”和“可信赖”之间隔着一条大多数 Vibe Coding 新手看不见的沟。demo 能跑通常只意味着 happy path 通了。输入正常、条件正常、结果正常的情况下没问题。但真实系统里80% 的复杂度来自异常路径用户输入了一个空字段上游返回了重复数据、网络超时、模型返回格式变化、依赖升级后行为改变。demo 能跑也不等于可维护。代码没有日志、没有分层、没有清晰的错误处理AI 生成时又可能把逻辑揉在一个大函数里。你让 AI 解释它自己当时的意图它说你上传代码时它就是这样的。这种状态下任何一次修复都可能引入新的连带问题。demo 能跑更不等于可复现。传统代码是确定性的同样的输入应该产生同样的输出。AI 应用不是。模型有随机性上下文窗口有截断外部工具调用顺序可能变化同一段 prompt 在不同模型版本下的行为可能完全不同。如果缺少记录你根本不知道这次结果是在什么条件产生的。所以我更愿意把“能跑”看成起点把“可信赖”定义为三件事行为可理解、变更可追溯、失败可复现。这三件事都依赖可观测性。1.3 真正缺的不是代码能力而是可解释性Vibe Coding 场景里开发者缺的往往不是写代码的能力而是对系统行为的解释能力。你问 AI“把 CSV 分组后合并成一个对象数组。” AI 写了。但为什么它选择保留这个字段为什么对空值默认取空字符串为什么递归深度只到两层这些隐含决策模型没有解释代码里也不一定看得出来。传统方式下你可以通过阅读每一行代码推导出全部行为。AI 生成方式下模型内部的推理过程我们看不穿。但有一点可以确定模型内部不可观测不代表系统行为不可观测。我们可以从行为层面观察它输入是什么输出是什么每一步耗时多久失败发生在哪个环节重试了几次模型用了哪个版本当时 token 消耗多少。把这些行为记录下来黑箱模型就可以被当成一个“行为可控的组件”来使用。这正是可观测性要补上的位置。提醒可观测性的目标不是看穿 AI 内部在想什么而是让 AI 的外部行为可以被记录、被关联、被复盘。2. 可观测性为什么是 AI Engineering 的分水岭传统软件开发已经形成了完整的可观测性体系。到了 AI 应用这里这套体系不但依然适用而且变得更重要。原因很简单系统里的不确定性变多了必须靠外部记录来弥补不可解释的内部过程。2.1 从“能运行”到“行为可理解”可观测性回答三个问题发生了什么、为什么发生、影响有多大。这三个问题在传统系统里已经很难回答在 AI 系统里更难。一个模型调用可能经历这样的链路用户请求进入服务、构造 prompt、调用模型、模型返回、解析 JSON、写入数据库、给前端返回结果。这 7 个环节里任何一个都可能出问题。如果没有日志你只能看到“最后结果不对”日志不结构化你只能靠 grep 关键字日志之间没有 trace_id你无法把一个请求的链路串起来。真正的可观测性意味着你能够随时回答“这条输出为什么是这样它经历了哪条路径消耗了什么资源失败卡在哪一个点”不管代码是手写的还是模型生成的只要系统运行在真实环境里这些问题就必须有答案。2.2 可观测性不是“多打日志”Logs / Metrics / Traces很多项目确实打了日志但依然不可观测。因为可观测性不是“多几行 print”而是三个维度互相配合。Logs日志记录离散事件比如一次请求进入、一次模型调用失败、一次重试发生。日志的价值在于定位细节但难做趋势分析。Metrics指标记录可聚合的数值比如每秒请求数、错误率、平均响应延迟、token 消耗量。指标的价值在于发现趋势但信息粒度粗。Traces追踪记录一个请求从入口到出口经过的整个链路。一次模型调用中prompt 构造、模型推理、后处理、外部工具调用每一步都可以作为 span 记录。追踪的价值在于理解跨环节的因果关系。对 AI 应用来说Traces 尤其重要因为一次生成往往跨越多层模型调用、数据库查询、缓存、工具调用、后处理、前端展示。如果只有日志没有 trace_id出了问题你只能看到各个模块自己的记录没法拼出完整路径。没有完整路径就无法判断“模型输出没问题是后处理把它弄坏了”还是“prompt 构造就有问题模型回答自然偏了”。2.3 AI 系统要多观察一层“意图”传统系统观察的是参数、请求、数据库、CPU、内存。AI 系统还要观察另外一层意图相关的输入和参数。具体来说你至少需要知道这一次调用模型的 prompt 是什么有没有被截断用了哪个模型版本温度是多少最大 token 数是多少上下文窗口占了多少请求和返回各消耗多少 token。这些数据里任何一个变化都可能让输出发生明显漂移。如果你把温度从 0.2 改到了 0.8输出不稳定你可能误以为模型能力退化。如果你近期更新了 prompt 模板模型输出明显变长没有记录 prompt 版本你就无法判断成本上涨的原因。可观测性在 AI 系统里多出来的这一层本质上是把“模型生成过程的可复现条件”记录在案。有了这层记录你才能在队友问“这次结果为什么这样”的时候拿出 trace 说你看请求长了 30%上下文被截断模型在缺少中间信息的情况下做出的判断。而不是只能说“我也不太清楚它有时候就是这样”。3. 给 Vibe Coding 加可观测性的最小闭环Vibe Coding 项目通常很小很多人听到“可观测性”会下意识觉得太重。但完整平台确实不必现在搭一个最小闭环其实很轻给请求加 trace_id把日志变成结构化输出在关键节点记录输入输出。这件事一两天就能做完却能让一个 AI 原型从“能跑”跨到“可调试”。3.1 先定义观察目标输入、行为、输出不要一上来就想“我要上日志平台”“我要接追踪系统”。先把观察目标定义清楚。对大多数 AI 项目只需要盯住三个维度观察维度要回答的问题记录内容典型用途输入这次生成是在什么条件下开始的prompt 摘要、输入长度、上下文长度、模型名称、温度、trace_id复现问题、分析成本行为中间发生了什么调用链、工具调用、重试次数、耗时、错误类型定位瓶颈、排查异常输出结果是否符合预期状态、输出长度、错误信息、token 消耗、验证结果质量评估、回归监控一个实用的判断标准如果有人问你“这个系统为什么会这样”你能否从已有的记录里拼出答案如果不能说明有个维度没覆盖到。3.2 最轻量的技术方案结构化日志 trace_id第一个最小方案不需要引入专门的可观测性平台只需要两件事。第一把日志从print改成结构化日志。结构化日志是一行 JSON而不是一串拼起来的字符串。原因很直接字符串日志只能靠人眼扫JSON 可以被查询、过滤、自动聚合。日志量大之后字符串日志就是噪音结构化日志才是可分析的数据。第二每个请求或每次任务生成一个trace_id从入口一直贯穿到出口。这样即使还没有接分布式追踪系统你也可以通过 trace_id 把一个请求的所有日志捞出来。对应到 AI 任务里可以是一次“生成文本”任务、一次“批量处理”任务也可以是一个用户会话。提醒结构化日志不等于把所有变量都打出来。可观测性的价值在于信息可检索、可关联而不是日志体积大。3.3 一段可用的落地示意下面是一段 Python 通用示例只用了标准库演示“trace_id 结构化日志 错误记录”这个最小闭环。具体项目里AI 调用 SDK 可能不同但思路是一样的。import json import logging import time import uuid # 配置为 JSON 结构日志的写法因语言和框架而异但核心是“一行一个 JSON 对象” logging.basicConfig(levellogging.INFO) logger logging.getLogger(vibe_app) def ai_process(prompt: str, context: str , model: str model-1) - str: trace_id uuid.uuid4().hex[:12] started time.time() logger.info(json.dumps({ event: ai_process.start, trace_id: trace_id, model: model, prompt_chars: len(prompt), context_chars: len(context), })) try: # 这里是 AI 模型调用具体 SDK 因项目而异 result 生成的文本 # ... 调用模型并拿到输出 ... duration_ms round((time.time() - started) * 1000, 2) logger.info(json.dumps({ event: ai_process.end, trace_id: trace_id, status: ok, output_chars: len(result), duration_ms: duration_ms, })) return result except Exception as exc: duration_ms round((time.time() - started) * 1000, 2) logger.error(json.dumps({ event: ai_process.error, trace_id: trace_id, error: type(exc).__name__, message: str(exc), duration_ms: duration_ms, })) raise在真实 AI 调用场景里还会额外记录模型参数和 token 消耗例如logger.info(json.dumps({ event: model.invoke, trace_id: trace_id, model: model_name, temperature: temperature, max_tokens: max_tokens, prompt_tokens: prompt_tokens, completion_tokens: completion_tokens, latency_ms: latency_ms, # 不要记录 prompt 的完整原文避免敏感信息进入日志 }))记录这些字段的价值是一段时间后当你发现某类请求变慢或输出变差时可以按模型版本、prompt 长度、token 消耗做一次快速分析。如果这些字段缺失你只能靠猜。3.4 第一批观察节点放哪里新手容易犯的错是打太多日志或者到处都打。更合适的做法是先在四个节点埋点。入口任务刚开始时记录输入摘要。模型调用前后记录模型名称、参数、耗时、token。异常处理所有except块里记录错误类型和 trace_id不许用except: pass。出口任务结束时记录状态和结果摘要。先保证这四条存在再考虑要不要加更多。很多 Vibe Coding 项目尤其是内部工具和自动化脚本有这个最小闭环就已经能解决绝大部分“这代码到底干了什么”的问题。4. 常见坑点很多 AI 项目 demo 完就死问题出在哪每次看到 demo 跑通后就放弃的项目我都会先怀疑一句话“我没有 log 也能跑啊为什么这些工程化这么麻烦” 这种观点忽略了系统进入长期运行后的场景。Vibe Coding 项目最容易在几个点上暴露出短板。4.1 三类典型症状第一类症状是输出不稳定。第一次跑结果很好第二次跑结果却变了。你说模型随机但说不清是什么参数导致的。没有记录温度、模型版本、上下文长度你只能抱着“它就是抽了”的态度接受它。第二类症状是任务中断后无法恢复。一个批量任务跑到一半挂了重新运行时又从最早开始重复消耗 token。因为没有 checkpoint也没有 trace你甚至不知道上次跑到第几条。第三类症状是结果不可复现。同一条 prompt在旧版本模型上生成的结果到新版本模型上完全不同。没有版本记录你就无法回溯“之前那个好结果是用什么模型生成的”。团队里换个人接手时问题更严重——他说“这个输出看起来不对”但没人能告诉他“对”的标准在哪。4.2 一条能用的排查链路当 AI 项目出问题我一般不是先去改 prompt而是按下面这个顺序排查确认行为是否发生先找 trace_id确认请求有没有真正进入系统。排查输入检查 prompt、上下文、输入长度、模型参数。很多时候不是模型变笨了是输入条件和上次不同。排查模型调用层模型调用是否成功、超时、被限流返回的 JSON 是否合法latency 和 token 是否异常。排查下游处理后处理解析、数据库写入、外部工具调用是否报错。AI 模型输出正常不代表下游代码能处理。排查资源与成本CPU、内存、并发、token 消耗是否到达瓶颈。系统变慢不一定是模型问题可能是批量任务把资源占满了。这条链路的核心原则是从“外部边界”往“内部细节”走。先确认整个输入输出有没有问题再层层往下看。如果一开始就盯着 AI 模型调 prompt很容易忽略真正的问题可能出在入口参数或者下游解析。4.3 常见错误姿势有些项目确实是打了日志但依然让人无从下手因为姿势不对。一是只在报错时看日志。平时不知道正常时应该长什么样结果报错日志和正常日志混在一起你分不清什么才是异常。正确做法是正常路径也打摘要日志建立基线。二是日志里没有 trace_id。日志是打了但每个模块各自打各自的一个请求在服务端经过多个步骤时无法串联。没有 trace_id 的日志在排查多环节问题时几乎等于没有。三是记录敏感信息。把 prompt 完整原文、用户输入、数据库连接串打进去日志一开隐私和账号风险全暴露。正确做法是记录摘要和长度文本内容按需脱敏。四是日志打太多。每个循环、每个变量都打一条最后日志文件膨胀检索效率极低反而找不到关键信息。好的日志是克制的只在有业务意义的事件上打点。4.4 不是所有项目都需要完整可观测性必须承认可观测性是分级的。对于单纯的一次性脚本、本地数据清洗、几天就删的实验代码确实没必要上一整套追踪系统。一次性脚本、本地实验结构化日志 trace_id 就够了。定期运行的内部工具加指标、错误率、重试逻辑和简单 dashboard。面向用户的服务需要完整的 Logs Metrics Traces配合告警。强合规、高安全场景还要增加审计日志、权限控制、敏感信息自动脱敏。判断标准其实很朴素这个系统会长期运行吗别人会接手吗失败的影响范围大吗三个问题里有两个是“是”就值得投入。如果只是临时脚本那保持轻量即可但至少别用裸print。5. 从 Vibe Coding 到 AI Engineering还差几块拼图可观测性是分水岭但不是全部。它解决的是“看得见、查得清”的问题而真正的 AI Engineering还需要把评估、版本、成本、安全这些因素纳入到统一的工作流里。5.1 可观测性之外的工程拼图第一块拼图是评估闭环。Vibe Coding 生成完代码你得有办法验证输出质量。不一定是完整测试套件但至少要有一条可重复的链路来判断“这版结果是否比上一版好”。常见的做法是给模型输出加结构化字段打分或者跑一组固定的样例用例观察它是否稳定产出预期结果。没有评估闭环可观测性会退化成“记录了一堆数据但不知道什么是好”。第二块拼图是版本控制。代码要进 Gitprompt 和模型配置也要进版本管理。很多 Vibe Coding 项目把 prompt 写在 Jupyter notebook 或 IDE 里随手改一下模型输出就变了却没人知道是哪版改的。把 prompt 模板、模型名称、温度、上下文构造逻辑都纳入版本管理才能和日志中的 model 字段对应起来。第三块拼图是成本控制。AI 项目里token 消耗是直接成本而且会随调用量增长快速上升。Vibe Coding 原型可以忽略它但一旦上线就必须在指标里记录 token 消耗设置调用上限思考缓存和批量策略不能让一个输出格式解析失败导致重复调用三五次。第四块拼图是权限与安全。AI 生成代码时如果 prompt 里包含不该暴露的数据或模型调用逻辑可以触达内部系统风险会成倍放大。日志里做脱敏、配置里做最小权限是 AI 工程里最基本的防线。5.2 团队协作里的关键转变能复现、能解释、能交接从一个开发者自己玩到多个人协作维护Vibe Coding 项目会遇到一个明显的协作瓶颈怎么把“我不太清楚它为什么这样”变成可沟通的信息。我之前遇到过类似场景同事用 Vibe Coding 写了一个 AI 辅助的数据处理工具demo 跑得不错。后来一次生成结果异常我们俩坐在同一台电脑前花了一个小时也没复现。因为他没记录模型版本也没记录当时的输入上下文。最后只能重新写 prompt靠聊天记录里的截图还原。这个教训很直接Vibe Coding 生成出来的不只是代码还有一系列决策点。这些决策点没有记录交给别人时就是一个“不可解释的盒子”。团队协作的转折点在于把沟通方式从“让我看看代码”变成“让我看看 trace”。代码当然要读但更有价值的是看到一个请求从进入到返回的完整路径。协作时能说“我把这次 trace 发给你你检查一下第 3 跳的上下文构造”比“你跑一次试试我这边是正常的”要高效得多。5.3 一条分层演进路径脚本、服务、产品我不建议任何项目都从第一天就搭完整的可观测性平台。更合理的方式是随复杂度递增按阶段演进。阶段一脚本级别。目标是把“能跑”变成“能调试”。做法结构化日志 trace_id 输入输出摘要。适合个人工具、原型验证。阶段二服务级别。目标是把“能调试”变成“能监控”。做法接入 Metrics记录请求量、错误率、延迟、token 消耗把日志转存到一个可以检索的平台。适合内部工具、小规模服务。阶段三产品级别。目标是把“能监控”变成“能预警、能复盘”。做法完整的 Traces、告警规则、dashboard、评估闭环、成本约束。适合用户模型、生产级 AI 应用。每升一级意味着投入增加但也意味着系统可靠性的要求更高。Vibe Coding 项目最大误区是认为原型验证之后可以直接进入生产。正确姿势是先确认它值得继续演进再按步骤补齐工程能力。6. 关于实践我的三条建议如果上面的内容对你有用最后我想收敛成三条可以直接落地的建议。它们都围绕同一个判断Vibe Coding 的代码可以快速生成工程能力却不能靠提示词生成。6.1 把每次 Vibe Coding 当成一次需要审计的代码提交不要抱着“反正是 AI 写的看看能不能跑”的心态。每次让 AI 生成代码前先写清楚一句话目标以及验收标准。生成完成后第一件事不是兴奋地跑结果而是补上最基本的入参校验和日志。这里最容易被忽略的是AI 生成时它默认你提供的需求是完整且明确的。它不会主动告诉你它跳过了哪些异常情况。你要做的是把它生成的代码当成一个陌生同事提交的 PR 来 review而不是当成“免费外包”。6.2 从第一行代码开始写结构化日志这是成本最低、收益最直接的工程化动作。无论项目多小都不要用print来调试和追踪。至少从第一行代码开始就用结构化日志给每次任务生成一个 trace_id把关键输入输出记录成 JSON。可能有人觉得这样很繁琐。但 Vibe Coding 项目最大的特点就是代码迭代快人工不可能逐行 read。日志是我们为数不多的“外部审计视角”。它可以帮你回答“它这次为什么不一样”“它在哪里失败了”“它消耗了多少资源”。没有这些你只能对着黑箱猜。6.3 先建立最小可观测闭环再谈优化和扩展不要在一开始就想着接全套指标、告警、dashboard。先建立一个可用的最小闭环。这个闭环的标准是一条请求能被追踪一个错误能被定位一次输出能被验证。只要这三个能力存在你就已经具备了把这套系统继续演进的基础。等未来出现性能问题或成本问题再按需要逐步增加 Metrics 和 Traces不用一开始就做成重型系统。反过来如果连最小闭环都没有就急于优化 prompt、提升效果、扩大并发那所有优化都会建立在“看不见的基础”上很难持久。说到底Vibe Coding 是一个很值得长期关注的方向但它的意义不是让我们绕过工程而是让我们把更多认知从“怎么写代码”里解放出来放到“我要什么结果对不对它为什么这样”这些更重要的判断上。可观测性正是承接这个判断的基础设施。AI 帮你把代码写出来了工程还是要你自己扛下去。如果你正准备用 Vibe Coding 做一个项目我建议在第一次运行之前先花十分钟回答一个问题这个程序跑起来后你会看到哪些记录靠这些记录你能不能向一个还没接触过项目的人解释它为什么这样工作如果能说明你已经从 Vibe Coding 走向了 AI Engineering如果不能那今天就是补齐这一步最好的时间点。