2_Agent_Langchain代理入门
1 工具 Tool
1.1 设置
需要设定如下内容,以便和 LLM 交互,名称、描述和 JSON 都在提示中使用。
- 名称(必需)
- 描述(可选)
- 输入的结构(可选)
- 函数的具体实现(需要在 langchain 中定义)
- 其它参数,如:是否将工具结果直接返回给用户
1.2 自定义工具
创建实现具体功能的函数。
1 | from langchain.tools import tool |
用 tool 装饰器,能自动生成名字描述等内容。这是最简单的一种方法,其它方法见:参考文档的自定义工具链接。
建议开始用 tool 装饰器,后面复杂了再切换到 BaseTool 方法。
2 Agent 原理
Agent 使用 LLM 来选择执行操作的顺序。在 Chain 模式中,操作序列是硬编码的,而在 Agent 模式中,语言模型作为推理引擎,决定采取哪些操作以及按什么顺序执行。
流程:选择工具 → 执行工具 → 处理结果 → 返回用户。在选择工具和处理结果时,都使用大模型。
- 根据用户问题,通过 LLM 选择工具
- 执行工具并得到结果
- 将用户问题和执行结果传给 LLM,由其判断是否进一步选择工具或直接回答用户
这样可能会引发循环调用工具,浪费 token。可以通过设置 agent 的 max_iterations 来控制迭代次数,默认值为 15 次。
3 实例
3.1 代码
这里实现了一个计算文本长度的工具。在 LLM 对话过程中,当需要统计长度时,agent 会自动调用该工具。如果对话与统计长度无关,则不会调用。
1 | from langchain_openai import ChatOpenAI |
3.2 看更多打印信息
1 | import logging |
3.3 相关概念
- Tools:工具是 Agent 可以调用的函数。
- Toolkits:LangChain 提供了工具包的概念——完成特定目标所需的 3-5 个工具组。
- Agent:负责决定下一步采取什么步骤的链。通常由语言模型、提示符和输出解析器提供支持。
- agent = tools + llm_chain + output_parser
- llm_chain = llm + prompt
- AgentExecutor:代理执行程序是代理的运行时,实际调用代理、执行其选择的操作、将操作输出传递回代理并重复此过程。
3.4 常用问题
- 跟踪工具函数的具体输出内容
- 实现 BaseCallbackHandler,记录工具的输入输出参数(内部逻辑和数据不建议过于依赖 Langchain 工具)。
- 如何实现默认信息
- 当所有工具都不匹配时,默认会返回 LLM 的回复。如果希望返回默认信息(比如在登录前,所有问题都回复“请先登录”),可以重写 OpenAIToolsAgentOutputParser 的 parse_result 方法。
- 有些问题在 Langchain Agent 的结构下很难解决,需要继承工具类并修改其内部的复杂逻辑。
3.5 langchain agent 核心代码逻辑
- 在 langchain/agents/agent.py 文件中,查看 AgentExecutor 类。
- 工具的实际运行在
_perform_agent_action()
方法中。 - 单步执行在
_take_next_stop()
方法,通过调用_iter_next_step()
完成。处理工具结果也是一个步骤。 - 与 LLM 的交互在
plan()
方法中进行,该方法在构造输入时会结合问题和之前调用工具的结果。
- 工具的实际运行在
如果想了解主流程,建议打断点并跟踪代码,这样就能明白整个过程。
3.6 优缺点
- 优点
- 肯定比完全自己写要强多了
- 调用工具很方便
- 解决了很多接口问题
- 缺点
- Langchain 太过复杂,以至于我不知道是我没用对,还是它就没有这个功能,学习成本高。
- Langchain 更新太快,很多之前的例程都不能用了。有时候找一个功能要花很长时间。
- 即使在一个版本中,工具调用也可做到不同层次,学习成本高。
- 框架逻辑复杂,为了一个小功能把 Agent 整个加进来,确实有点重。
- 虽然 Langchain 后期做了分块,但每个功能做得不够精细。
- 总结
- Agent 的主要用途是与用户进行更平滑的交互。
- 多数逻辑需要通过 Prompt 来处理。
- Langchain Agent 可以看作一个分流器,根据提供的工具,对用户意图进行分流。相对 Chain,它的数据流结构更为灵活。
- LangChain 提供的 Agent 更多用于处理单步任务和工具调用,不太适合复杂任务。
- 注意事项
- 不需要花太多时间彻底了解每个工具,理解其原理并能够使用即可。
- 不要将所有逻辑都写在里面,只需将 langchain 作为一个中间封装层,随时可替换。
- 思考
- 有效地解决了接口问题。原先实现功能需要明确定义,如函数名、参数类型等等。而现在通过 agent,可以有更大的功能调用余地和容错率。在对话中,只需用语言大致描述其功能,就能找到相应的函数进行调用,并以聊天形式返回给用户。
4 问题与解答
- 如何看具体步骤
- 如果想看具体步骤,用 stream 方式调用,整个输入输出都能保留,以方便追踪每步的结果。
- 便宜的模型能不能满足对工具的使用
- gpt-3.5 和 deepseek 都可用
- 用 gpt-4o 效果明显好于 gpt-3.5,后者很多时候会选错工具,需要花很多时间调 prompt。
- 工具的输入输出描述非常重要,不要只当注释写,如果与实现对不上,会影响结果。
- 提示词改一点都不行。
- 复杂功能能否实现
- langchain agent 有很多层次,只要做得足够低层,或者说选对自己合适的层次,理论上可以实现,但比较复杂。
- 一般的 prompt 怎么写,或者主要用哪个模板
- 这里不能像 demo 写的那么简单,尤其要把输出结果定义清楚,以使后续操作更加顺利。
- 叠加存储每一步的思考,不是只能存最后一步。
- 可参考 ReactAgent。
- agent 如何构造
- 有多种构造方法。
- langchain 是如何选择工具的
- openai 新 api 提供 tool 的接口,所以是通过 tools 参数直接把函数传给 openai,而不是组成 prompt 再传。
- 默认情况下,每一步 agent 与 llm 交互都把最后一次的结果和用户问题一起组装成 prompt 传给 llm。
- prompt 和函数描述尽量详细。
5 参考
5.1 工具文档
5.2 代理文档
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.