我的从零开始学 LangChain 系列还没更完,感觉就要快被策反了 🤣,最近炒的很火的 我为什么放弃了 LangChain? ,算是代表社区和广大开发者进行了一次大吐槽。LangChain 确实和 OpenAI 耦合的太紧导致扩展性较差,也存在过度封装以及调试困难的问题,但我的观点是在更成熟的框架出来之前,刚开始接触 LLM 应用开发的同学还是应该看看 Langchain,它运用 Prompt Engineering 的思想很值得借鉴,不过 LLM 应用开发的老司机确实该换工具了 🤡,这篇就给大家介绍下这款号称要替代 LangChain 的 AutoChain 。
我的新书《LangChain编程从入门到实践》 已经开售!推荐正在学习AI应用开发的朋友购买阅读!
介绍 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 jsonfrom autochain.agent.openai_functions_agent.openai_functions_agent import ( OpenAIFunctionsAgent, ) from autochain.chain.chain import Chainfrom autochain.memory.buffer_memory import BufferMemoryfrom autochain.models.chat_openai import ChatOpenAIfrom autochain.tools.base import Tooldef 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_agentfrom langchain.agents import AgentTypefrom langchain.chat_models import ChatOpenAIfrom langchain.tools import Toolimport jsondef 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,转发文章 **~
参考链接