Koalablog

Agent 学习笔记

2025-07-24

参考文章:

Agent 原理

Agent 是以大语言模型为核心的工具,由 LLM 调用其他工具来完成一些纯 LLM 不能胜任的任务,意图是扩展 LLM 的能力边界。在 OpenAI 推出 Agent 概念之前,LangChain 就已经在做这方面的工作了。

一般来说,Agent 由 Model、Tools、Memory 三个部分组成。如果了解 LLM 新兴概念,我们可以分别用一句话来概括这三个部分:Model 就是大模型,Tools 就是 MCP 或者 LangChain,Memory 就是 RAG。所以其实大家在做的事就是将过去围绕大模型建立的各种扩展能力综合起来,配上更强的大模型,让 LLM 全副武装成为 Agent。

我们把 LLM 在 Agent 中的角色称为 Planner,负责根据输入确定后面需要执行哪些步骤。而后,Agent 的中枢逻辑负责根据 Planner 的输出判断后续是否需要使用到某个 Tool,调用并收集返回结果(Action)。Action 的结果会重新送回 Planner,让大模型决策下一步是调用 Tool 还是最终输出。下图是一个常规 Agent 的大致结构。

对照流程图可以发现,上面的流程中缺少了 Memory 这个部分,我们来补全这个部分。Memory 的核心作用是让 Agent 保留对于过去的记忆,但受限于上下文窗口长度,我们不能把所有的内容都放置在 Prompt 内,只能保留近期的一部分作为短期记忆(Short-term memory),更长期的记忆需要 LLM 主动查看,这就有点像 RAG。一般来说,我们会通过向量数据库来实现 RAG,自然也可以通过相似的方法实现长期记忆。

Agent 和解释器的类比

从编程的角度来学习 Agent,我们会发现很多相似的编程范式。例如,Agent 核心是根据大模型的指令来确定下一步要做什么,大模型没有喊停之前就一直循环执行,这有点像是 EventLoop 或者解释器的运行方式。解释器是编程语言(例如 Python)和外部程序沟通的桥梁,负责自上而下地解析并执行语句(Statment),根据语义来确定要调用哪些 Native Function(文件 IO/Socket/glibc等等)。类比一下,解释器就是 Agent,被调用的操作系统 IO 能力和文件系统就是 Tools/Memory。

LLM Agent 和解释器的最大不同点就是 LLM 的输入和输出都是自然语言,而不是程序语言。然而 Agent 的循环中,需要根据 LLM 的指令来判断调用什么 Tool,以及相应的参数,这时我们需要的是结构化数据,或者说我们需要一种让大模型输出便于解析的结构化结果的方法来补全这块拼图。

OpenAI 给出的答案是 Function calling,现在的主流大模型都已经支持了这种调用方式。这并不是什么很玄乎的功能,其实就是在给大模型输入的时候,除了历史上下文、最新的 Prompt 之外,提供给他当前能调用的 Tools 和参数列表。如果 LLM 需要调用 Tools 的话,就会返回一段固定格式的 JSON。下面的例子是让 LLM 发送邮件时的输出:

[
    {
        "type": "function_call",
        "id": "fc_12345xyz",
        "call_id": "call_9876abc",
        "name": "send_email",
        "arguments": "{\"to\":\"ilan@example.com\",\"subject\":\"Hello!\",\"body\":\"Just wanted to say hi\"}"
    },
    {
        "type": "function_call",
        "id": "fc_12345xyz",
        "call_id": "call_9876abc",
        "name": "send_email",
        "arguments": "{\"to\":\"katia@example.com\",\"subject\":\"Hello!\",\"body\":\"Just wanted to say hi\"}"
    }
]

Function calling 对于 Agent 来说是非常重要的能力,虽然没有它,我们也能通过 Prompt 和后处理的手段来让大模型输出结构化数据,但稳定性要差很多。