ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

对抗LLM编程的程序化停滞:从代码生成到工程化落地

对抗LLM编程的程序化停滞:从代码生成到工程化落地 说到 LLM 写代码我最常被问的不是某个模型好不好用而是“我们团队现在代码量暴涨为什么越来越没人能接手维护”。这个现象正好对应一个概念Programmatic Stagnation中文可以理解成程序化停滞。它不是在说 LLM 能力不行而是在说人和生产流程在大模型时代会暴露出来的卡点生成代码的速度上去了理解、调试、测试、维护和架构决策的能力没跟上。如果你正在用 LLM 辅助开发或者团队已经引入了 AI 编程这篇文章值得看完。我会先讲清楚程序化停滞的具体信号再给一套个人和团队都能落地的对抗方法然后继续拆到应用落地时最容易卡住的编排、部署与验收环节。整体思路很简单LLM 代替的是重复劳动不是人的理解能力。1. 程序化停滞到底卡在哪不是模型不够强是生产链路没有跟着变1.1 先从现象认识“程序化停滞”最典型的场景长这样一个需求下来开发者把需求复制给 LLM模型生成几百行代码开发者本地跑一遍没问题提交了。过了两天另一个需求要改其中一段逻辑没有人能说清原来那段代码为什么这么写。于是又让 LLM 重新生成一个版本可能整个函数被推倒重来。代码仓库里的文件越来越多但模块之间的边界越来越模糊。这就是程序化停滞程序在持续生产编程能力却原地徘徊。它也可以表现为文档缺失。注释都写得像模像样但设计文档为空函数都能跑但没人知道为什么拆成这些函数接口都能调通但接口之间的数据流向只存在于某次对话记录里。等到模型升级、依赖升级、人员变动这些问题会集中爆发。程序化停滞不是某一个人独有的问题。它更像一种团队状态每个节点都在用 LLM 产出代码但真正能把代码从“能跑”推进到“可维护”的环节没人负责。生成速度越快积压的不可控代码越多项目反而越难推进。1.2 为什么 LLM 会让这种停滞更容易发生很多人在使用 AI 编程工具之后会有一个直觉代码长得越来越像正确答案。以前从论坛复制粘贴的代码多少还残留着调试痕迹、奇怪的临时变量、缺一半的异常处理LLM 输出通常结构完整、命名规范、注释齐全。这种“专业感”会让人放松警惕默认它是对的。但真正决定代码能不能长期维护的往往不是格式而是业务约束、边界条件和异常路径。这些恰恰需要人去读、去测、去验证。模型生成代码时缺少对真实业务场景的确认它只是在概率上补全一段看起来合理的文本。如果开发者不补上验证环节就相当于把不确定的复杂度直接放进生产环境。另一个原因是反馈回路变短了。传统编程里写错要经过编译、运行、报错、修复这个过程虽然痛苦但会逼着人理解每一步。用 LLM 之后从需求到产出只要几分钟中间的冲突和试错被抹平了人没有机会积累那部分直觉。短期的感觉是效率变高长期来看调试经验、代码阅读能力、问题定位能力都会退化。还有一个容易被忽视的点技能结构发生了位移。以前老手和新手的差距很多体现在代码阅读能力和调试能力上现在这两项能力恰恰是最容易被 AI 代劳的。如果一个人长期只写 prompt、只复制结果他的调试能力会钝化。一旦失去这个能力遇到复杂问题时就只会不断换 prompt 重试而不是打开日志找原因。1.3 识别停滞的几个信号如果你不确定自己有没有进入这个状态可以先对照几个信号来看离开 LLM 提示连一个短小函数都不会起笔。模型生成的代码报错第一反应是重新生成而不是打开日志找原因。功能能跑但没有为它补测试用例。你能把模型生成的代码贴出来但讲不清楚它为什么这么设计。代码评审里所有人只看结果能不能运行没有人讨论接口契约和模块边界。反过来健康的信号也很明确你能改掉模型生成的一部分逻辑而不怕出问题你能为新场景补上边界测试你能在半小时内说清一段代码的输入、输出和风险。可以用下面这个表格做快速判断停滞信号健康信号离开模型不会写小函数能独立写出短小清晰的函数报错后重新生成先看日志和调用栈定位原因不写测试至少为关键分支补测试贴代码但讲不清能解释模块边界和异常处理方案只关心能否运行关心可测试性和可维护性这些信号不需要全部命中才算停滞。只要中了三条就该调整使用 LLM 的姿势了。2. 对抗个人停滞把 LLM 当成结对搭档而不是自动结账机2.1 “读-改-测-讲”四步闭环我这里有一个很笨但很有效的办法每次让 LLM 生成代码后不要直接接受先做四步。第一步读。把生成代码从头到尾读一遍不是看有没有语法错误而是看它把逻辑分成了哪几段哪些地方你没想到。读的时候可以问自己如果下次换一个需求我要改哪里第二步改。随便挑一个变量名、一个边界值或一个分支条件主动改一下跑一遍测试看结果是否按预期变化。这个动作是为了确认你真的理解了这段代码而不是只会看。第三步测。补一组用例至少覆盖空输入、正常输入、异常输入。模型生成的代码往往只覆盖了正常路径的前半段边界测试是最容易暴露问题的地方。第四步讲。把你读到的实现思路讲给别人听或者带着结论写到周报和笔记里。讲不出来的部分就是你的知识盲区也是程序化停滞最常发生的地方。这个闭环的价值不在于效率而在于把使用 LLM 的过程重新变成学习过程。你仍然用模型省掉搭建骨架的时间但你必须为结果负责。模型可以帮你完成初稿但不能替你建立对代码的所有权。2.2 用 LLM wiki 的思路建个人知识库近年开发者圈子里经常出现 LLM wiki 这个提法。它的核心不是让模型替你写文档而是把大模型当作一个可以随时问话的对话式知识库同时由你自己维护知识结构。换句话说模型负责检索和表达你负责判断哪些东西值得沉淀。我自己的做法很简单遇到一个能跑通但不太理解的方案我会在本地 Markdown 文件里记录三件事——问题是什么、我做了什么尝试、最终为什么这么选。LLM 可以辅助生成记录草稿但目录和标签由我自己维护。这样下次遇到类似问题我不必重新让模型从头推理只需翻看自己的 wiki。工具层面Obsidian 或其他本地笔记工具都只是容器。真正重要的是内容是否围绕你的实践展开。长期积累下来个人 wiki 会越来越像一份专属架构手册而不是收藏夹里越堆越多的文章链接。程序化停滞的一个典型表现就是反复让模型回答同一个问题却从不把答案变成自己的知识资产。2.3 把 LLM 放进代码审查流程我建议团队把 LLM 放进代码审查里但不要把审查权交给它。具体做法是当开发者提交代码时让 LLM 负责三类检查。第一边界条件有没有遗漏。比如空列表、超长输入、并发写、文件不存在这些情况模型生成代码时经常只处理正常分支。第二错误处理有没有收敛。是不是只管返回 null没有日志是不是把所有异常都吞掉导致线上问题无法定位。第三能不能基于现有代码生成一批测试用例。不是简单跑通主流程而是补覆盖率和边界分支。开发者收到这些建议后再对照业务需求做判断。为什么不能让 LLM 全权把关因为模型缺少项目上下文和长期演进目标。它看得见局部代码却看不见模块之间为什么这么划分。真正应该由人拍板的是接口契约、数据流方向、兼容性策略和重构边界。把这些交给模型等于把架构决策外包给一个没有全局视图的助手。3. 从“写代码”到“搭应用”工程化编排才是真正拉开差距的地方3.1 为什么单次生成不等于应用落地很多初学者第一次接触 LLM 应用开发时会以为“调用模型接口返回结果”就是应用的全部。实际上一个能稳定上线的 LLM 应用除了模型调用还要处理三件事上下文怎么组织、工具怎么接入、失败怎么兜底。这就是越来越多人提到 LLM 编排框架的原因。不是说必须用复杂框架而是说单次调用无法覆盖真实场景。真实场景长什么样用户提出一个问题这个问题的答案可能在文档库里需要先检索也可能需要通过工具查询系统数据而不是直接靠模型记忆更可能第一遍回答不完整需要模型反复纠偏。如果只是把用户输入拼进 prompt然后拿模型输出返回很多场景会直接翻车。LLM 应用开发领域会看到 RAG、MCP、Agent、SpringAI 这些词它们不是同一层的东西解决的问题也不一样。把这几个概念放对位置比背熟某个框架 API 更重要。3.2 理解 RAG、MCP、Agent 各自的位置我一般会跟团队这样解释这几个概念。RAG检索增强生成解决的问题是给模型补充外部知识。你有一个企业内部文档库模型没有训练过这些内容于是先检索相关文档再把文档内容放进上下文最后让模型基于这些内容回答。判断任务是否需要 RAG就看答案是不是依赖私有、动态更新的知识。如果回答只需要模型通用能力就不需要引入检索链路。MCP模型上下文协议解决的问题是让模型能够调用外部工具。可以把工具理解成接口搜索网页、查询数据库、创建工单、解析文件。MCP 提供了一套统一连接方式让模型不需要为每个工具写一套私有协议。判断任务是否需要 MCP就看模型是否需要去外部系统拿数据或执行动作。Agent智能体解决的问题是让模型在一个循环里做规划、调用工具、观察结果、继续决策。它适合多步骤任务比如“查一下最近几天数据异常的原因并把结论整理成邮件”。判断任务是否需要 Agent如果只是单轮问答那不需要如果模型要连续做两三次工具调用并且依赖中间结果决定下一步那才需要考虑 Agent。SpringAI 这类框架是在 Java 生态里把这些能力封装成统一入口。具体 API 每个版本差异很大所以我这里不给精确代码只给一条通用的处理链路# 伪代码一条带检索和工具调用的问答链路 def handle(user_input): docs retriever.search(user_input) # RAG检索外部知识 context build_prompt(user_input, docs) plan agent.plan(context) # Agent决定是直接回答还是调用工具 if plan.action tool: result tool_client.call(plan.tool) # MCP调用外部工具 final_context build_prompt(user_input, docs, result) return agent.finish(final_context) return agent.answer(context)这是流程示意实际落地时你需要关心向量库和 embedding API 的配置工具调用要设超时Agent 要限制最大循环次数防止模型在工具之间反复横跳。很多 RAG 项目报错并不是模型调不起来而是 embedding API 未配置。记住RAG 的检索依赖向量化如果 embedding 服务没有配置好后面的检索结果就是空的模型拿着空上下文回答问题答案自然不靠谱。遇到这类问题先确认三件事embedding 服务的地址和密钥能不能通向量维度与集合设置是否一致插入向量时有没有报错。3.3 从简到繁的选型梯度做 LLM 应用不要一上来就上全套框架。我的建议是分四档第一档单次问答或文本摘要。直接调模型接口不需要 RAG不需要 Agent。先把模型调用、日志、异常处理写好。第二档带知识库的问答。加入 RAG引入向量库和 embedding API排查点也会增加一个检索链路。第三档需要调用外部工具。加入 MCP 和 Agent处理工具调用的权限、超时和重试。第四档复杂业务流程。多个 Agent 协作需要任务队列、人工审核、审计日志、权限隔离和监控告警。判断标准很简单当前任务不依赖外部知识就不要加 RAG不需要多步决策就不要上 Agent。过度编排和没有编排一样都会让项目快速进入停滞。4. 部署与资源分配哪些环节最容易让项目跑起来就卡住4.1 本地跑 LLM先看精度、显存和推理引擎很多项目在 Demo 阶段没问题一换成自己本地部署就各种启动失败。最常见的原因不是代码写得不好而是模型精度和设备资源不匹配。这里把几个关键精度聊聊。精度位数权重占用数值范围主要用途常见注意点FP3232最高大训练、基准测试显存要求高推理不一定需要FP1616约为 FP32 一半较小常见推理可能出现精度损失、上下溢出BF1616约为 FP32 一半比 FP16 更大大模型训练与推理部分旧硬件不支持速度要看算子优化举个简单估算方法一个 7B 参数的模型如果以 FP16 加载权重文件大约是 14GBBF16 也接近这个体积FP32 会翻倍。推理时还要加上 KV cache 和中间激活值所以实际需要的内存会更高。这不是说一定要用最低精度而是要根据显卡、内存、框架支持一起判断。在 NVIDIA 显卡上常见的量化格式和 Mac 上的推理引擎支持情况不同。落地时先查你用的框架文档不要照搬别人的参数。尤其是 Mac 用户统一内存架构下显存和内存共用具体能用多大窗口、多长上下文完全取决于引擎对模型格式的支持程度。注意调并发前先确认资源占用。显存接近上限时优先降上下文长度和并发数再考虑换精度。4.2 ComfyUI 和 LLM 不是必须在同一台电脑这个问题经常被问到回答很明确不用。ComfyUI 本身是图像生成工作流它加载的是图像模型LLM 是语言模型推理服务。两者都需要显存和内存但不是同一个进程。如果你的机器显卡很强可以都在本机跑但建议不要同时开大任务。先用一个跑完再调另一个否则很容易显存交换频繁速度反而更慢。如果机器配置一般更合理的方案是分开放。一台图像工作站专门跑 ComfyUI另一台带 GPU 的服务器跑 LLM 推理服务通过本机网络调用接口。没有 GPU 也一样能用前提是你接受 API 服务的成本和数据传递方式。判断标准很简单同一时间会不会并发跑两类大模型任务会不会互相抢占显存延迟能不能容忍。有个容易误解的配置点ComfyUI 的 extra_model_paths.yaml 是用来扩展 ComfyUI 自己读取模型目录的并不是配置 LLM 模型位置的地方。如果你在 YAML 里写了一个 llm_pathComfyUI 本身也不会去加载这个模型。想要让 ComfyUI 里的工作流调用 LLM通常是通过自定义节点或外部 HTTP 请求而不是把 LLM 塞进它的模型路径配置。不要在这个文件上花太多时间。4.3 本地部署排查顺序我总结一个通用排查顺序遇到跑起来就卡住的问题按这个顺序走先看启动阶段。模型文件是否完整路径是否写对依赖是否装齐端口有没有冲突。再看资源占用。用系统监控看显存和内存如果接近上限优先降并发、降上下文长度或者换低精度。再看生成阶段。生成很慢先看输入长度、并行数量、模型参数量和硬件是不是匹配输出乱码先查精度和后处理不一定是模型坏了。最后看链路。如果接入了 RAG 或工具调用先单独测 embedding 和工具接口确认没有报错再回到总流程。这个顺序不复杂但能避开很多“表面上是模型问题实际是路径、权限、依赖版本”的坑。5. 用工程标准验收 LLM 产出的代码5.1 验收清单如果团队每天合并很多 AI 生成的代码但又没有统一的验收标准那么代码量越大系统越不稳定。我建议至少用这张清单做检查维度检查点功能正确性主流程能跑通定义的输入输出与实际一致边界情况空输入、超长输入、重复调用、并发调用是否有兜底错误处理失败时有明确日志而不是静默返回空值可重复性同一输入在相同上下文下结果和副作用可控可测试性核心逻辑可以被测试用例覆盖不依赖外部服务可维护性代码结构清晰命名直接无明显重复和过深嵌套这六项不是每行代码都要做到但一个功能模块如果连前三项都不满足就不应该合并。5.2 多数生成代码最缺的部分让 LLM 生成代码很多时候它会把正常路径写得非常完整却在边界和异常路径上漏掉细节。这也是
返回列表