目录
- [1 智能体开发流程概述](#1 智能体开发流程概述)
- [2 使用LangChain调用大模型](#2 使用LangChain调用大模型)
-
- [2.1 大模型实例化](#2.1 大模型实例化)
- [2.2 初始化提示词模板](#2.2 初始化提示词模板)
-
- [2.2.1 文本提示词模板PromptTemplate](#2.2.1 文本提示词模板PromptTemplate)
- [2.2.2 聊天提示词模板ChatPromptTemplate](#2.2.2 聊天提示词模板ChatPromptTemplate)
- [2.2.3 提示词及消息体的抽象复用](#2.2.3 提示词及消息体的抽象复用)
- [2.2.4 少样本提示词模板FewShotPromptTemplate](#2.2.4 少样本提示词模板FewShotPromptTemplate)
- [2.2.5 常用提示词模板类特性及使用场景对比](#2.2.5 常用提示词模板类特性及使用场景对比)
- [2.3 链式调用大模型](#2.3 链式调用大模型)
- [3 自定义工具](#3 自定义工具)
-
- [3.1 绑定自定义工具流程](#3.1 绑定自定义工具流程)
- [3.2 tool装饰器注册工具及使用args_schema控制工具入参](#3.2 tool装饰器注册工具及使用args_schema控制工具入参)
- 写在最后
1 智能体开发流程概述
开发一个智能体,本质上就是让AI具备"思考-行动-反馈"的循环能力。简单来说,我们需要让AI能够:
- 调用大模型进行推理(包含合适的提示词模板)
- 使用各种工具(比如搜索、计算、文件操作等)
- 根据结果做出决策,然后继续执行下一步操作

下面,我们将从"查询城市天气"的例子出发,看下如何使用LangChain开发一个简单的智能体
2 使用LangChain调用大模型
2.1 大模型实例化
使用 LangChain 实例化大模型,并将 api_key 使用 Pydantic 的 SecretStr 类型加密。其中,Pydantic 是一个基于 Python 类型注解的数据验证库,主要用于确保数据符合预期的格式和类型。
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 初始化提示词模板
示例如下:
python
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_prompt([
("system", "你是一名经验丰富的Python开发工程师, 名字叫小黄"),
("human", "{user_input}")
])
2.2.1 文本提示词模板PromptTemplate
PromptTemplate 是 LangChain 框架中的核心组件,用于结构化和管理与语言模型交互的提示文本。它通过模板化的方式动态生成提示,支持变量插入和格式化。
适用场景:
- 用于文本补全模型,输入是纯文本
- 适用于简单的任务,如生成一段文本、回答问题或执行指令
特点:
- 输入变量插值:通过{}占位符动态替换变量
- 模板格式:支持f-string
- 输出形式:生成一个完整的字符串作为模型输入
示例代码:
python
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中的占位符)
示例代码:
python
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 实现对消息体的抽象和复用。
示例代码:
python
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)
示例代码:
python
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)是指将多个大模型相关的操作或组件通过某种连接方式串联起来,形成一个处理管道或工作流。这种模式允许数据在不同的处理阶段之间流动,每个阶段对数据进行特定的转换或处理。
链式调用的特点:
- 模块化设计:将复杂任务分解为多个独立的处理模块
- 数据流驱动:数据在各个组件之间顺序流动和处理
- 可组合性:可以灵活地组合不同的组件来构建不同的处理流程
- 可读性强:代码表达清晰,易于理解和维护
以下两段代码等价:
python
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
链式调用代码示例:
python
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 绑定自定义工具流程
在第二章,我们了解了大模型实例,以及如何设计提示词,仅仅只实现了与大模型"对话",如果想让大模型帮助我们解决问题,还有至关重要的一步:将自定义工具与大模型绑定,让大模型了解工具的使用。主要有如下五个步骤:
- 开发工具方法
- 将工具方法转为LangChain Tool对象
- 将大模型与Tool对象绑定
- 调用大模型,尝试让大模型调用工具
- 调用工具
示例代码:
python
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_weather
tool_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调用自定义工具的流程,但还是有比较大的问题:
- 自定义工具方法参数没有类型规范
- 调用自定义工具时非常笨拙、粗糙,需要做一些类型转化、参数命名等,而我们更希望llm能帮我们处理这些问题
而这个需求,我们可以通过装饰器 @tool 装饰器实现:
@tool 是 LangChain 框架中的核心装饰器,用于将普通 Python 函数转换为大模型可以调用的工具(Tool),其主要作用如下:
- 函数注册:将函数注册为大模型可调用的工具
- 元数据提取:自动提取函数名、参数信息、文档字符串
- 类型转换:将 Python 函数转换为 LangChain 的 Tool 对象
args_schema 是 @tool 装饰器的重要参数,用于定义工具参数的结构和验证规则,其主要作用如下:
- 参数验证:确保传入参数符合预期格式
- 类型安全:定义参数的数据类型和约束
- 文档生成:为大模型提供清晰的参数说明
- 默认值处理:支持参数默认值
使用示例如下:
python
from langchain.tools import tool
from pydantic import BaseModel, Field
class 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装饰器后,修改后的示例代码如下:
python
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实战开发 收录,欢迎 点击订阅专栏
以上便是本文的全部内容啦!创作不易,如果你有任何问题,欢迎私信,感谢您的支持!
