概述
Agent 是一种能够基于接收到的输入,利用自身的决策逻辑和可用的工具,动态地规划并执行一系列操作,以达成特定任务的程序或系统。它在与外界交互过程中,会根据实时情况灵活调整策略,而不是按照固定的预设流程执行任务。
核心组成部分
-
语言模型(LLM):作为 Agent 的“大脑”,负责理解用户的输入、生成推理和决策所需的文本信息。例如,当用户提出一个复杂的问题时,语言模型会对问题进行分析和理解。
-
工具:是 Agent 用于完成特定任务的具体手段。这些工具可以是各种 API 接口,如搜索引擎 API 用于获取外部信息、数学计算工具用于进行数值运算等。例如,当需要查询某一历史事件的具体时间时,Agent 可以调用搜索引擎工具来获取相关信息。
-
决策逻辑:决定何时以及如何使用工具。它会根据语言模型对输入的分析结果,结合工具的功能和描述,选择最合适的工具来解决问题。例如,如果用户的问题涉及到数据查询和数学计算,决策逻辑会先让 Agent 使用搜索引擎工具获取相关数据,再使用数学计算工具对数据进行处理
工作流程
-
接收输入:Agent 接收用户提出的任务或问题。例如,用户输入“查询苹果公司最新款手机的价格,并计算其在打 8 折后的售价”。
-
分析理解:语言模型对输入进行分析和理解,明确任务的核心目标和关键信息。在上述例子中,语言模型会识别出需要查询手机价格并进行折扣计算这两个关键任务。
-
决策规划:决策逻辑根据分析结果,确定完成任务所需的工具和操作步骤。在这个例子中,会先选择搜索引擎工具查询苹果公司最新款手机的价格,再选择数学计算工具计算打折后的售价。
-
执行操作:按照规划好的步骤,依次调用相应的工具执行任务。首先调用搜索引擎工具获取手机价格信息,然后将价格信息传递给数学计算工具进行打折计算。
-
输出结果:将最终的处理结果反馈给用户。在这个例子中,会将计算得出的打折后售价返回给用户。
工具
langchain_community.agent_toolkits提供了丰富多样的工具包,这些工具包可以帮助开发者更方便地构建功能强大的智能代理。
可以通过如下代码查询工具列表:
from langchain_community.agent_toolkits.load_tools import load_tools, get_all_tool_names#查询所有提供的工具
tool_names = get_all_tool_names()
print(tool_names)
1. 搜索与信息检索类
-
google-search
:用于在 Google 搜索引擎上进行搜索,获取互联网上广泛的信息。 -
google-search-results-json
:以 JSON 格式返回 Google 搜索的结果,方便后续数据处理和分析。 -
searx-search-results-json
:借助 Searx(一个元搜索引擎)进行搜索,并以 JSON 格式返回搜索结果。 -
bing-search
:在 Bing 搜索引擎上执行搜索操作,获取 Bing 索引的网页信息。 -
metaphor-search
:利用 Metaphor 搜索引擎进行搜索,可能在特定领域或搜索算法上有独特优势。 -
ddg-search
:使用 DuckDuckGo 搜索引擎进行搜索,DuckDuckGo 注重用户隐私,不跟踪用户搜索历史。 -
google-books
:专门用于搜索 Google 图书数据库,查找相关书籍信息。 -
google-scholar
:在 Google Scholar 上搜索学术文献、研究论文、学术书籍等学术资源。 -
google-finance
:用于获取 Google Finance 上的金融相关信息,如股票行情、财经新闻等。 -
google-trends
:从 Google Trends 获取搜索关键词的热度趋势数据,可用于分析市场趋势、话题热度等。 -
google-jobs
:搜索 Google Jobs 上的招聘信息,帮助用户查找工作机会。 -
google-serper
:通过 Serper API 进行 Google 搜索,可能提供更定制化的搜索服务。 -
google-serper-results-json
:以 JSON 格式返回通过 Google Serper 搜索得到的结果。 -
searchapi
:使用 SearchApi 进行搜索,可访问多种搜索引擎的功能。 -
searchapi-results-json
:以 JSON 格式返回 SearchApi 的搜索结果。 -
serpapi
:提供统一的 API 来访问多个搜索引擎(如 Google、Bing 等)的搜索结果,简化搜索集成。 -
wikipedia
:用于在维基百科上搜索信息,获取权威的百科知识。 -
arxiv
:搜索 arXiv 预印本数据库,获取科学研究领域的最新论文。 -
pubmed
:在 PubMed 数据库中搜索生物医学领域的文献。 -
reddit_search
:在 Reddit 平台上进行搜索,获取相关的社区讨论和内容。 -
news-api
:通过 News API 搜索和获取新闻文章,可用于新闻资讯聚合。
2. 计算与数据处理类
-
wolfram-alpha
:借助 Wolfram Alpha 强大的计算和知识引擎,进行各种数学计算、数据分析、科学知识查询等。 -
llm-math
:利用大语言模型进行数学计算,适合处理简单的数学问题。
3. 内容生成与媒体类
-
dalle-image-generator
:使用 DALL - E 模型生成图像,根据文本描述创建相应的图像。 -
eleven_labs_text2speech
:通过 Eleven Labs 的 API 将文本转换为语音。 -
google_cloud_texttospeech
:利用 Google Cloud 的文本转语音服务,将文本转换为自然流畅的语音。 -
sceneXplain
:可能用于图像理解和解释,对图像内容进行分析和描述。
4. 社交与通信类
-
twilio
:集成 Twilio 通信平台,可实现短信发送、语音通话、视频通话等通信功能。
5. 其他工具类
-
sleep
:使代理暂停执行一段时间,可用于控制流程的执行节奏。 -
human
:引入人类交互环节,在代理执行过程中可以向人类寻求帮助或获取信息。 -
awslambda
:与 AWS Lambda 函数集成,利用 AWS Lambda 的无服务器计算能力执行自定义代码。 -
stackexchange
:在 Stack Exchange 网络(如 Stack Overflow)上搜索问题和答案,获取技术领域的专业知识。 -
graphql
:用于执行 GraphQL 查询,与支持 GraphQL 的 API 进行交互。 -
openweathermap-api
:通过 OpenWeatherMap API 获取天气信息,如气温、湿度、天气状况等。 -
dataforseo-api-search
:使用 DataForSEO API 进行搜索相关操作。 -
dataforseo-api-search-json
:以 JSON 格式返回 DataForSEO API 搜索的结果。 -
memorize
:可能用于在代理执行过程中存储和记忆某些信息,方便后续使用。 -
read_file
:用于读取文件内容,可处理本地文件或远程文件。 -
tmdb-api
:与 The Movie Database(TMDB)API 集成,获取电影和电视节目相关信息。 -
podcast-api
:通过 Podcast API 搜索和获取播客相关信息。 -
open-meteo-api
:利用 Open Meteo API 获取气象数据。 -
requests
:使用 Python 的requests
库发送 HTTP 请求,可与各种 Web API 进行交互。 -
requests_get
:专门用于发送 HTTP GET 请求。 -
requests_post
:专门用于发送 HTTP POST 请求。 -
requests_patch
:专门用于发送 HTTP PATCH 请求。 -
requests_put
:专门用于发送 HTTP PUT 请求。 -
requests_delete
:专门用于发送 HTTP DELETE 请求。 -
terminal
:允许代理在终端环境中执行命令,例如运行脚本、调用系统工具等。 -
merriam-webster
:通过 Merriam - Webster 词典进行词汇查询,获取单词的释义、发音等信息。 -
golden-query
:用于与 Golden 知识图谱进行交互,查询相关的结构化知识。 -
terminal
:可在终端环境中执行命令,适用于执行本地脚本或系统命令。
加载工具:
from langchain_community.agent_toolkits.load_tools import load_tools, get_all_tool_names#加载工具 arxiv 用于搜索arxiv上的论文 llm-math让 LLM 执行数学计算任务(结合计算器)
tools = load_tools(["arxiv", "llm-math"], llm=deepseek_llm)
1 使用 initialize_agent
函数创建标准 Agent
initialize_agent
是 LangChain 中最常用的创建 Agent 的函数,它提供了一种简单的方式来初始化不同类型的 Agent。可以根据需要选择不同的 Agent 类型和工具。
Agent 类型
LangChain 提供了多种 Agent 类型
1. ZERO_SHOT_REACT_DESCRIPTION
-
含义:这是一种零样本学习的 Agent,在采取行动之前会进行推理步骤。所谓零样本学习,意味着该 Agent 不需要针对特定任务进行额外的训练,就可以根据工具的描述来使用工具解决问题。
-
工作原理:当接收到用户的输入时,它会先对问题进行推理分析,确定需要使用哪些工具以及如何使用这些工具,然后再执行相应的操作。例如,在面对一个需要查询数据并进行计算的问题时,它会先思考应该调用搜索引擎工具获取数据,再调用计算工具进行计算。
2. REACT_DOCSTORE
-
含义:同样是一种在行动前进行推理的零样本 Agent,但它可以访问一个文档存储库。这个文档存储库允许 Agent 查找与回答问题相关的信息。
-
工作原理:在处理问题时,它不仅会进行推理分析,还会利用文档存储库中的信息来辅助解决问题。例如,当用户询问关于某个历史事件的详细信息时,它可以在文档存储库中查找相关的历史文献、资料等,结合推理过程给出更准确的答案。
3. SELF_ASK_WITH_SEARCH
-
含义:这种 Agent 会将一个复杂的问题分解为一系列更简单的问题,然后使用搜索工具查找这些简单问题的答案,最终根据这些答案来回答原始的复杂问题。
-
工作原理:当接收到一个复杂问题时,它会首先分析问题的结构,将其拆分成多个简单的子问题。然后,依次使用搜索工具查找每个子问题的答案。最后,将这些子问题的答案整合起来,形成对原始复杂问题的回答。例如,对于“如何制作一道复杂的菜肴”这个问题,它可能会将其拆分为“这道菜需要哪些食材”“每种食材的处理方法”“烹饪的步骤和时间”等子问题,分别进行搜索并整合答案。
4. CONVERSATIONAL_REACT_DESCRIPTION
-
含义:从名称推测,这是一种适用于对话场景的 Agent,在行动前会进行推理。它能够在多轮对话中保持上下文的连贯性,根据之前的对话内容和当前的输入进行推理和行动。
-
工作原理:在对话过程中,它会维护对话历史,理解每一轮对话的上下文信息。当用户输入新的内容时,它会结合上下文进行推理分析,选择合适的工具和操作来做出回应。例如,在一个关于旅游规划的对话中,用户先询问了某个旅游景点的信息,之后又询问如何到达该景点,它会根据之前关于景点的对话内容,调用地图搜索工具等给出到达景点的路线建议。
5. CHAT_ZERO_SHOT_REACT_DESCRIPTION
-
含义:这是一种专为聊天场景设计的零样本 Agent,在行动前进行推理。它结合了零样本学习的能力和聊天场景的特点,能够在没有针对特定聊天任务进行训练的情况下,处理聊天中的各种问题。
-
工作原理:在聊天过程中,它会根据用户的输入进行推理,判断需要使用哪些工具来满足用户的需求。例如,在聊天中用户提到了想要了解某部电影的信息,它会推理出需要调用电影数据库 API 来获取相关信息。
6. CHAT_CONVERSATIONAL_REACT_DESCRIPTION
-
含义:这是一种针对聊天场景优化的、适用于多轮对话的 Agent,在行动前进行推理。它综合了聊天场景和多轮对话的特性,能够更好地处理复杂的聊天交互。
-
工作原理:在多轮对话中,它会持续跟踪对话的上下文,根据用户的最新输入和之前的对话历史进行推理分析。例如,在一个关于购物的聊天中,用户先询问了某类商品的价格,之后又询问该商品的优惠活动,它会结合之前关于价格的对话内容,调用电商平台的 API 来获取优惠信息。
7. STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION
-
含义:这是一种针对聊天模型优化的零样本反应 Agent,能够调用具有多个输入的工具。它在聊天场景中,即使面对需要多个参数输入的工具,也能准确地进行调用和处理。
-
工作原理:在聊天过程中,当遇到需要使用具有多个输入的工具时,它会根据工具的描述和用户的输入,准确地组织和提供所需的输入参数。例如,在一个关于旅游规划的聊天中,用户想要查询从一个城市到另一个城市的航班信息,它可以调用航班查询 API,并根据用户提供的出发地、目的地、出发时间等多个参数进行查询。
8. OPENAI_FUNCTIONS
-
含义:这是一种针对使用 OpenAI 函数进行优化的 Agent。OpenAI 提供了一些函数调用的机制,该 Agent 能够高效地利用这些函数来完成特定的任务。
-
工作原理:它会根据用户的输入和任务需求,调用 OpenAI 提供的相关函数。例如,在处理文本生成任务时,它可以调用 OpenAI 的文本生成函数,根据用户的要求生成符合特定风格和内容的文本。
9. OPENAI_MULTI_FUNCTIONS
-
含义:从名称推测,这是一种能够调用多个 OpenAI 函数的 Agent。它可以根据任务的复杂性,灵活地组合和调用多个 OpenAI 函数来完成任务。
-
工作原理:在面对复杂任务时,它会分析任务的需求,选择合适的多个 OpenAI 函数,并按照一定的顺序和逻辑进行调用。例如,在一个需要进行文本分析和生成的任务中,它可以先调用 OpenAI 的文本分析函数对输入文本进行分析,然后根据分析结果调用文本生成函数生成相关的回复。
示例1
from langchain.agents import initialize_agent, AgentType
from langchain_community.agent_toolkits.load_tools import load_tools, get_all_tool_names
from model.deepseek import deepseek_llm
#查询所有提供的工具
#tool_names = get_all_tool_names()
#print(tool_names)#加载工具 arxiv 用于搜索arxiv上的论文 llm-math让 LLM 执行数学计算任务(结合计算器)
tools = load_tools(["arxiv", "llm-math"], llm=deepseek_llm)agent = initialize_agent(tools,deepseek_llm,agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION, #使用的agent类型handle_parsing_errors=True, #如果解析报错继续verbose=True, #输出的信息不要太多
)resp = agent.invoke({"input": "人工智能领域最新的论文是什么?请问中文回答"})
print(resp)
示例2
create_react_agent
函数用于创建一个基于 ReACT(Reasoning + Acting in a Cycle)框架的智能代理(Agent)。ReACT 框架通过结合推理和行动,使得代理能够更好地与环境交互,完成复杂任务。
#Tavily 搜索工具
#搜索最多返回5条结果
import osfrom langchain import hub
from langchain.agents import create_react_agent
from langchain_core.prompts import PromptTemplate
from langchain_tavily import TavilySearchfrom model.deepseek import deepseek_llm
from model.guiji import guiji_llmos.environ['TAVILY_API_KEY'] = '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'
tavily_tool = TavilySearch(max_results=1)#定义工具集
tools = [tavily_tool]
template = '''尽你所能回答以下问题。你可以使用以下工具:
{tools}
使用以下格式:
问题:你必须回答的输入问题
思考:你应该始终思考要做什么
行动:要采取的行动,应该是 [{tool_names}] 中的一个
行动输入:行动的输入
观察:行动的结果
……(这个“思考/行动/行动输入/观察”可以重复 N 次)
思考:我现在知道最终答案了
最终答案:原始输入问题的最终答案
开始!
问题:{input}
思考:{agent_scratchpad}'''prompt = PromptTemplate.from_template(template)
#定义一个agent
agent = create_react_agent(llm=deepseek_llm,tools=tools,prompt=prompt
)resp = agent.invoke({"input": "请根据 ReAct 模板,逐步思考并提供关于 'langchain 中文教程' 的信息。","intermediate_steps": []
})
print(resp)
示例3
create_structured_chat_agent
是一个重要的函数,它用于创建具备结构化输出能力的聊天代理(Agent)。这个代理能够处理复杂的输入参数,并以结构化的形式输出结果,在面对复杂任务时表现出色。
LangSmith上提供了一些常用的提示词可以直接使用
使用方式:prompt = hub.pull("hwchase17/structured-chat-agent")
from langchain import hub
from langchain.agents import create_structured_chat_agent, AgentExecutor
from langchain_community.agent_toolkits.load_tools import load_tools
from langchain_core.tools import StructuredTool
from pydantic import BaseModel, Field
from langchain.agents import toolfrom model.deepseek import deepseek_llm"""
使用@tool装饰器定义一个搜索模拟工具
@tool装饰器可以将一个函数转换成一个工具
return_direct=True表示直接返回函数的结果,不需要再进行思考
args_schema=SearchInput表示输入的参数类型是SearchInput
"""
class SearchInput(BaseModel):keyword: str = Field(description="搜索的关键词")
@tool("这是一个搜索的工具", return_direct=True, args_schema=SearchInput)
def search(keyword: str) -> str:"""这是一个搜索电脑上的数据的工具"""return f'我是一个搜索工具{keyword}'"""
使用StructuredTool.from_function定义一个排序工具
StructuredTool.from_function可以将一个函数转换成一个工具
return_direct=True表示直接返回函数的结果,不需要再进行思考·
args_schema=SortToolInput表示输入的参数类型是SortToolInput
"""
def sort_num(numString: str):"""这是一个工具,对所有的数字排序"""return sorted(eval(numString))class SortToolInput(BaseModel):num: str = Field(description="搜索的关键词")#结构化工具
sort_tool = StructuredTool.from_function(func=sort_num,name='sort_tool',description='这是一个工具,对所有的数字排序',args_schema=SortToolInput,return_direct=True
)"""
使用StructuredTool.from_function定义一个计算字符串长度的工具
StructuredTool.from_function可以将一个函数转换成一个工具
return_direct=True表示直接返回函数的结果,不需要再进行思考
args_schema=ArgsInput表示输入的参数类型是ArgsInput
"""
class ArgsInput(BaseModel):a: str = Field(description="第一个字符串")b: str = Field(description="第二个字符串")def count_str(a: str, b: str) -> int:return len(a) + len(b)count_tool = StructuredTool.from_function(func=count_str,name='count_tool',description='这是一个工具,计算两个字符串的长度',args_schema=ArgsInput,return_direct=True
)
#加载官方工具 arxiv 用于搜索arxiv上的论文 llm-math让 LLM 执行数学计算任务(结合计算器)
tools = load_tools(["arxiv", "llm-math"], llm=deepseek_llm)
#自定义工具
tools = [search, sort_tool, count_tool] + tools
#使用提示器模版
prompt = hub.pull("hwchase17/structured-chat-agent")agent = create_structured_chat_agent(deepseek_llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True)
resp = agent_executor.invoke(# {"input": "‘bbccdd’的字符串长度加上‘abc’字符串长度是多少"}{"input": "最新关于ai的论文"}
)
print(resp)