今天咱们来聊一聊如何用LangChain框架构建一个功能强大的AI Agent。如果你已经有一定的Python基础,并且对LangChain有所了解,那么这篇教程将会帮助你更深入地掌握如何构建一个能够回答问题、搜索网络信息并记住对话历史的智能助手。废话不多说,直接进入正题吧!
一、环境境准备
首先,确保你已经安装了必要的库。如果还没有安装,可以通过以下命令安装:
pip install langchain langchain-openai langgraph
二、理解LangChain的基本概念
LangChain提供了一系列的工具和组件,可以帮助你快速构建复杂的对话系统。其中几个核心概念包括:
- Chains: 用于连接多个组件,形成一个处理流程。
- Agents: 能够执行特定任务的实体,可以调用不同的工具。
- Tools: 具体的功能模块,如搜索引擎、数据库查询等。
- Memory: 用于存储对话历史,使Agent能够记住之前的对话内容。
三、构建一个多功能Agent
我们将构建一个能够处理以下任务的Agent:
- 回答常见问题。
- 搜索天气信息。
- 记住对话历史并根据历史进行回应。
3.1 初始化项目
首先,创建一个新的Python文件,例如 langchain_agent.py
。
3.2 导入必要的库
from langchain_openai import ChatOpenAI
from langchain_community.tools.tavily_search import TavilySearchResults#外部搜索工具
from langchain_core.messages import HumanMessage
from langgraph.checkpoint.memory import MemorySaver #存储记忆
from langgraph.prebuilt import create_react_agent #反应式代理
import os
3.3 设置API密钥
确保你有一个OpenAI API密钥。将密钥设置为环境变量:
api_key=os.getenv("agicto_test_apikey")
api_url="https://api.agicto.cn/v1"
3.4 创建基本的对话链
llm = ChatOpenAI(
model="ERNIE-Speed-128K",
api_key=api_key,
base_url=api_url
)
3.5 添加搜索功能
我们将使用一个简单的天气搜索工具。
#下面函数返回2个结果,该函数自动调用在环境变量里预先设定好的TAVILY_API_KEY的值,
# 该api值需要在tavily.com网站中复制免费的api_key
search = TavilySearchResults(max_results=2)
tools = [search]
3.6 添加记忆功能
使用 MemorySaver来存储对话历史。
memory = MemorySaver()
config = {"configurable":{"thread_id":"abc123"}}
3.7 初始化Agent
将对话链、搜索工具和记忆功能组合在一起,创建一个Agent。
agent_executor = create_react_agent(llm,tools,checkpointer=memory)
3.8运行Agent
agent_executor.invoke({"messages":[HumanMessage(content="你好,我是木木,我住在阜阳")]},config)
results=agent_executor.invoke({"messages":[HumanMessage(content="我所在的地方今天风大吗")]},config)
print(result)
3.9 运行结果(包含思考过程,其中标红的为对话结果。)
{'messages': [HumanMessage(content='你好,我是小木子,我住在合肥', additional_kwargs={}, response_metadata={}, id='847303db-6f35-4991-9fec-0e9a1521c7c8'), AIMessage(content='你好,小木子!很高兴认识你。合肥是个很美丽的城市,有很多有趣的地方和美食。你最近有什么有趣的事情想分享吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 42, 'prompt_tokens': 90, 'total_tokens': 132, 'completion_tokens_details': None}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_04751d0b65', 'finish_reason': 'stop', 'logprobs': None}, id='run-0818099d-7ae7-4911-9369-cb61c532de4e-0', usage_metadata={'input_tokens': 90, 'output_tokens': 42, 'total_tokens': 132}), HumanMessage(content='我叫什么名字?我所在的地方今天风大吗', additional_kwargs={}, response_metadata={}, id='a4d6ff33-3a2e-4a02-bcd9-c421ac843191'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_BmOBqjYC2MiOHq0A2ncIgyHg', 'function': {'arguments': '{"query":"合肥天气"}', 'name': 'tavily_search_results_json'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 20, 'prompt_tokens': 151, 'total_tokens': 171, 'completion_tokens_details': None}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_d54531d9eb', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-af34943e-5a9f-4a0f-8993-6ff640979714-0', tool_calls=[{'name': 'tavily_search_results_json', 'args': {'query': '合肥天气'}, 'id': 'call_BmOBqjYC2MiOHq0A2ncIgyHg', 'type': 'tool_call'}], usage_metadata={'input_tokens': 151, 'output_tokens': 20, 'total_tokens': 171}), ToolMessage(content="HTTPError('400 Client Error: Bad Request for url: https://api.tavily.com/search')", name='tavily_search_results_json', id='f7cb5f29-0f95-4e09-aaac-dfd32999c302', tool_call_id='call_BmOBqjYC2MiOHq0A2ncIgyHg', artifact={}), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_CtcjIBJiMUhAoKpF2tNzNjGu', 'function': {'arguments': '{"query":"合肥今日风速"}', 'name': 'tavily_search_results_json'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 22, 'prompt_tokens': 204, 'total_tokens': 226, 'completion_tokens_details': None}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_04751d0b65', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-e9c9ad8a-e68c-480f-b801-0803ac2b4667-0', tool_calls=[{'name': 'tavily_search_results_json', 'args': {'query': '合肥今日风速'}, 'id': 'call_CtcjIBJiMUhAoKpF2tNzNjGu', 'type': 'tool_call'}], usage_metadata={'input_tokens': 204, 'output_tokens': 22, 'total_tokens': 226}), ToolMessage(content='[{"url": "https://tianqi.fliggy.com/340100/140900048-1", "content": "风速:15km/h. 相对湿度:88%rh. 合肥11月14日17:30天气预报,今天15℃-23℃,阴, 风向情况:东北风,总降水量:0.00mm,相对湿度:88%。合肥今日生活指数: 交通指数,良好"}, {"url": "https://tianqi.fliggy.com/340100/", "content": "风速:30km/h. 相对湿度:92%rh. 有大风, 蓝色警报 ... 风力不大,建议用中性保湿型霜类化妆品,无需选用防晒化妆品。周边城市今日天气预报 ... 合肥今日生活指数: 交通指数,"}]', name='tavily_search_results_json', id='a2b82634-f8f3-4ca4-a83e-571f8e262236', tool_call_id='call_CtcjIBJiMUhAoKpF2tNzNjGu', artifact={'query': '合肥今日风速', 'follow_up_questions': None, 'answer': None, 'images': [], 'results': [{'url': 'https://tianqi.fliggy.com/340100/140900048-1', 'title': '合肥鸡鸣山24 小时天气预报', 'content': '风速:15km/h. 相对湿度:88%rh. 合肥11月14日17:30天气预报,今天15℃-23℃,阴, 风向情况:东北风,总降水量:0.00mm,相对湿度:88%。合肥今日生活指数: 交通指数,良好', 'score': 0.998259, 'raw_content': None}, {'url': 'https://tianqi.fliggy.com/340100/', 'title': '【合肥天气预报】最新实时天气,合肥旅游指数/交通指数', 'content': '风速:30km/h. 相对湿度:92%rh. 有大风, 蓝色警报 ... 风力不大,建议用中性保湿型霜类化妆品,无需选用防晒化妆品。周边城市今日天气预报 ... 合肥今日生活指数: 交通指数,', 'score': 0.9972638, 'raw_content': None}], 'response_time': 3.84}), AIMessage(content='你叫小木子,今天合肥的风速大约在15km/h到30km/h之间,整体感觉有点风。气温在15℃到23℃之间,湿度较高,达到了88%。如果你有外出计划,可以适当注意风的影响哦!你还有其他想了解的内容吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 74, 'prompt_tokens': 435, 'total_tokens': 509, 'completion_tokens_details': None}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_04751d0b65', 'finish_reason': 'stop', 'logprobs': None}, id='run-fba56bf7-2ad8-4812-be2a-ea99a847afd3-0', usage_metadata={'input_tokens': 435, 'output_tokens': 74, 'total_tokens': 509})]}
通过以上步骤,你已经成功构建了一个能够回答问题、搜索天气信息并记住对话历史的AI Agent。