代码智能体工作原理:从 LLM 到工具调用
和任何工具一样,了解代码智能体的底层工作原理,能帮你做出更好的应用决策。
代码智能体本质上是一套软件,它作为 LLM 的执行框架(Harness),通过不可见的提示和可调用工具,为 LLM 扩展了额外能力。
大语言模型(LLM)
任何代码智能体的核心都是一个 LLM。它们有各种名字,比如 GPT-5.4、Claude Opus 4.6、Gemini 3.1 Pro 或 Qwen3.5-35B-A3B。
LLM 是一种机器学习模型,能够补全文本句子。给模型输入“the cat sat on the ”,它(几乎肯定)会建议下一个词是“mat”。
随着模型规模增大、训练数据增多,它们能补全更复杂的句子,比如“a python function to download a file from a URL is def download_file(url): ”。
LLM 实际上并不直接处理单词,而是处理Token。一段文本会被转换成整数 Token 序列,所以“the cat sat on the ”就变成了 [3086, 9059, 10139, 402, 290, 220]。理解这点很重要,因为 LLM 提供商按处理的 Token 数量收费,并且一次能考虑的 Token 数量也有限制。
你可以用 OpenAI 的 Tokenizer 工具来实验:platform.openai.com/tokenizer。
输入给 LLM 的内容叫提示(Prompt)。LLM 返回的文本叫补全(Completion),有时也叫响应(Response)。
如今许多模型是**多模态(Multimodal)**的,这意味着它们能接受文本以外的输入。视觉 LLM(vLLM) 可以接受图像作为输入,这样你就能喂给它草图、照片或截图。一个常见的误解是这些图像会经过单独的 OCR 或图像分析流程处理,但实际上这些输入也被转换成了更多的整数 Token,并以与文本相同的方式进行处理。
聊天模板提示
早期的 LLM 作为补全引擎工作——用户提供一个提示,然后由模型补全,就像上面那两个例子。
这种方式对用户不太友好,所以模型大多转向使用聊天模板提示(Chat Templated Prompts),它将与模型的交流模拟成一段对话。
这实际上只是一种特殊格式的补全提示,看起来像这样:
user: write a python function to download a file from a URL
assistant:
这个提示的自然补全就是助手(由 LLM 扮演)用一些 Python 代码来回答用户的问题。
LLM 是无状态的:每次执行提示时,它们都从同一张白纸开始。
为了维持对话的模拟效果,与模型对话的软件需要维护自己的状态,并在用户每次输入新的聊天提示时,重放整个已有的对话:
user: write a python function to download a file from a URL
assistant: def download_url(url):
return urllib.request.urlopen(url).read()
user: use the requests library instead
assistant:
由于提供商对输入和输出 Token 都收费,这意味着随着对话变长,每次提示的成本会越来越高,因为输入 Token 的数量每次都在增加。
Token 缓存
大多数模型提供商通过缓存输入 Token(Cached Input Tokens) 的更低费率来部分抵消这种成本——在短时间内处理过的常见 Token 前缀可以按较低费率收费,因为底层基础设施可以缓存并复用处理该输入时使用的许多昂贵计算。
代码智能体的设计就考虑到了这种优化——它们避免修改先前的对话内容,以确保尽可能高效地利用缓存。
调用工具
LLM 智能体(Agent) 的定义性特征是能够调用工具(Tools)。但什么是工具?
工具是智能体执行框架提供给 LLM 调用的函数。
在提示层面,它看起来像这样:
system: If you need to access the weather, end your turn with <tool>get_weather(city_name)</tool>
user: what's the weather in San Francisco?
assistant:
这里,助手可能会用以下文本响应:
<tool>get_weather("San Francisco")</tool>
然后,模型执行框架软件会从响应中提取这个函数调用请求——可能用正则表达式——并执行该工具。
接着,它将结果返回给模型,构造的提示看起来像这样:
system: If you need to access the weather, end your turn with <tool>get_weather(city_name)</tool>
user: what's the weather in San Francisco?
assistant: <tool>get_weather("San Francisco")</tool>
user: <tool-result>61°, Partly cloudy</tool-result>
assistant:
现在,LLM 可以利用这个工具结果来帮助生成用户问题的答案。
大多数代码智能体定义了十几个甚至更多的工具供智能体调用。其中最强大的工具允许代码执行——例如,执行终端命令的 Bash() 工具,或运行 Python 代码的 Python() 工具。
系统提示
在前面的例子中,我包含了一条标记为“system”的初始消息,它告知 LLM 可用的工具以及如何调用它。
代码智能体通常以这样的系统提示开始每次对话,它不显示给用户,但提供了指示模型应如何行为的指令。
这些系统提示可能长达数百行。以 OpenAI Codex 的系统提示(截至 2026 年 3 月)为例,这是一个清晰展示了让这些代码智能体工作的指令类型的实用例子。
推理
2025 年的一大新进展是前沿模型家族引入了推理(Reasoning) 能力。
推理,有时在 UI 中呈现为思考(Thinking),是指模型在向用户呈现回复之前,花费额外时间生成文本,来梳理问题及其潜在解决方案。
这看起来有点像一个人在自言自语,效果也类似。关键在于,它允许模型花费更多时间(和更多 Token)来处理问题,以期获得更好的结果。
推理对于调试代码问题特别有用,因为它给了模型一个机会来导航更复杂的代码路径,混合工具调用,并利用推理阶段来追踪函数调用,定位问题的潜在根源。
许多代码智能体包含了调整推理努力程度的选项,鼓励模型在更棘手的问题上花更多时间思考。
LLM + 系统提示 + 工具循环
信不信由你,构建一个代码智能体主要就是这些!
如果你想更深入地理解这些东西如何工作,一个有用的练习是尝试从头构建你自己的智能体。在现有 LLM API 的基础上,用几十行代码就能实现一个简单的工具循环。
当然,一个好的工具循环比这要复杂得多,但基本的机制出人意料地简单直接。
觉得有用?分享给更多人