自从去年下半年到最近一直都聚焦在 Agent 框架实现上,从相对底层的 langchain、到专注做多 Agent 协作的 AutoGen、MetaGPT ,还有专注做记忆的 MemGPT 这些框架,自己都是认真地进行学习和研究,所有也沉淀了一些东西,所以今天就来聊一聊,从 langchain 聊起,聊的内容不会拘泥于局部具体实现,以及如何使用 langchain Api ,我会从应用角度来看一看 langchain 3 个比较基础模块是如何设计的,以及他们都解决了什么样问题,个人也推出了一套分享,可以帮助大家快速了解 langchain 分享发布在 b zhan 上,希望大家多多支持。
langchain 是什么
LangChain 是一个开源的框架,用于开发基于 LLM 的应用程序。借助 LangChain ,开发人员可以更快速地开发基于 LLM 的应用。lagnchain 提供让 LLM 可以利用外部计算资源,并且通过数据来增强 LLM 的知识。LangChain 还通过提供检查、监控和评估的工具。
要聊的内容
今天主要来聊一聊 LangChain 下面 3 个个人任务相对比较基础且重要的模块,因为我们可能只需要这 3 个模块就足够搭建出一个 LLM 的应用,换句话说他们是开发 LLM 的应用 langchain 提供最小模块集合。为了让大家可以快速上手 langchain,就先挑选这 3 个主要模块给大家来说一说。
- prompt
- tool
- parser
langChain快速入门
工具调用
人类进步是离不开工具,今天汽车也好、飞机也好都是扩展我们人类的能力边界,通过外延工具让我们能够完成自我超越。那么对于 Agent 同样也需要工具来操作 LLM 自身能力,突破限制,做的更好。那么工具能够解决那些 LLM 那些限制和不足。
- 实时性
- 缺乏专业领域知识
- 和周围环境的交互
- 幻觉
- 多模态
工具对于 LLM 的重要性不言而喻,工具是 LLM 和外界连接手段和方式,通过搜索工具使用,LLM 可以突破实时性的限制,获取当前最新的信息。通过工具调用也是实现 RAG 基础,这样就可以通过 RAG LLM 就可以利用外部知识在不破坏原有的表征学习基础上来吸收一些专业知识,同时工具也是 memory 模块也是十分重要,是实现 memory 模块重要的基础,有了工具,LLM 才能感知更多信息,来控制外界。
最近 ollama 也开始支持工具了,由此可见工具重要性各家都已经意识到了,工总是一句话工具的使用,扩展了 LLM 扩展边界。除此之外工具也可以矫正 LLM 幻觉的问题。
那么如何让大语言模型认识工具,主要是通过这些的 schema 对工具进行抽象
tools=[{
'type': 'function',
'function': {
'name': 'get_current_weather',
'description': 'Get the current weather for a city',
'parameters': {
'type': 'object',
'properties': {
'city': {
'type': 'string',
'description': 'The name of the city',
},
},
'required': ['city'],
},
},
},
]
对于一个普通函数,langchain 提供丰富工具将其变为可使用的工具,例如可以通过注解来将一个函数变为工具。
@tool
def add(x: float, y: float) -> float:
"""Add 'x' and 'y'."""
return x + y
也可以让类继承于 Tool 从而转化为工具,同时 langchain 也内置许多类,他们对常用 Api 或者 SDK 进行封装便于开发者更好调用,
在消息类型也提供了 ToolMessage、FunctionMessage 类型的 Message 让 LLM 可以接收到工具和函数返回的信息。这个也可以看作 LLM 和外界的交互。其实工具底层实现还是通过 prompt 让模型了解工具,学会使用工具,所以也需要模型在训练阶段倾向让其学会使用工具。
在视频分享了两个实例,这两个实例整合了之前学习的内容,
prompt
langchain 在 prompt 上也是下了功夫的,设计了 promptTemplate 通过模板方式一方面增加了模板的规范化,复用性,另一个方面通过变量增加模板灵活性。
在 langchain 主要针对 completion 和 chat 设计了 PromptTemplate 和 ChatPromptTemplate,特别是在 ChatPromptTemplate 设计上下了很多功夫,增加 Message 帮助结构化信息以及 placeholder 来增加模块灵活性,还有就是 examples 方面的支持,也提供多种的 exampleSelector 帮助从众多 examples 选择出有效的 example 在 prompt 中作为示例,让 LLM 更好理解任务规范输出。
不过大家不要忘记,无论花样有多少,prompt 最终就是一个字符串,我们通过打印观察来学习些出一个好的 prompt 技巧,目前开看是这是需要做实践和摸索的工作。
OutputParser
为什么需要 OutputParser,解析器设计更多考虑到对大语言模型输出进行结构化,因为 Agent 可能作为一个现有应用的一个模块,或者 Agent 之间需要传递数据进行沟通,这样需要对大语言模型输出进行结构化,这是为什么设计 OuputParser
现在很多模型的提供企业也注意这一点重要性,如果没有结构化的输出,那么 LLM 就无法融入到现有系统,无法给我们提供有用的输出,更不要说在应用内部 Agent 之间的协作了。
所以在 langchan 中对此也有了良好的支持,其中过多受欢迎就当属 json 格式,langchain 提供了 JsonOutputParser 以及 PydanticOutputParser 这样数据校验库也给与很好支持。