智能体开发快速入门
第1节:智能体概述
1. 什么是智能体
关于智能体的定义,网上的说法总是云里雾里,我这里总结一个,对新手比较友好的解释:
智能体是可以自主规划任务和调用工具的应用程序
这里有两部分需要了解
自主规划任务
自主规划任务指的是:用户提出了一个要求,具体需要有那几步来完成任务,每一步具体做什么,都由智能体来规划。
调用工具
在执行任务的过程中,如果涉及到调用工具,智能体可以基于大模型的分析,自主调用工具,以便完成任务。
什么是自主规划任务和调用工具呢,举个例子:
例如我和智能体说:
下载昨天的新闻
智能体的执行步骤是:
- 调用新闻接口工具,获取昨天的新闻。
- 调用文件系统工具,将获取到的新闻保存到本地。
这就是智能体的功能,理解了些,就知道了智能体的基本概念。我们的这个文档目的,也是为了让大家可以独立开发这样的智能体。
2. 为什么需要智能体
有朋友看到这可能会想问,AI大模型不能调用工具和规划任务吗,为什么需要智能体来做这些呢。讨论这个问题,我们先从下面三个说说大模型的能力限制。
- 大模型没有记忆,只是一个问答机器人。
- 大模型反馈的内容,都是以文本形式呈现。
- 大模型不能感知外部环境,无法获取实时信息。
基于大模型能力的局限,我们就需要在大模型外部包裹一层应用程序,来扩充大模型的能力,这一层应用程序置于大模型与用户之间,作为一个代理(agent),成为了用户与大模型之间的桥梁,这就是智能体的作用。
3. 智能体开发工具
智能体开发工具分为低代码工具和代码框架,主流的低代码工具包括coze、dify、n8n等。代码框架包括LangChain,LangGraph,LlamaIndex等,我们本节教程主要使用LangChain框架进行智能体开发。
4. LangChain概述
LangChain可以让基于大模型的应用开发变得更简单。
langchain提供了哪些功能
- 接入大模型的快捷方法。
- 封装好的提示词面板
- 记忆功能
- 方便的工具调用方法
- 可以实现RAG的文档检索功能
了解了上面这五点,就可以开发自己的智能体了。
第2节:创建项目
1. 创建虚拟环境
开发智能体项目之前,为了防止项目依赖于电脑全局环境冲突,我们先创建一个虚拟环境。
创建虚拟环境
python -m venv .venv
激活虚拟环境
.venv\Scripts\activate
2. 安装依赖
激活虚拟环境后,下载langChain框架,以及必要的开发工具。
pip install langchain langchain-openai python-dotenv
- langchain:智能体开发框架
- langchain-openai:用来接入大模型
- python-dotenv:用.env文件存放大模型秘钥。
如果下载速度较慢,可以讲pip的下载地址更改为国内的镜像地址,修改方法我已经放在《常用工具使用手册》中,有需要的小伙伴可以到【晓舟的AI交流66群】获取文档资料。
第3节:接入大模型
要想在langchain中接入AI大模型,我们需要三个参数:
- API key
- 大模型名称
- 提供服务的地址
这里我们以DeepSeek为例, 先 访问DeepSeek 大模型官网 注册账号,然后在控制台创建一个API key,接着在DeepSeek文档中找到DeepSeek大模型的名称,以及提供服务的地址。
有了这三个参数,为了防止账号API key被盗用,我们还要创建一个.env
文件来存放API key。
然后使用dotenv
模块引入API key
示例代码如下
from dotenv import load_dotenv
import os
load_dotenv()
print(os.getenv("DEEPSEEK_MODEL"))
配置好API key,就可以接入大模型了,示例代码如下:
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os
load_dotenv()
llm = ChatOpenAI(
model=os.getenv("DEEPSEEK_MODEL"),
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url=os.getenv("DEEPSEEK_API_BASE")
)
prompt = "你是谁"
response = llm.invoke(prompt);
print(response.content)
如果自己编写的项目需要推送到Git仓库,要将.env
文件添加到你的 .gitignore
文件中,防止意外将 API Key 推送到线上。.gitignore文件如下
.venv/
.env
关于Git的使用方法,我已经写在《常用工具使用手册》中,有需要的小伙伴可以到【晓舟的AI交流66群】获取。
到这里,运行程序,如果一切顺利,我们就可以看到DeepSeek大模型的回复了。
第4章:链与提示词
1. 链
上一节我们接入大模型之后,是通过下面的方式给AI输入提示词的
prompt = "你是谁"
response = llm.invoke(prompt);
print(response.content)
在实际开发中,为了让提示词更加灵活,我们会把提示词写在一个提示词模板组件中,示例代码如下
# 引入提示词模板
from langchain.prompts import ChatPromptTemplate
# 创建一个提示词模板组件
prompt = ChatPromptTemplate("你是谁?")
关于提示词模板,我们一会儿细说,这里先讲“链”的概念。
langchian中的“链”,示例代码如下:
chain = prompt | llm
response = chain.invoke({})
print(response.content)
代码中的chain = prompt | model
是就是“链”。
在 LangChain 中,链可以将多个组件组合起来,按特定顺序执行,以完成更复杂任务的逻辑单元。这是LangChain的表达式语言 ,简称LCEL
LCEL 的核心是 |
(管道) 操作符,类似于 Unix/Linux 中的管道命令。它允许我们将一个组件的返回值向下传递给下一个组件作为输入。
基本语法:
chain = component_A | component_B | component_C
chain.invoke({"parm":"value"})
这表示:
- 将
{"parm":"value"}
传递给component_A
。 component_A
的输出作为输入传递给component_B
。component_B
的输出作为输入传递给component_C
。chain
在调用invoke方法后,返回值就是component_C
的输出。 这就是langchain中“链”的使用方法。
因此示例代码chain = prompt | model
的作用是当执行chain.invoke()
的时候,把一个空字典传递给提示词模板,然后再传递给大模型,最后获取大模型的返回值。这样,我们就成功拿到了达摩习惯你的返回结果。
2. 提示词模板
了解了链的概念之后,我们接着看提示词模板,可以在ChatPromptTemplate
方法中进一步划分系统提示词和用户提示词。系统提示词用来设置提问的背景,用户提示词用来描述具体问题。示例代码如下:
prompt = ChatPromptTemplate([
("system", "你是一个擅长心理学的学习助手,帮我用心理学的理论知识解决我学习过程中的困惑"),
("user", "我为什么学习不好?")
])
chain = prompt | llm
response = chain.invoke({})
print(response.content)
可以看到,大模型按照要求给我们回复了内容。
我们还可以通过langchain提示词模板提供的语法来传递参数,示例代码如下:
prompt = ChatPromptTemplate([
("system", "你是一个擅长心理学的学习助手,帮我用心理学的理论知识解决我学习过程中的困惑"),
("user", "{input}")
])
chain = prompt | llm
response = chain.invoke({"input": "我为什么学习不好"})
print(response.content)
这样用户就可以向大模型输入自定义的问题了。
这里ChatPromptTemplate
的参数是一个又元组
组成的列表
,元组
只能存放两个参数,第一个是角色
,第二个是提示词
,如果多余两个参数langchain会报错。
第5章:解析器
在开发智能体的过程中,我们可能希望通过大模型,得到指定格式的数据,例如字符串,布尔, JSON等。解析器 (Output Parsers) 的作用就是将输出结果转化为我们期望的格式。
1. 解析为字符串
在之前的代码,我们使用response.content
来获取大模型的返回。
prompt = "你是谁"
response = llm.invoke(prompt);
print(response.content)
为了更方便地获取返回字符串,我们可以用一个解析器将返回的response
直接解析成字符串,核心代码如下:
from langchain_core.output_parsers import StrOutputParser
prompt = ChatPromptTemplate([
("system", "你是一个擅长心理学的学习助手,帮我用心理学的理论知识解决我学习过程中的困惑"),
("user", "{input}")
])
chain = prompt | llm | StrOutputParser();
response = chain.invoke({"input": "我为什么学习不好"})
print(response)
流式输出内容
我们拿到的字符串也可以通过流式输出的形式展现给用户,就像我们使用AI聊天机器人一样。输出内容的示例代码如下:
for chunk in chain.stream({}):
print(chunk,end="",flush=True)
end=""
参数的作用是:默认情况下,print()
会在结尾添加换行符\n
,设置end=""
后,不会添加换行符,使下一个 chunk 继续在同一行输出。 flush=True
参数的作用是:默认情况下,输出会有缓冲区,内容不会立即显示,设置flush=True
强制立即将内容输出到终端。
2. 解析为布尔值
BooleanOutputParser
解析器可以讲结果解析为布尔值,但是需要注意的是,我们需要在提示词里要求大模型返回的结果是“yes”或“no”,否则程序运行会出现异常。
from langchain.output_parsers.boolean import BooleanOutputParser
prompt = ChatPromptTemplate([
("system", "你来判断这个人是否适合结婚,请用yes或no回答"),
("user", "{input}")
])
parser = BooleanOutputParser();
chain = prompt | llm | parser
response = chain.invoke(
#{"input": "脾气差,人品差,不顾家,收入低"}
{"input": "脾气好,人品好,热爱生活,收入高"}
)
print(response)
3. 解析为json格式
下面的代码可以将返回的结果解析为json格式。
from langchain_core.output_parsers.json import JsonOutputParser
prompt = ChatPromptTemplate([
("system", "你是一个格式转换助手,将我输入的内容转换为JSON格式。"),
("human", "请将以下内容转换为JSON格式:{input}")
])
parser = JsonOutputParser();
chain = prompt | llm | parser
response = chain.invoke(
{"input": "我是晓舟,是一名程序员"}
)
print(response)
输出结果:
{'name': '晓舟', 'profession': '程序员'}
第6章:工具调用
文档最开始说过,智能体是可以自主规划任务和调用工具的应用程序,那么智能体到底要如何调用工具呢,我们分别讲解自定义工具和内置工具的使用方法。
1. 自定义工具
使用@tool
装饰器,可以将一个函数包装成一个langchain的工具,工具需要编写文档字符串,来说明工具所需的参数以及返回值,这部分文档字符串是用来让大模型识别工具用的,所以一定要编写清楚,否则大模型不能成功调用工具。
下面的代码我们定义了两个工具,一个用来计算加法,一个用来计算减法。
from langchain_core.tools import tool
@tool("AddNumbers") # 工具名称
def add_numbers(a: float, b: float) -> float:
"""计算两个数字的和。输入应为两个数字(如:{'a': 3, 'b': 5})"""
return a + b
@tool("SubtractNumbers")
def subtract_numbers(a: float, b: float) -> float:
"""计算两个数字的差(a减b)。输入应为两个数字(如:{'a': 10, 'b': 3})"""
return a - b
result = add_numbers.invoke({"a": 5, "b": 4})
result = subtract_numbers.invoke({"a": 5, "b": 4})
print(result)
虽然工具被成功调用,但是大家发现,这个工具的调用和普通函数的调用没区别,那么,如何让智能体按照用户的要求,自行调用工具呢。
这就需要使用langchain的agent组件,创建和调用使用agent组件的方式入下面代码所示:
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts.chat import MessagesPlaceholder
@tool("AddNumbers") # 工具名称
def add_numbers(a: float, b: float) -> float:
"""计算两个数字的和。输入应为两个数字(如:{'a': 3, 'b': 5})"""
return a + b
@tool("SubtractNumbers")
def subtract_numbers(a: float, b: float) -> float:
"""计算两个数字的差(a减b)。输入应为两个数字(如:{'a': 10, 'b': 3})"""
return a - b
tools = [add_numbers, subtract_numbers]
prompt = ChatPromptTemplate([··
("system", "你是一个能使用工具的助手。根据问题判断是否需要调用工具,如需调用,严格按照工具要求的格式传递参数。"),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad")
])
agent = create_tool_calling_agent(
llm=llm,
tools=tools,
prompt=prompt
)
agent_executor = AgentExecutor.from_agent_and_tools(
agent=agent,
tools=tools,
verbose=True
)
result = agent_executor.invoke({"input": "计算10加上20的结果"})
print(result)
上面的代码需要注意一下几点:
- 工具需要存放在一个
tools
列表中,方便后续传递给agent
- 提示词需要传入一个
agent_scratchpad
,它的作用是在agent
运行过程中,记录自己的思考步骤、中间结果和工具调用过程。 create_tool_calling_agent
的作用是初始化一个agent
。AgentExecutor
是agent
执行器,它负责指挥agent
调用工具并解决问题,verbose=True
参数的作用是“在终端显示调用过程”,方便调试。
可以看到这个例子中,如果我们说的是计算加法,agent就会自动调用加法工具,如果我们说的是计算减法,agent就会自动调用减法工具。这实现了智能体的基本功能。
2. langchain内置工具
在开发智能体的过程中,大部分工具是不用我们手动编写的,LangChain 提供了许多可以直接使用的内置工具,通常在 langchain_community.tools中。使用工具需要先安装依赖:
pip install langchain-community
这里是langchain的工具文档,如果有工具使用需求,可以参考文档内容自行调用。
下面以一个“文件系统”工具为例写一个案例,让文件系统工具来操作本地文件
from langchain_community.agent_toolkits import FileManagementToolkit
tookKit = FileManagementToolkit(
root_dir = "D:/test"
)
tools = tookKit.get_tools();
prompt = ChatPromptTemplate([
("system", "你是一个智能体,帮我调用工具。"),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad")
])
response = agent_executor.invoke({
"input":"请创建一个名为'notes.txt'的文件,并在其中写入'这是我的笔记:今天天气晴朗,适合散步。'"
})
print(response)
在FileManagementToolkit
我们定义了D:/test
为智能体可以操作的文件目录,这里斜杠的方向别写错了,tookKit.get_tools()
方法返回一个工具列表。
定义文件和获取工具列表之后,其他的操作就和上面的案例相同了,只要我们对智能体说出文件操作的要求,智能体就会通过FileManagementToolkit
工具操作本地文件。
总结
本节内容我们通过langchain的核心组件和功能,讲解了智能体开发的快速入门流程。后续晓舟还会持续更新智能体开发文档和案例。
大家可以在抖音【晓舟报告】首页加入【晓舟的AI交流66群】,一起交流技术问题,并获取更多学习资料。
最后祝大家早日富可敌国,【晓舟的直播时间是】工作日中午12:00,抖音直播间见啦,拜拜~