为什么 AI 写代码总差点意思?可能是我们没给它一本「能查的说明书」
你有没有过这种经历:让 AI 写个小功能,它能一口气写完,但一加需求、一改边界条件,它就开始顾头不顾尾——刚修完的 bug 转头又冒出来,文档和代码永远对不上。问题到底出在模型不够聪明,还是我们给它的「工作环境」不对?
你和 AI 协作写代码时,是不是总在「补上下文」?
我们现在和 AI 协作写代码的方式,本质上还停留在「聊天」:把需求丢给它,它吐一段代码,你发现不对,再补两句说明,它再改一轮。几个回合下来,你一半时间都在重复解释「这个函数是干什么的」「那个变量为什么不能动」。
你可能会想:是不是把整个项目都塞进上下文窗口就好了?但真试过就知道,给得越多,它反而越容易抓不住重点——就像让一个人在堆满文件的房间里找一张便签,东西越多越容易漏。
问题的关键从来不是「上下文够不够多」,而是「上下文能不能被找对、用对」。人类程序员写代码时,手里有 IDE(集成开发环境):点一下函数名就能跳转到定义,搜一下就能看到所有引用的地方,改了代码编辑器会立刻标红不匹配的地方。而 AI 拿到的,往往只是一坨没有结构的纯文本。
把代码、文档、测试织成一张「名字的网」
那能不能给 AI 也造一个它能用的「IDE」?一篇叫 A Literate Programming Environment for Human and Machine Agents 的论文提出了一个很有意思的思路:做一个叫 notlob 的文学编程环境,把代码、自然语言说明、测试、属性约束全都放进同一个源文件里,再用一张「名称图」把它们串起来 [1]。
什么是文学编程(literate programming)?简单说,就是把程序写成一篇给人读的文章,代码只是文章里的片段,顺着文章的逻辑自然展开。notlob 把这个想法往前推了一步:不仅给人读,也给 AI 读。
它的源文件长得像带代码块的 Markdown,用 # 标题分章节,用不同的「印记符」标记不同类型的代码块——比如 ~test 是单元测试,~example 是示例,~property 是属性测试 [1]。但最核心的设计是「名称图」(name-graph):它把所有标题、函数名、测试名都当成一等对象,从语法树里构建出一张连接散文、概念和可执行代码的图 [1]。
打个比方:以前 AI 拿到的是一本没目录、没索引、页码乱序的说明书,它得从头到尾硬读,还不一定找得到重点;有了名称图,就像给了它一本带完整索引、交叉引用、超链接的说明书,它可以像人类用 IDE 一样,顺着名字跳转到定义、查到所有引用关系,甚至检查文档和代码是不是对得上 [1]。
当然,实际情况比这个比喻更复杂。notlob 还做了一套绑定机制,可以对接现有的编程语言和工具链——目前已经实现了 Haskell、Python、TypeScript 三种语言的绑定,能把它自己的测试块自动映射成对应语言的测试用例 [1]。
AI 也会「偷懒」:那些反直觉的协作观察
notlob 最有意思的部分,其实不是技术设计,而是作者在用它和 AI 协作过程中观察到的种种行为模式——这些模式和人类团队的管理问题惊人地相似。
第一个反直觉发现:AI 会「偷懒」不写属性测试。作者在做 Petri 网网页游戏项目时发现,AI 明明在散文里读到了 Petri 网的形式化性质,而且这些性质对游戏运行至关重要,却完全没有主动添加对应的属性测试 [1]。这种「忽视脚手架式声明构件」的倾向,在四种不同类型的构件里都出现了——像极了人类团队里大家都愿意写功能代码,却总拖着不写测试、不补文档的样子。
第二个发现更有意思:狂野风格的批评家反而找出更多 bug。作者让 Claude 扮演两种风格的项目审查员——一种是《纽约客》式的严谨书评人,另一种是受亨特·汤普森、大卫·福斯特·华莱士影响的「gonzo」狂野风格。结果狂野风格的对话找出了更多 bug,包括功能错误和散文与代码不一致的问题 [1]。当然,这只是轶事观察,不是统计结论,但足够让人重新思考「我们该用什么姿态和 AI 协作」。
作者也很坦诚地承认,目前这些观察都是跨几个项目的轶事性发现,还没有做受控实验或量化评估 [1]。但这些细节恰恰说明:和人类一样,AI 的行为模式也会被「工作环境」深刻塑造——环境设计得好不好,直接决定了它能发挥出多少能力。
不止编程:所有 Agent 都在遇到同一个「上下文难题」
其实不只是写代码,几乎所有 AI 智能体(Agent,指能自主感知环境、调用工具、完成任务的 AI 系统)都在面对同一个难题:怎么让 AI 在正确的时间、拿到正确的上下文、用对正确的工具。
配电网领域的 ADN-Agent 架构就遇到了类似的问题。配电网里有一大堆不同厂商、不同接口的专业模型工具,操作员根本记不住每个工具的参数和用法。ADN-Agent 的解法是给每个专业工具配一个「翻译官」(Translator 模块):通用大语言模型当调度总管,只需要用自然语言描述子任务,翻译官负责把自然语言转成具体的工具命令,再把结果传回来 [2]。这样总管不用记每个工具的细节,工具升级也不用重新培训总管——本质上就是用一层翻译机制,解决了「上下文和接口不统一」的问题 [2]。
如果说 ADN-Agent 是「多个专家配翻译」,那 MoRe(Mixture of Roles,角色混合)走的就是另一条路:让一个模型在脑子里同时调出多个角色。它的思路是,先学习一组角色转向向量(steering vector,指可以引导模型输出风格和方向的激活向量),每个向量对应一个潜在角色;然后根据输入查询,动态把几个角色的向量合成一条,注入到模型中间层 [4]。这样单模型、单轮推理就能实现多视角协作,token 成本只有多智能体系统的 1/20 [4]。
两条路看起来完全不同,但底层问题是同一个:怎么把零散的知识、工具、视角组织起来,让 AI 在需要的时候能精准调用,而不是全塞进上下文里瞎蒙。
分久必合:三大 Agent 框架悄悄长成了一个样子
如果把视野拉得更远一点,看看整个 Agent 框架的演化,你会发现一件很有意思的事:不管出发点多么不一样,最后长出来的架构都差不多。
一篇叫 The Empire, Long Divided, Must Unite 的论文做了个源码级的多案例研究,选了三个哲学起点完全对立的开源编码代理框架(agent harness,指把语言模型包装成自主代理的外围代码):一个是「大而全」的 LangChain deepagents,一个是「极简主义」的 Earendil pi,还有一个是「一切皆插件」的 DeepSeek dsh [3]。
结果发现,两个成熟的框架走着走着居然往中间凑了:大而全的那个在不断减掉冗余的脚手架,极简的那个在悄悄长出各种基础设施——最后都收敛到了五个核心要素:商品化的主循环、仅追加可重放的会话记录、把模型的特殊癖好当成数据管理、上下文渐进披露、明确的扩展接缝 [3]。第三个框架作为留出验证,也全都具备这五个要素,甚至在某个扩展点上直接复用了另一个的实现 [3]。
为什么会这样?因为「长时自主运行」这个问题本身,会逼着所有框架往同一个方向演化。比如「上下文渐进披露」——就是不要一上来把所有东西都塞给模型,而是用到什么给什么——不是某个人的偏好,而是上下文窗口有限、模型注意力容易分散这些客观约束下的必然选择 [3]。
从 Knuth 到 notlob:文学编程为什么突然又香了?
说到这里,你可能会好奇:文学编程不是个老概念吗?怎么突然又和 AI 扯上关系了?
文学编程最早是计算机科学家高德纳(Donald Knuth)在 1980 年代提出的,核心思想是「程序应该是给人读的文章,顺便能被机器执行」。这个概念在过去几十年里一直不温不火,在人类开发者中是小众爱好——毕竟大多数人写代码还是优先给机器执行,文档能补就补 [6]。
但到了 LLM 时代,这件事突然反过来了:LLM 天然最擅长理解带上下文的自然语言,反而对纯符号化的、没有注释的代码有点「读不懂气氛」。notlob 这类工具的出现,其实是把文学编程的受众从「人类读者」扩展到了「人类 + LLM 双读者」——自然语言说明不再是写给人看的「附属品」,而是人和 AI 共同理解代码的核心介质 [1]。
这就解释了为什么这个老概念突然焕发了生机:不是人类开发者突然变文艺了,而是我们的「协作对象」变了。和 AI 协作,你得用它最擅长的方式和它沟通。
还差最后一块拼图:谁来证明 AI 说的是对的?
不过,现在所有这些框架都还缺一块关键拼图:外部可验证性。
前面说的那三个收敛的 Agent 框架,作者专门指出,在所有核心架构维度里,只有「外部可验证性」——也就是能被第三方检查的、防篡改的运行记录——是三者全都没有、也完全没有往那个方向走的 [3]。
这事儿有多重要?想想看:如果 AI 写了一段代码,说「我是根据某某文档、某某测试用例写的」,你怎么知道它真的参考了那些东西,还是瞎编的?如果 AI 给出一个结论,附带了引用,你又怎么确定这个引用真的能支撑它的结论?
有研究指出,用户甚至会过度信任带引用的 LLM 回答,哪怕那些引用是随机加的 [5]。引用本来是用来增加可信度的,结果反而成了「信任安慰剂」。
而数据引用比文本引用更难。一篇关于大模型数据引用的立场论文指出,数据引用要解决三个层次的问题:训练数据怎么归因、推理时检索的数据怎么标注粒度和版本、知识图谱里的单条事实怎么定义引用和分配贡献 [5]。这些问题到现在都还没有成熟的解决方案,尤其是训练数据归因,目前对闭源模型基本不现实 [5]。
但这恰恰是人机协作绕不开的坎。未来的协作环境,不仅要让 AI 能找到上下文,还要能让人和机器都能追溯每一行代码、每一个结论的来源和依据——不然,AI 做得越快,你越不敢信。
如果你只记住一件事
真正在发生的变化,不是 AI 替代人写代码,而是我们在造一个人和 AI 共用的「工作台」。
参考文献
- A Literate Programming Environment for Human and Machine Agents(arXiv (Cornell University)、2026、全文精读)
- One Request, Multiple Experts: LLM Orchestrates Domain Specific Models via Adaptive Task Routing(arXiv、2026、全文精读)
- The Empire, Long Divided, Must Unite: Architectural Convergence in Three LLM Agent Harnesses(arXiv、2026、全文精读)
- One Model, Many Minds: Unlocking Multi-Agent Synergy in a Single Agent via Mixture of Roles(arXiv、2026、全文精读)
- Data Citation for Large Language Models: A Challenge(arXiv、2026、全文精读)
- An annotated bibliography of literate programming(ACM SIGPLAN Notices、1991、仅摘要)