AutoChain 与 LangChain 比较

我的从零开始学 LangChain系列还没更完,感觉就要快被策反了 🤣,最近炒的很火的 我为什么放弃了 LangChain?,算是代表社区和广大开发者进行了一次大吐槽。LangChain 确实和 OpenAI 耦合的太紧导致扩展性较差,也存在过度封装以及调试困难的问题,但我的观点是在更成熟的框架出来之前,刚开始接触 LLM 应用开发的同学还是应该看看 Langchain,它运用 Prompt Engineering 的思想很值得借鉴,不过 LLM 应用开发的老司机确实该换工具了 🤡,这篇就给大家介绍下这款号称要替代 LangChain 的 AutoChain

我的新书《LangChain编程从入门到实践》 已经开售!推荐正在学习AI应用开发的朋友购买阅读!
LangChain编程从入门到实践

介绍

AutoCHain 是 Forethought AI 公司(成立于 2017,AI 智能客服领域)开源的,先看看它对自己的介绍:AutoChain 从 LangChain 和 AutoGPT 中汲取灵感,旨在通过提供一个轻量级、可扩展的框架来解决这两个问题,开发人员可以使用 LLMs 和自定义工具构建自己的代理,并通过模拟对话自动评估不同的用户场景。有经验的 LangChain 用户会发现 AutoChain 很容易上手,因为它们共享相似但更简单的概念。我们的目标是通过简化代理定制和评估,实现生成式代理的快速迭代。

看见没,AutoChain 是在 LangChain 的基础上取其精华,去其糟粕,旨在成为构建轻量级、可扩展且可测试的 LLM 代理优秀开发工具,下面我们逐一过下特性,然后通过实现一个天气查询的功能来比对下代码,看看是噱头,还是真优雅。

特性

  • 🚀 轻量级、可扩展的生成式代理 pipeline
  • 🔗 可使用不同自定义工具并支持 OpenAI 函数调用的代理
  • 💾 对对话历史和工具输出进行简单的内存跟踪
  • 🤖 通过模拟对话自动进行代理多轮对话评估

代码实践

下面以 OpenAI Functions Calling 和天气查询 API 结合实现查天气功能的 Agent 为例,比对下 AutoChain 和 LangChain 区别。

AutoChain

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import json
from autochain.agent.openai_functions_agent.openai_functions_agent import (
OpenAIFunctionsAgent,
)
from autochain.chain.chain import Chain
from autochain.memory.buffer_memory import BufferMemory
from autochain.models.chat_openai import ChatOpenAI
from autochain.tools.base import Tool


def get_current_weather(location: str, unit: str = "celsius"):
"""根据输入地点获取天气情况"""
weather_info = {
"location": location,
"temperature": "28",
"unit": unit,
"forecast": ["温暖", "晴朗"],
}
return json.dumps(weather_info)


tools = [
Tool(
name="get_current_weather",
func=get_current_weather,
description="""根据输入地点获取天气情况""",
)
]

if __name__ == "__main__":
memory = BufferMemory()
llm = ChatOpenAI(temperature=0)
agent = OpenAIFunctionsAgent.from_llm_and_tools(llm=llm, tools=tools)
chain = Chain(agent=agent, memory=memory)
user_query = "今天北京天气怎么样?"
print(f">> User: {user_query}")
print(f">> Assistant: {chain.run(user_query)['message']}")

执行结果跟踪

1
2
3
4
5
6
7
8
9
10
11
12
13
>> User: 今天北京天气怎么样?
Planning

Planning output:
message content: 'hum..'; function_call: {'name': 'get_current_weather', 'arguments': '{\n "location": "Beijing"\n}'}
Plan to take action 'get_current_weather'

Took action 'get_current_weather' with inputs '{'location': 'Beijing'}', and the tool_output is {"location": "Beijing", "temperature": "28", "unit": "celsius", "forecast": ["\u6e29\u6696", "\u6674\u6717"]}
Planning

Planning output:
message content: '今天北京的天气很好,温度为28摄氏度,天气晴朗。'; function_call: {}
>> Assistant: 今天北京的天气很好,温度为28摄氏度,天气晴朗。

LangChain

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.chat_models import ChatOpenAI
from langchain.tools import Tool
import json

def get_current_weather(location: str, unit: str = "celsius"):
"""根据输入地点获取天气情况"""
weather_info = {
"location": location,
"temperature": "28",
"unit": unit,
"forecast": ["温暖", "晴朗"],
}
return json.dumps(weather_info)

tools = [
Tool.from_function(
name="get_current_weather",
func=get_current_weather,
description="""根据输入地点获取天气情况""",
),
]

if __name__ == "__main__":
llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613")
mrkl = initialize_agent(tools, llm, agent=AgentType.OPENAI_FUNCTIONS, verbose=True)
mrkl.run("今天北京天气怎么样?")

执行结果跟踪

1
2
3
4
5
6
7
8
> Entering new AgentExecutor chain...

Invoking: `get_current_weather` with `{'location': '北京'}`


{"location": "\u5317\u4eac", "temperature": "28", "unit": "celsius", "forecast": ["\u6e29\u6696", "\u6674\u6717"]}今天北京的天气情况是温暖的,气温为28摄氏度,天气晴朗。

> Finished chain.

对比探讨

AutoChain 明显嵌套更浅一点,而且对开发人员来说直觉上更容易理解,一个特定功能的 Agent 就是一个特定工具与 LLM 的结合,实际开发过程中会面临大量 Agent 的管理和复用。这种方式也更容易对 Agent 进行嵌套,而且直接用类似 OpenAIFunctionsAgent 的声明极大的提高了代码可读性。
同时日志的输出也更加友好易懂,按照用户意图转换为执行计划,动作规划,执行计划结果返回展示

1
2
agent = OpenAIFunctionsAgent.from_llm_and_tools(llm=llm, tools=tools)
chain = Chain(agent=agent, memory=memory)

LangChain 则让写代码的人非常疑惑,这里的 Agent 初始化,直接将特定工具,LLM 和 Agent 类型整合在一起,但是实际开发过程中工具来源多样性,LLM 也是多样的,再加后面的 Agent 类型,管理起来会非常混乱。开发人员需要的是灵活组合且可管理的 Agent,统一用 initialize_agent 一次性声明固然方便,但代码维护者负担很大。

日志也是很不友好,因为你直接去读,无法感知到 Agent 的运行逻辑,除非打开全局日志(虽然详细,但是会输出一大段未处理的原始调用信息 😅)

1
mrkl = initialize_agent(tools, llm, agent=AgentType.OPENAI_FUNCTIONS, verbose=True)

结论

AutoChain 值得关注,使用体感上确实强于 LangChain,笔者本人已经准备积极拥抱 AutoChain 了,推荐大家去阅读源码,并尝试更多的案例,毕竟优雅的开发框架可以帮助自己提高效率,拥有更多 Coffee Time ☕️

不可错过 👉:之前创建的 LLM 应用开发交流群已经运行 1 年了,里面会实时分享 AI 应用开发生态最新进展,欢迎感兴趣的朋友加入交流,请备注【入群交流

如果觉得内容不错,欢迎**订阅邮件和RSS,转发文章**~

参考链接

作者

莫尔索

发布于

2023-07-24

更新于

2024-05-19

许可协议

评论