1 引言

可以说,agent 是一种解决问题思路(道),具体的工具(术)并不重要。但在程序中,它还是需要一个具体的形态。一开始想直接用 langchain,毕竟总比自己处理逻辑要简单。然而,我发现很多非常常用的功能没有直接实现的方法,加上 llm 带来的稳定性问题,这让产品化变得很困难。于是我在外围做代码补救,使整个结构变得非常混乱。虽然功能都实现了,但考虑到后面还要添加更多 agent 功能,觉得这个框架可能无法驾驭过于复杂的逻辑。

举个例子,langchain 就像一家初创公司,只有几个员工,扁平化管理。在事务简单人也少的时候还能应付,但一旦人多事杂,就会变得混乱,有问题时不知道该找谁。即使没有一个主管,也至少一套制度规则,接口设计满足常用需求。langchain 的 agent 主要是在结构上较弱,而不是功能性差。

由于时间有限,我只调研了目前 GitHub 上最热门的 agent 工具,也看了一些项目中自行实现的 agent 代码。最终选择了 autogen,在 langchain 中遇到的问题都得以解决,总结如下。

2 使用场景

先看看选型的目的是什么?

  • 支持我需要的功能它都支持,不用自己改太多。
  • 容易理解,用法简单,学习成本低,安装打包方便。
  • 稳定性高,灵活性强。
  • 便于未来扩展。

具体选择还要看所需的功能。如果只是做一个以闲聊为主、偶尔调用工具的聊天机器人,可以用 langchain。如果涉及较多功能、偏 Agent 应用、工具间有复杂逻辑,或者觉得 langchain 无法满足需求,建议试试 autogen。

3 langchain

Langchain 提供了丰富的工具和功能,在 Agent 方面较为简单。它主要是对 LLM 工具/函数的简单封装,示例比较零散,网上的教程大多只介绍最基础的用法,上手较慢。Langchain 包含很多工具集,由于考虑了代码重用和逻辑统一性,因此如果仅使用 Agent,编写起来会有些麻烦。

由于 Langchain 出现较早且功能全面,对其 API 熟悉的人不少,网上教程也比较多。因此,对于简单使用 Agent 的情况,选择 Langchain 也是可行的。我的代码中已经使用了 LangChain 的其它功能,所以一开始我选的也是 LangChain 的 agent。

4 autogen

autogen 是 Microsoft 出品。它的文档和示例也更完整,还有一篇论文来介绍它的原理和功能 (AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation)。接口初调非常方便,只需十行代码即可搞定。对于比较复杂的用法,由于接口参数设计得比较充分,其绝大部分功能都可通过接口调用实现。除了需要跟踪基本的调用关系和了解类的父子关系外,不需要理解太多内部代码。

另一个亮点是,它集成了 Python 环境,并且可以在独立的 Docker 容器中运行代码。简单的工具可以边生成边执行,带来了更好的运行时体验,不止能调用最初设计好的工具。

另外,还可以让用户参与到与多个 Agent 的对话中,引导 agent 完成任务,非常灵活。

5 生态

从大模型支持来看,LangChain 和 AutoGen 都支持保留对话上下文。常用的 LLM 接口,如 OpenAI、Gemini 和 Claude,也都提供支持。

从安装方面看,这两个库都可以通过 pip 安装。LangChain 目前被拆成了多个包,因此相对较重,而 AutoGen 则相对更简单一些。

6 其它方法

我也看了一些代码内部自行实现的 Agent(有的利用 Langchain 的 LLM 部分和 Memory 部分,自己实现 Agent 部分)。对于简单的功能来说,这样做没问题,代码量也不多。但要想在短时间内抽象好是很难的。随着功能的增加,可能需要重写或者大改,还会出现各种各样的 bug,不如直接找个相对成熟的工具来用。

更底层的方法是直接调用 LLM 的 API 中 Tool/Function 的功能,但很多东西都要自己构造,还要考虑支持多个 LLM,非常麻烦。

这只是目前我的理解,如果大家有更好的推荐,请私信我,我也想学习一下。

7 框架切换

我的程序将逻辑和框架分开,因此可以随时替换 agent 框架而不影响功能。从 langchain 切换到 autogen 非常迅速。也可以在调工具时使用 autogen,而其他对话场景可以继续使用 langchain,两者同时使用也没问题。

从 langchain 转向 agent,之前在使用 langchain 时遇到的一些疑问或不便,autogen 基本都有所改善。特别是程序员能够控制整个流程,它包含控制层(多层控管),而不是全部交由初始的 Prompt 和 LLM 控制,这样具有更大的可控性,从而提升了稳定性。