当前位置: 首页 > news >正文

【AI-agent】LangChain开发智能体工具流程

目录

  • 1 智能体开发流程概述
  • 2 使用LangChain调用大模型
    • 2.1 大模型实例化
    • 2.2 初始化提示词模板
      • 2.2.1 文本提示词模板PromptTemplate
      • 2.2.2 聊天提示词模板ChatPromptTemplate
      • 2.2.3 提示词及消息体的抽象复用
      • 2.2.4 少样本提示词模板FewShotPromptTemplate
      • 2.2.5 常用提示词模板类特性及使用场景对比
    • 2.3 链式调用大模型
  • 3 自定义工具
    • 3.1 绑定自定义工具流程
    • 3.2 tool装饰器注册工具及使用args_schema控制工具入参
  • 写在最后


1 智能体开发流程概述

开发一个智能体,本质上就是让AI具备"思考-行动-反馈"的循环能力。简单来说,我们需要让AI能够:

  1. 调用大模型进行推理(包含合适的提示词模板)
  2. 使用各种工具(比如搜索、计算、文件操作等)
  3. 根据结果做出决策,然后继续执行下一步操作

在这里插入图片描述
下面,我们将从“查询城市天气”的例子出发,看下如何使用LangChain开发一个简单的智能体

2 使用LangChain调用大模型

2.1 大模型实例化

使用 LangChain 实例化大模型,并将 api_key 使用 Pydantic 的 SecretStr 类型加密。其中,Pydantic 是一个基于 Python 类型注解的数据验证库,主要用于确保数据符合预期的格式和类型。

from langchain_openai import ChatOpenAI
import os
from dotenv import load_dotenv
from pydantic import SecretStr# 加载.env文件中的环境变量
load_dotenv()llm = ChatOpenAI(model="qwen-flash",base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",api_key=SecretStr(os.getenv("DASHSCOPE_API_KEY")),streaming=True
)print(llm)

在这里插入图片描述

2.2 初始化提示词模板

示例如下:

from langchain_core.prompts import ChatPromptTemplateprompt = ChatPromptTemplate.from_prompt([("system", "你是一名经验丰富的Python开发工程师, 名字叫小黄"),("human", "{user_input}")
])

2.2.1 文本提示词模板PromptTemplate

PromptTemplate 是 LangChain 框架中的核心组件,用于结构化和管理与语言模型交互的提示文本。它通过模板化的方式动态生成提示,支持变量插入和格式化。

适用场景:

  • 用于文本补全模型,输入是纯文本
  • 适用于简单的任务,如生成一段文本、回答问题或执行指令

特点:

  • 输入变量插值:通过{}占位符动态替换变量
  • 模板格式:支持f-string
  • 输出形式:生成一个完整的字符串作为模型输入

示例代码:

from langchain_core.prompts import PromptTemplate# 创建提示词模板
prompt_template = PromptTemplate.from_template("你做的{something}真棒!")
# 模板 -> 提示词
prompt = prompt_template.format(something="程序")
print(prompt)

结合之前实例的大模型,传入生成的prompt就能实现如下效果:
在这里插入图片描述

2.2.2 聊天提示词模板ChatPromptTemplate

ChatPromptTemplate 是 LangChain 中专门用于 多轮对话场景 的提示模板,支持定义 角色(Role) 和 消息类型(Message),适用于构建聊天机器人、对话系统等需要上下文交互的应用。

适用场景:

  • 用于聊天模型(ChatGPT等),输入是多轮对话的消息列表(SystemMessage、HumanMessage、AIMessage等)
  • 适用于需要模拟多轮对话和角色扮演的场景

特点:

  • 多消息类型支持:可以组合系统指令、用户输入和助手回复
  • 消息格式化:生成结构化的消息列表,供聊天模型处理
  • 使用灵活:支持动态替换变量(如SystemMessage中的占位符)

示例代码:

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
import os
from dotenv import load_dotenv
from pydantic import SecretStr# 加载.env文件中的环境变量
load_dotenv()llm = ChatOpenAI(model="qwen-flash",base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",api_key=SecretStr(os.getenv("DASHSCOPE_API_KEY")),streaming=True
)# 创建提示词模板
chat_prompt_template = ChatPromptTemplate.from_messages([("system", "你是一位{role}专家, 擅长解决{domain}领域的问题"),("user", "用户的问题:{question}")
])
# 模板 -> 提示词
prompt = chat_prompt_template.format_messages(role="Python编程",domain="AI-agent开发",question="如何创建一个简单的智能体?")
# 输入给AI模型, 获取结果
resp = llm.stream(prompt)
for chunk in resp:print(chunk.content, end="")

在这里插入图片描述

2.2.3 提示词及消息体的抽象复用

通过 ChatPromptTemplate 和 ChatMessagePromptTemplate 实现对消息体的抽象和复用。

示例代码:

from langchain_core.prompts import ChatPromptTemplate, ChatMessagePromptTemplate
from langchain_openai import ChatOpenAI
import os
from dotenv import load_dotenv
from pydantic import SecretStr# 加载.env文件中的环境变量
load_dotenv()llm = ChatOpenAI(model="qwen-flash",base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",api_key=SecretStr(os.getenv("DASHSCOPE_API_KEY")),streaming=True
)# 系统消息模板
system_message_template = ChatMessagePromptTemplate.from_template(template="你是一位{role}专家, 擅长解决{domain}领域的问题",role="system"
)
# 用户消息模板
human_message_template = ChatMessagePromptTemplate.from_template(template="用户的问题:{question}",role="user"
)
# 创建提示词模板
chat_prompt_template = ChatPromptTemplate.from_messages([system_message_template,human_message_template
])
# 模板 -> 提示词
prompt = chat_prompt_template.format_messages(role="Python编程",domain="AI-agent开发",question="如何创建一个简单的智能体?")
# 输入给AI模型, 获取结果
resp = llm.stream(prompt)
for chunk in resp:print(chunk.content, end="")

2.2.4 少样本提示词模板FewShotPromptTemplate

适用场景:

  • 用于少样本学习,在提示词中包含示例,帮助模型理解任务
  • 适用于复杂任务(翻译、分类、推理等),需要引入来引导模型行为

特点:

  • 示例嵌入:通过 examples 参数提供示例输入和输出
  • 动态示例选择:支持 ExampleSelector 动态选择最相关的示例
  • 模板格式:通常包含前缀(Prefix)、示例(Examples)和后缀(Suffix)

示例代码:

from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate
from langchain_openai import ChatOpenAI
import os
from dotenv import load_dotenv
from pydantic import SecretStr# 加载.env文件中的环境变量
load_dotenv()llm = ChatOpenAI(model="qwen-flash",base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",api_key=SecretStr(os.getenv("DASHSCOPE_API_KEY")),streaming=True
)# 示例模板
example_template = "输入:{input}\n输出:{output}"# 示例
examples = [{"input": "将'你好'翻译成英文", "output": "Hello"},{"input": "将'好的'翻译成英文", "output": "Ok"}
]# 少样本提示词模板
few_shot_prompt_template = FewShotPromptTemplate(examples=examples,example_prompt=PromptTemplate.from_template(example_template),prefix="请将下面的中文翻译为英文:",suffix="输入:{text}\n输出:",input_variables=["text"]
)prompt = few_shot_prompt_template.format(text="我热爱编程")
# print(prompt)resp = llm.stream(prompt)
for chunk in resp:print(chunk.content, end="")

上述代码中传给llm的prompt如下:
请将下面的中文翻译为英文:
输入:将’你好’翻译成英文
输出:Hello
输入:将’好的’翻译成英文
输出:Ok
输入:我热爱编程
输出:

以下是调用llm后返回的结果,可以看到llm根据example进行了少样本学习,直接返回了翻译的结果。
在这里插入图片描述

2.2.5 常用提示词模板类特性及使用场景对比

子类适用模型类型输入类型主要用途
PromptTemplate文本补全模型单字符串生成单轮文本任务提示
ChatPromptTemplate聊天模型多消息列表模拟多轮对话或角色扮演
FewShotPromptTemplate所有模型包含示例的模板通过示例引导模型完成复杂任务

2.3 链式调用大模型

链式调用大模型(Chained LLM Invocation)是指将多个大模型相关的操作或组件通过某种连接方式串联起来,形成一个处理管道或工作流。这种模式允许数据在不同的处理阶段之间流动,每个阶段对数据进行特定的转换或处理。

链式调用的特点:

  • 模块化设计:将复杂任务分解为多个独立的处理模块
  • 数据流驱动:数据在各个组件之间顺序流动和处理
  • 可组合性:可以灵活地组合不同的组件来构建不同的处理流程
  • 可读性强:代码表达清晰,易于理解和维护

以下两段代码等价:

chain = few_shot_prompt_template | llm
resp = chain.stream(input={"text": "你好"})
# 等价于以下步骤:
prompt = few_shot_prompt_template.format()  # 生成提示词
resp = llm.invoke(prompt)  

在表达式 chain = few_shot_prompt_template | llm 中,管道符 | 的作用是连接两个组件,形成数据流管道。数据流向 few_shot_prompt_template → | → llm → chain

链式调用代码示例:

from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate
from langchain_openai import ChatOpenAI
import os
from dotenv import load_dotenv
from pydantic import SecretStr"""使用langchain链式调用大模型"""
# 加载.env文件中的环境变量
load_dotenv()llm = ChatOpenAI(model="qwen-flash",base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",api_key=SecretStr(os.getenv("DASHSCOPE_API_KEY")),streaming=True
)# 示例模板
example_template = "输入:{input}\n输出:{output}"# 示例
examples = [{"input": "将'你好'翻译成英文", "output": "Hello"},{"input": "将'好的'翻译成英文", "output": "Ok"}
]# 少样本提示词模板
few_shot_prompt_template = FewShotPromptTemplate(examples=examples,example_prompt=PromptTemplate.from_template(example_template),prefix="请将下面的中文翻译为英文:",suffix="输入:{text}\n输出:",input_variables=["text"]
)chain = few_shot_prompt_template | llm
resp = chain.stream(input={"text": "你好"})for chunk in resp:print(chunk.content, end="")

3 自定义工具

3.1 绑定自定义工具流程

在第二章,我们了解了大模型实例,以及如何设计提示词,仅仅只实现了与大模型"对话",如果想让大模型帮助我们解决问题,还有至关重要的一步:将自定义工具与大模型绑定,让大模型了解工具的使用。主要有如下五个步骤:

  1. 开发工具方法
  2. 将工具方法转为LangChain Tool对象
  3. 将大模型与Tool对象绑定
  4. 调用大模型,尝试让大模型调用工具
  5. 调用工具

示例代码:

from langchain_core.tools import Tool
from app.bailian.common import chat_prompt_template, llm"绑定自定义工具"# 1.开发自定义工具
def fetch_weather(city: str) -> str:"""获取某个城市的真实天气"""# 模拟调用天气API逻辑...weather_data = {'北京': '多云','深圳': '晴朗'}if city not in weather_data.keys():return '天气多变'return weather_data[city]# 2.将工具方法转为LangChain Tool对象
fetch_weather_tool = Tool.from_function(func=fetch_weather,  # 与工具方法关联name='fetch_weather',  # 工具名, 唯一description='获取某个城市的真实天气',  # 工具说明
)
# 定义工具字典, value为python方法
tool_dict = {'fetch_weather': fetch_weather
}
# 3.将大模型与Tool对象绑定
llm_with_tool = llm.bind_tools([fetch_weather_tool])
# 链式声明
chain = chat_prompt_template | llm_with_tool
# 4.调用大模型
resp = chain.invoke(input={"role": "气象学", "domain": "天气领域", "question": "深圳天气怎么样?"})
print(resp)  # content='' additional_kwargs={} response_metadata={'finish_reason': 'tool_calls', 'model_name': 'qwen-flash', 'model_provider': 'openai'} id='lc_run--22c45fc8-81dd-49dc-bdea-aa7ef5288321' tool_calls=[{'name': 'fetch_weather', 'args': {'__arg1': '深圳'}, 'id': 'call_5bea195addc242cbafc984', 'type': 'tool_call'}]
# 5.调用工具
for tool_calls in resp.tool_calls:print(tool_calls)  # {'name': 'fetch_weather', 'args': {'__arg1': '深圳'}, 'id': 'call_a74fe41dae4d4b85a69ddb', 'type': 'tool_call'}args = tool_calls["args"]print(args)  # {'__arg1': '深圳'}func_name = tool_calls["name"]print(func_name)  # fetch_weathertool_func = tool_dict[func_name]tool_content = tool_func(args["__arg1"])print(tool_content)  # 晴朗

在这里插入图片描述
在上述代码中,我们粗略实现了绑定自定义工具的流程。在示例中,我们定义了一个简单的查询城市天气的方法,并将方法与大模型绑定。而后,我们向大模型提问:“深圳天气怎么样?”,大模型返回了使用工具的方法:
content=‘’ additional_kwargs={} response_metadata={‘finish_reason’: ‘tool_calls’, ‘model_name’: ‘qwen-flash’, ‘model_provider’: ‘openai’} id=‘lc_run–d2285936-24b3-435d-aca6-d3fde28111e7’ tool_calls=[{‘name’: ‘fetch_weather’, ‘args’: {‘__arg1’: ‘深圳’}, ‘id’: ‘call_4d384d81ae1548b1bd2cbf’, ‘type’: ‘tool_call’}]
大模型通过问题,判断出该用什么工具、怎么用工具,并将该信息返回(tool_calls),说明最终使用工具解决问题的不是大模型而是Agent!: 通过大模型返回的信息中的tool_calls[‘args’]、tool_calls[‘name’],我们能提炼出解决问题该调用什么工具,传入什么参数。

3.2 tool装饰器注册工具及使用args_schema控制工具入参

上一节,粗略实现了llm调用自定义工具的流程,但还是有比较大的问题:

  1. 自定义工具方法参数没有类型规范
  2. 调用自定义工具时非常笨拙、粗糙,需要做一些类型转化、参数命名等,而我们更希望llm能帮我们处理这些问题

而这个需求,我们可以通过装饰器 @tool 装饰器实现:
@tool 是 LangChain 框架中的核心装饰器,用于将普通 Python 函数转换为大模型可以调用的工具(Tool),其主要作用如下:

  • 函数注册:将函数注册为大模型可调用的工具
  • 元数据提取:自动提取函数名、参数信息、文档字符串
  • 类型转换:将 Python 函数转换为 LangChain 的 Tool 对象

args_schema 是 @tool 装饰器的重要参数,用于定义工具参数的结构和验证规则,其主要作用如下:

  • 参数验证:确保传入参数符合预期格式
  • 类型安全:定义参数的数据类型和约束
  • 文档生成:为大模型提供清晰的参数说明
  • 默认值处理:支持参数默认值

使用示例如下:

from langchain.tools import tool
from pydantic import BaseModel, Fieldclass SearchInput(BaseModel):query: str = Field(description="搜索关键词")limit: int = Field(default=10, description="返回结果数量限制")@tool(args_schema=SearchInput)
def search_web(input_data: SearchInput) -> str:"""根据输入参数搜索网络信息"""return f"搜索结果: {input_data.query}, 限制: {input_data.limit}"

对于3.1中实现的demo,引入tool装饰器后,修改后的示例代码如下:

from langchain_core.tools import tool
from app.bailian.common import chat_prompt_template, llm
from pydantic import BaseModel, Field"绑定自定义工具-使用tool装饰器"class FetchWeatherInputArgs(BaseModel):city: str = Field(description="城市名称")# 1.开发自定义工具, 并注册tool
@tool(description="获取某个城市的真实天气",args_schema=FetchWeatherInputArgs
)
def fetch_weather(city: str) -> str:"""获取某个城市的真实天气"""# 模拟调用天气API逻辑...weather_data = {'北京': '多云','深圳': '晴朗'}if city not in weather_data.keys():return '天气多变'return weather_data[city]# 定义工具字典, value为python方法
tool_dict = {'fetch_weather': fetch_weather
}
# 3.将大模型与Tool对象绑定
llm_with_tool = llm.bind_tools([fetch_weather])
# 链式声明
chain = chat_prompt_template | llm_with_tool
# 4.调用大模型
resp = chain.invoke(input={"role": "气象学", "domain": "天气领域", "question": "深圳天气怎么样?"})
# 5.调用工具
for tool_calls in resp.tool_calls:# 获取要调用的参数和工具args = tool_calls["args"]func_name = tool_calls["name"]tool_func = tool_dict[func_name]# 调用工具tool_content = tool_func.invoke(args)print(tool_content)  # 晴朗

写在最后

本文已被专栏 AI agent实战开发 收录,欢迎 点击订阅专栏
 以上便是本文的全部内容啦!创作不易,如果你有任何问题,欢迎私信,感谢您的支持!

在这里插入图片描述

http://www.dtcms.com/a/585605.html

相关文章:

  • 测量为什么要建站本地广东中山网站建设
  • 数据结构与算法:树上倍增与LCA
  • P1997 faebdc 的烦恼+P7764 [COCI 2016/2017 #5] Poklon(莫队)
  • Nginx请求超时
  • 基于单片机的交流功率测量仪设计与实现
  • Zookeeper实现分布式锁
  • 好看的个人网站设计专做轮胎的网站
  • VGG论文精细解读
  • 抖音自动化-实现给特定用户发私信
  • 安徽省教育基本建设学会网站查看网站被百度收录
  • LeetCode算法学习之旋转数组
  • webrtc降噪-NoiseSuppressor类源码分析与算法原理
  • openEuler容器化实践:从Docker入门到生产部署
  • Spring Security实战代码详解
  • ES6 Promise:告别回调地狱的异步编程革命
  • 企业网站备案教程免费建设网站抽取佣金
  • seo网站诊断流程公司网站建设费用会计处理
  • 与Figma AI对话的对话框在哪里?
  • 【科研绘图系列】R语言绘制微生物箱线图(box plot)
  • 禅城区网站建设管理网站模板下载免费下载
  • 前端微服务化
  • Linux 软件安装 “命令密码本”:yum/apt/brew 一网打尽
  • 做网站框架显示不出来中国最大的软件公司
  • 轻量级云原生体验:在OpenEuler 25.09上快速部署单节点K3s
  • 程序员 给老婆做网站网站建设 海南
  • 解释 StringRedisTemplate 类和对象的作用与关系
  • MATLAB遗传算法优化RVFL神经网络回归预测(随机函数链接神经网络)
  • 建设网站的知识竞赛国家建设网站
  • ROS2 Humble 笔记(七)标准与自定义 Interface 接口
  • 深入探索序列学习:循环神经网络(RNN)及其变体(LSTM、GRU)的详尽解析