代理的高级用法
LangChain中的代理(Agents)是系统中最强大的组件之一,它们能够动态地调用各种工具,执行复杂的任务并与外部环境交互。在高级用法中,代理不仅仅用于简单的任务执行,还可以通过自定义代理策略、上下文管理、异步任务、以及多任务处理等方式,实现更复杂的场景。
1. 自定义代理策略
LangChain允许开发者自定义代理的决策策略,以控制代理如何调用工具并处理用户输入。默认情况下,LangChain代理基于“零次提示”(Zero-Shot Prompting)来推断使用哪些工具,但是在高级场景中,可以自定义这些决策。
自定义逻辑代理
例如,可以创建一个代理,它根据输入的关键词决定调用哪个工具:
from langchain.agents import AgentExecutor, Tool, LLMSingleActionAgent
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
# 定义工具
tools = [WeatherTool(), GitHubUserTool()]
# 自定义提示模板
template = """如果用户想要天气信息,请使用weather_tool。
如果用户想要GitHub信息,请使用github_user_tool。
用户说:“{input}”"""
prompt = PromptTemplate(input_variables=["input"], template=template)
# 自定义代理执行器
class CustomLLMAgent(LLMSingleActionAgent):
def plan(self, input_text: str) -> str:
# 基于输入文本选择工具
if "天气" in input_text:
return "weather_tool"
elif "GitHub" in input_text:
return "github_user_tool"
else:
return "无效输入"
llm = OpenAI(model_name="gpt-3.5-turbo")
# 初始化自定义代理
agent_executor = AgentExecutor.from_agent_and_tools(agent=CustomLLMAgent(llm), tools=tools)
# 运行代理
response = agent_executor.run("查询上海的天气")
print(response)
这种自定义策略让代理根据输入动态选择工具,而不依赖于语言模型自行推断。
2. 上下文管理与记忆
在更复杂的应用中,代理需要能够管理上下文,并记住用户的先前请求,以便在对话中维护状态。LangChain提供了Memory模块,允许代理在多轮交互中保存上下文信息。
使用记忆存储上下文
通过引入记忆,代理可以记住之前的对话状态,并根据之前的用户输入动态生成输出:
from langchain.memory import ConversationBufferMemory
from langchain.agents import initialize_agent
# 定义代理记忆
memory = ConversationBufferMemory(memory_key="chat_history")
# 初始化带有记忆的代理
agent = initialize_agent(llm=OpenAI(), tools=[WeatherTool()], memory=memory, agent_type="conversational")
# 运行多轮对话
response = agent.run("今天上海的天气如何?")
print(response)
response = agent.run("明天呢?")
print(response)
在此示例中,代理会记住用户先前询问的城市,并在后续的交互中自动接续相关的上下文。
3. 异步任务处理
当代理需要处理耗时的任务(如API请求或计算任务)时,异步处理可以提高响应速度。LangChain支持异步代理,使得代理可以同时执行多个任务,而不阻塞主进程。
异步代理使用示例
使用异步API请求工具来处理天气查询的例子:
import aiohttp
from langchain.agents import AsyncAgentExecutor
class AsyncWeatherTool(BaseTool):
async def _run(self, city: str):
api_key = "your_api_key"
url = f"http://api.weatherapi.com/v1/current.json?key={api_key}&q={city}"
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
if response.status == 200:
data = await response.json()
return f"{city}的天气是{data['current']['condition']['text']},气温为{data['current']['temp_c']}度。"
return "无法获取天气信息。"
tools = [AsyncWeatherTool()]
# 初始化异步代理
async_agent = AsyncAgentExecutor(llm=OpenAI(), tools=tools)
# 异步运行代理
response = await async_agent.run("查询北京的天气")
print(response)
这种异步执行方式能够提升代理处理大批量任务时的性能。
4. 多任务处理与多工具协作
在某些情况下,代理需要同时调用多个工具来完成复杂的任务。LangChain允许代理在同一个执行流程中使用多个工具,这使得代理能够处理多任务,或将一个复杂任务分解为多个子任务。
多工具协作示例
以下是一个代理,首先获取天气信息,然后根据天气结果进行数学计算:
class CalculationTool(BaseTool):
def _run(self, expression: str):
return eval(expression)
tools = [WeatherTool(), CalculationTool()]
# 初始化代理
agent = initialize_agent(llm=OpenAI(), tools=tools, agent_type="zero-shot")
# 执行多任务处理
response = agent.run("查询上海的天气,并且计算 5 + 10")
print(response)
在这个示例中,代理会首先调用WeatherTool,然后调用CalculationTool来执行数学运算,实现多个工具的协作。
5. 动态代理与自我改进
高级代理可以根据执行结果动态调整其行为,甚至在某些场景下,自我改进或重新训练。通过动态加载新的工具、调整代理策略,代理可以在实际操作中变得更加智能和高效。
示例:动态加载工具
代理可以根据任务需要,动态加载新的工具模块:
class DynamicAgent(AgentExecutor):
def add_tool(self, tool):
self.tools.append(tool)
# 初始化动态代理
dynamic_agent = DynamicAgent(llm=OpenAI(), tools=[])
# 动态添加工具
dynamic_agent.add_tool(WeatherTool())
dynamic_agent.add_tool(CalculationTool())
# 执行任务
response = dynamic_agent.run("查询天气并计算 8 * 6")
print(response)
通过动态加载工具,代理可以在任务执行中灵活地扩展其功能。
6. 总结
代理的高级用法使LangChain不仅能够处理简单的工具调用,还能够处理复杂的任务逻辑、上下文管理、异步操作以及多任务处理。开发者可以根据应用需求自定义代理策略、集成记忆功能、实现异步任务,并通过多工具协作,构建出功能强大、灵活多变的代理系统。这些高级功能为构建复杂智能系统提供了强大的能力支持。
