LangChain 智能体(Agent)技术详解
1. 智能体类型(AgentType)概览
LangChain 中的 AgentType
是一个枚举类,定义了不同类型的智能体。每种智能体类型都有不同的使用场景、实现机制和提示词模板。
class AgentType(str, Enum):
"""智能体类型的枚举"""
ZERO_SHOT_REACT_DESCRIPTION = "zero-shot-react-description"
REACT_DOCSTORE = "react-docstore"
SELF_ASK_WITH_SEARCH = "self-ask-with-search"
CONVERSATIONAL_REACT_DESCRIPTION = "conversational-react-description"
CHAT_ZERO_SHOT_REACT_DESCRIPTION = "chat-zero-shot-react-description"
CHAT_CONVERSATIONAL_REACT_DESCRIPTION = "chat-conversational-react-description"
STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION = "structured-chat-zero-shot-react-description"
OPENAI_FUNCTIONS = "openai-functions"
OPENAI_MULTI_FUNCTIONS = "openai-multi-functions"
2. 关键智能体类型详解
2.1 ReAct 智能体 (ZERO_SHOT_REACT_DESCRIPTION)
实现机制
ReAct(Reasoning+Acting)是一种结合推理和行动的智能体类型,它让大语言模型先进行推理,再采取行动。
核心提示词
# ReAct 提示词示例
prompt_template = """Answer the following questions as best you can. You have access to the following tools:
{tools}
Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Begin!
Question: {input}
Thought:{agent_scratchpad}"""
关键代码实现
def create_react_agent(
llm: BaseLanguageModel,
tools: Sequence[BaseTool],
prompt: BasePromptTemplate,
output_parser: Optional[AgentOutputParser] = None,
tools_renderer: ToolsRenderer = render_text_description,
*,
stop_sequence: Union[bool, List[str]] = True,
) -> Runnable:
"""创建一个使用ReAct提示的智能体"""
# 验证提示词中是否包含必要的变量
missing_vars = {"tools", "tool_names", "agent_scratchpad"}.difference(
prompt.input_variables + list(prompt.partial_variables)
)
if missing_vars:
raise ValueError(f"Prompt missing required variables: {missing_vars}")
# 构建ReAct Agent
prompt = prompt.partial(
tools=tools_renderer(list(tools)),
tool_names=", ".join([t.name for t in tools]),
)
# 设置停止词,避免模型继续生成
if stop_sequence:
stop = ["\nObservation"] if stop_sequence is True else stop_sequence
llm_with_stop = llm.bind(stop=stop)
else:
llm_with_stop = llm
output_parser = output_parser or ReActSingleInputOutputParser()
# 构建RunninablePipeline
agent = (
RunnablePassthrough.assign(
agent_scratchpad=lambda x: format_log_to_str(x["intermediate_steps"]),
)
| prompt
| llm_with_stop
| output_parser
)
return agent
2.2 REACT_DOCSTORE 智能体
实现机制
这种智能体在ReAct基础上增加了文档存储功能,可以在推理过程中查询相关文档获取信息。
核心提示词
# REACT_DOCSTORE 提示词示例
prompt_template = """Answer the following questions as best you can. You have access to the following tools:
{tools}
Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Begin!
Question: {input}
Thought:{agent_scratchpad}"""
关键代码实现
def create_react_docstore_agent(
llm: BaseLanguageModel,
docstore: BaseDocumentStore,
tools: List[BaseTool],
prompt: BasePromptTemplate,
**kwargs
) -> AgentExecutor:
"""创建一个使用文档存储功能的ReAct智能体"""
# 创建文档检索工具
doc_retriever = DocstoreRetriever(docstore=docstore)
tools = tools + [
Tool(
name="Search",
func=doc_retriever.search,
description="搜索文档库中的信息"
),
Tool(
name="Lookup",
func=doc_retriever.lookup,
description="根据关键词查找文档库中的特定内容"
)
]
# 创建基础ReAct智能体
agent = create_react_agent(llm, tools, prompt)
# 创建智能体执行器
return AgentExecutor.from_agent_and_tools(
agent=agent,
tools=tools,
**kwargs
)
使用场景
适用于问题解答需要查询知识库或文档的场景,例如客服机器人、知识库问答等。
2.3 SELF_ASK_WITH_SEARCH 智能体
实现机制
这种智能体通过自问自答的方式分解复杂问题,通过搜索工具查找中间问题的答案,最终解决原始问题。
核心提示词
# SELF_ASK_WITH_SEARCH 提示词示例
prompt_template = """Question: {input}
To solve this question, I need to break it down into smaller questions that I can solve step by step.
{agent_scratchpad}"""
# 完整的自问自答格式示例
complete_example = """
Question: What is the hometown of the reigning men's U.S. Open champion?
To solve this question, I need to break it down into smaller questions that I can solve step by step.
Follow up: Who is the reigning men's U.S. Open champion?
Intermediate answer: The reigning men's U.S. Open champion is Carlos Alcaraz.
Follow up: What is Carlos Alcaraz's hometown?
Intermediate answer: Carlos Alcaraz's hometown is El Palmar, Murcia, Spain.
So the final answer is: El Palmar, Murcia, Spain
"""
关键代码实现
def create_self_ask_with_search_agent(
llm: BaseLanguageModel,
search_tool: BaseTool,
prompt: Optional[BasePromptTemplate] = None,
**kwargs
) -> AgentExecutor:
"""创建一个自问自答型智能体"""
# 默认提示词模板
if prompt is None:
prompt = PromptTemplate.from_template(prompt_template)
# 创建自问自答输出解析器
output_parser = SelfAskOutputParser()
# 创建搜索工具
tools = [search_tool]
# 创建自问自答智能体
agent = LLMSingleActionAgent(
llm_chain=LLMChain(llm=llm, prompt=prompt),
output_parser=output_parser,
stop=["Intermediate answer:"],
)
# 创建智能体执行器
return AgentExecutor.from_agent_and_tools(
agent=agent,
tools=tools,
**kwargs
)
2.4 CONVERSATIONAL_REACT_DESCRIPTION 智能体
实现机制
这种智能体在ReAct基础上增加了对话历史处理能力,适合多轮对话场景。
核心提示词
# CONVERSATIONAL_REACT_DESCRIPTION 提示词示例
prompt_template = """Assistant is a large language model trained by AI.
Assistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.
Assistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.
Overall, Assistant is a powerful tool that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.
TOOLS:
------
Assistant has access to the following tools:
{tools}
To use a tool, please use the following format:
Thought: Do I need to use a tool? Yes
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
When you have a response to say to the Human, or if you do not need to use a tool, you MUST use the format:
Thought: Do I need to use a tool? No
AI: [your response here]
Begin!
Previous conversation history:
{chat_history}
New input: {input}
{agent_scratchpad}"""
关键代码实现
def create_conversational_react_agent(
llm: BaseLanguageModel,
tools: List[BaseTool],
prompt: Optional[BasePromptTemplate] = None,
**kwargs
) -> AgentExecutor:
"""创建一个对话型ReAct智能体"""
# 默认提示词模板
if prompt is None:
prompt = ChatPromptTemplate.from_template(prompt_template)
# 创建对话型ReAct输出解析器
output_parser = ConversationalReactOutputParser()
# 创建聊天记忆
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
# 创建LLM链
llm_chain = LLMChain(
llm=llm,
prompt=prompt,
memory=memory
)
# 创建对话型ReAct智能体
agent = LLMSingleActionAgent(
llm_chain=llm_chain,
output_parser=output_parser,
stop=["\nObservation:"],
)
# 创建智能体执行器
return AgentExecutor.from_agent_and_tools(
agent=agent,
tools=tools,
memory=memory,
**kwargs
)
2.5 CHAT_ZERO_SHOT_REACT_DESCRIPTION 智能体
实现机制
这种智能体是为聊天模型优化的零样本 ReAct 智能体,更适合与 ChatGPT/Claude 等聊天模型配合使用。
核心提示词
# CHAT_ZERO_SHOT_REACT_DESCRIPTION 提示词示例
SYSTEM_MESSAGE_PREFIX = """You are a helpful AI assistant. I'll give you a task, and you will help me find an answer by thinking step by step.
You have access to the following tools:"""
SYSTEM_MESSAGE_SUFFIX = """When I ask you something, use the following format:
Thought: Think step-by-step about how to solve the problem.
Action: The action to take. Must be one of {tool_names}
Action Input: The input to the action
Observation: The result of the action
... (repeat this Thought/Action/Action Input/Observation multiple times if needed)
Thought: I have enough information to answer the question now.
Final Answer: The final answer to the original question
If you cannot find an answer, or are unsure, say so in the Final Answer.
Begin!"""
HUMAN_MESSAGE = "{input}"
关键代码实现
def create_chat_zero_shot_react_agent(
llm: BaseLanguageModel,
tools: List[BaseTool],
**kwargs
) -> AgentExecutor:
"""创建一个聊天优化的零样本ReAct智能体"""
# 构建提示词模板
system_message = SystemMessage(
content=(
f"{SYSTEM_MESSAGE_PREFIX}\n\n"
f"{format_tool_descriptions(tools)}\n\n"
f"{SYSTEM_MESSAGE_SUFFIX.format(tool_names=', '.join([tool.name for tool in tools]))}"
)
)
human_message = HumanMessagePromptTemplate.from_template(HUMAN_MESSAGE)
chat_prompt = ChatPromptTemplate.from_messages([
system_message,
MessagesPlaceholder(variable_name="chat_history"),
human_message,
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
# 创建聊天型ReAct输出解析器
output_parser = ReActSingleInputOutputParser()
# 设置LLM停止标记
llm_with_stop = llm.bind(stop=["Observation:"])
# 创建Runnable链
agent = (
RunnablePassthrough.assign(
agent_scratchpad=lambda x: format_chat_messages(x["intermediate_steps"])
)
| chat_prompt
| llm_with_stop
| output_parser
)
# 创建智能体执行器
return AgentExecutor.from_agent_and_tools(
agent=agent,
tools=tools,
**kwargs
)
2.6 CHAT_CONVERSATIONAL_REACT_DESCRIPTION 智能体
实现机制
这种智能体结合了对话能力和 ReAct 推理能力,专为聊天模型优化,适合长期对话场景。
核心提示词
# CHAT_CONVERSATIONAL_REACT_DESCRIPTION 提示词示例
CHAT_CONVERSATIONAL_REACT_DESCRIPTION_SYSTEM_MESSAGE = """Assistant is a large language model trained by AI.
Assistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.
Assistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.
Overall, Assistant is a powerful tool that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.
TOOLS:
------
Assistant has access to the following tools:
{tools}
To use a tool, please use the following format:
Thought: Do I need to use a tool? Yes
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
When you have a response to say to the Human, or if you do not need to use a tool, you MUST use the format:
Thought: Do I need to use a tool? No
AI: [your response here]
You must respond according to the previous conversation history and the Human's new input.
Begin!"""
# 聊天历史和用户输入的提示词
CHAT_CONVERSATIONAL_REACT_DESCRIPTION_HUMAN_TEMPLATE = """Previous conversation history:
{chat_history}
New input: {input}
{agent_scratchpad}"""
关键代码实现
def create_chat_conversational_react_agent(
llm: BaseLanguageModel,
tools: List[BaseTool],
**kwargs
) -> AgentExecutor:
"""创建一个聊天对话型ReAct智能体"""
# 构建提示词模板
system_message = SystemMessage(
content=CHAT_CONVERSATIONAL_REACT_DESCRIPTION_SYSTEM_MESSAGE.format(
tools=format_tool_descriptions(tools),
tool_names=", ".join([tool.name for tool in tools])
)
)
human_message = HumanMessagePromptTemplate.from_template(
CHAT_CONVERSATIONAL_REACT_DESCRIPTION_HUMAN_TEMPLATE
)
chat_prompt = ChatPromptTemplate.from_messages([
system_message,
human_message,
])
# 创建聊天对话型ReAct输出解析器
output_parser = ConversationalChatReActOutputParser()
# 设置LLM停止标记
llm_with_stop = llm.bind(stop=["Observation:"])
# 创建聊天记忆
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
# 创建Runnable链
agent = (
RunnablePassthrough.assign(
agent_scratchpad=lambda x: format_chat_messages(x["intermediate_steps"])
)
| chat_prompt
| llm_with_stop
| output_parser
)
# 创建智能体执行器
return AgentExecutor.from_agent_and_tools(
agent=agent,
tools=tools,
memory=memory,
**kwargs
)
2.7 STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION 智能体
实现机制
这种智能体在聊天模型上进行了优化,能够处理结构化工具输入,支持使用多参数工具。
核心提示词
# STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION 提示词示例
STRUCTURED_CHAT_SYSTEM_PREFIX = """You are a helpful AI assistant. I'll give you a task, and you will help me find an answer by thinking step by step.
You have access to the following tools:"""
STRUCTURED_CHAT_SYSTEM_SUFFIX = """When I ask you something, use the following format:
Thought: Think step-by-step about how to solve the problem.
Action: The action to take. Must be one of {tool_names}
Action Input: A valid JSON object with the required parameters for the action. The JSON should be well-formed and ready to be parsed.
Observation: The result of the action
... (repeat this Thought/Action/Action Input/Observation multiple times if needed)
Thought: I have enough information to answer the question now.
Final Answer: The final answer to the original question
If you cannot find an answer, or are unsure, say so in the Final Answer.
Begin!"""
STRUCTURED_CHAT_HUMAN_MESSAGE = "{input}"
关键代码实现
def create_structured_chat_agent(
llm: BaseLanguageModel,
tools: List[BaseTool],
**kwargs
) -> AgentExecutor:
"""创建一个结构化聊天零样本ReAct智能体"""
# 格式化工具描述(包含JSON架构)
tool_descriptions = format_structured_tool_descriptions(tools)
# 构建提示词模板
system_message = SystemMessage(
content=(
f"{STRUCTURED_CHAT_SYSTEM_PREFIX}\n\n"
f"{tool_descriptions}\n\n"
f"{STRUCTURED_CHAT_SYSTEM_SUFFIX.format(tool_names=', '.join([tool.name for tool in tools]))}"
)
)
human_message = HumanMessagePromptTemplate.from_template(STRUCTURED_CHAT_HUMAN_MESSAGE)
chat_prompt = ChatPromptTemplate.from_messages([
system_message,
MessagesPlaceholder(variable_name="chat_history"),
human_message,
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
# 创建结构化输出解析器
output_parser = StructuredChatOutputParser()
# 设置LLM停止标记
llm_with_stop = llm.bind(stop=["Observation:"])
# 创建Runnable链
agent = (
RunnablePassthrough.assign(
agent_scratchpad=lambda x: format_structured_chat_messages(x["intermediate_steps"])
)
| chat_prompt
| llm_with_stop
| output_parser
)
# 创建智能体执行器
return AgentExecutor.from_agent_and_tools(
agent=agent,
tools=tools,
**kwargs
)
2.8 OPENAI_FUNCTIONS 智能体
实现机制
这种智能体利用OpenAI模型的函数调用能力,将工具表示为可以被模型直接调用的函数。
核心提示词
# OPENAI_FUNCTIONS 系统提示词
OPENAI_FUNCTIONS_SYSTEM_MESSAGE_TEMPLATE = """You are a helpful assistant.
You have access to the following tools:
{tools}
You must always respond with a valid JSON object matching this schema:
{{
"thoughts": {{
"reasoning": "string"
}},
"function_call": {{
"name": "string",
"arguments": {{
// function arguments as key-value pairs
}}
}}
}}
Or, if you want to respond directly to the user:
{{
"thoughts": {{
"reasoning": "string"
}},
"response": "string"
}}
Begin!"""
关键代码实现
def create_openai_functions_agent(
llm: BaseLanguageModel,
tools: List[BaseTool],
**kwargs
) -> AgentExecutor:
"""创建一个使用OpenAI函数调用的智能体"""
# 确保LLM支持函数调用
if not hasattr(llm, "bind_functions"):
raise ValueError("LLM must support function calling (e.g., OpenAI model with function calling)")
# 将工具转换为OpenAI函数格式
functions = [convert_tool_to_openai_function(tool) for tool in tools]
# 构建提示词模板
system_message = SystemMessage(
content=OPENAI_FUNCTIONS_SYSTEM_MESSAGE_TEMPLATE.format(
tools=format_tool_descriptions(tools)
)
)
prompt = ChatPromptTemplate.from_messages([
system_message,
MessagesPlaceholder(variable_name="chat_history"),
HumanMessagePromptTemplate.from_template("{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
# 绑定函数到LLM
llm_with_functions = llm.bind_functions(functions=functions)
# 创建OpenAI函数输出解析器
output_parser = OpenAIFunctionsOutputParser()
# 创建Runnable链
agent = (
RunnablePassthrough.assign(
agent_scratchpad=lambda x: format_to_openai_functions(x["intermediate_steps"])
)
| prompt
| llm_with_functions
| output_parser
)
# 创建智能体执行器
return AgentExecutor.from_agent_and_tools(
agent=agent,
tools=tools,
**kwargs
)
2.9 OPENAI_MULTI_FUNCTIONS 智能体
实现机制
这种智能体对OpenAI函数智能体进行了扩展,支持单轮中调用多个函数(工具)。
核心提示词
# OPENAI_MULTI_FUNCTIONS 系统提示词
OPENAI_MULTI_FUNCTIONS_SYSTEM_MESSAGE_TEMPLATE = """You are a helpful assistant.
You have access to the following tools:
{tools}
You can choose to call multiple tools in a single response, or respond directly to the user.
When calling multiple tools, format your response with a list of function calls and your final response. For example:
[
{{"function_call": {{"name": "tool1", "arguments": {{"arg1": "value1"}} }}}},
{{"function_call": {{"name": "tool2", "arguments": {{"arg1": "value1", "arg2": "value2"}} }}}}
]
Final Response: Your final response to the user.
Begin!"""
关键代码实现
def create_openai_multi_functions_agent(
llm: BaseLanguageModel,
tools: List[BaseTool],
**kwargs
) -> AgentExecutor:
"""创建一个支持多函数调用的OpenAI函数智能体"""
# 确保LLM支持函数调用
if not hasattr(llm, "bind_functions"):
raise ValueError("LLM must support function calling (e.g., OpenAI model with function calling)")
# 将工具转换为OpenAI函数格式
functions = [convert_tool_to_openai_function(tool) for tool in tools]
# 构建提示词模板
system_message = SystemMessage(
content=OPENAI_MULTI_FUNCTIONS_SYSTEM_MESSAGE_TEMPLATE.format(
tools=format_tool_descriptions(tools)
)
)
prompt = ChatPromptTemplate.from_messages([
system_message,
MessagesPlaceholder(variable_name="chat_history"),
HumanMessagePromptTemplate.from_template("{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
# 绑定函数到LLM,并允许多函数调用
llm_with_functions = llm.bind_functions(functions=functions, function_call="auto")
# 创建OpenAI多函数输出解析器
output_parser = OpenAIMultiFunctionsOutputParser()
# 创建Runnable链
agent = (
RunnablePassthrough.assign(
agent_scratchpad=lambda x: format_to_openai_multi_functions(x["intermediate_steps"])
)
| prompt
| llm_with_functions
| output_parser
)
# 创建智能体执行器
return AgentExecutor.from_agent_and_tools(
agent=agent,
tools=tools,
**kwargs
)
3. AgentExecutor - 智能体执行器
AgentExecutor是核心组件,负责运行智能体的思考-行动-观察循环。
核心代码实现
class AgentExecutor(Chain):
"""使用工具的智能体"""
agent: Union[BaseSingleActionAgent, BaseMultiActionAgent, Runnable]
"""用于创建计划和决定每个执行循环步骤中要采取的操作的智能体"""
tools: Sequence[BaseTool]
"""智能体可以调用的有效工具"""
max_iterations: Optional[int] = 15
"""执行循环中执行的最大步骤数"""
early_stopping_method: str = "force"
"""如果智能体从不返回AgentFinish,则使用的早期停止方法"""
def _call(
self,
inputs: Dict[str, str],
run_manager: Optional[CallbackManagerForChainRun] = None,
) -> Dict[str, Any]:
"""执行智能体并获取响应"""
# 构建工具名称到工具的映射,便于查找
name_to_tool_map = {tool.name: tool for tool in self.tools}
# 构建每个工具到颜色的映射,用于日志记录
color_mapping = get_color_mapping(
[tool.name for tool in self.tools], excluded_colors=["green", "red"]
)
intermediate_steps: List[Tuple[AgentAction, str]] = []
# 开始跟踪迭代次数和经过的时间
iterations = 0
time_elapsed = 0.0
start_time = time.time()
# 进入智能体循环(直到返回结果)
while self._should_continue(iterations, time_elapsed):
next_step_output = self._take_next_step(
name_to_tool_map,
color_mapping,
inputs,
intermediate_steps,
run_manager=run_manager,
)
if isinstance(next_step_output, AgentFinish):
return self._return(
next_step_output, intermediate_steps, run_manager=run_manager
)
intermediate_steps.extend(next_step_output)
if len(next_step_output) == 1:
next_step_action = next_step_output[0]
# 检查工具是否应该直接返回
tool_return = self._get_tool_return(next_step_action)
if tool_return is not None:
return self._return(
tool_return, intermediate_steps, run_manager=run_manager
)
iterations += 1
time_elapsed = time.time() - start_time
output = self._action_agent.return_stopped_response(
self.early_stopping_method, intermediate_steps, **inputs
)
return self._return(output, intermediate_steps, run_manager=run_manager)
智能体执行循环关键代码
def _iter_next_step(
self,
name_to_tool_map: Dict[str, BaseTool],
color_mapping: Dict[str, str],
inputs: Dict[str, str],
intermediate_steps: List[Tuple[AgentAction, str]],
run_manager: Optional[CallbackManagerForChainRun] = None,
) -> Iterator[Union[AgentFinish, AgentAction, AgentStep]]:
"""在思考-行动-观察循环中执行单个步骤"""
try:
intermediate_steps = self._prepare_intermediate_steps(intermediate_steps)
# 调用LLM来决定下一步做什么
output = self._action_agent.plan(
intermediate_steps,
callbacks=run_manager.get_child() if run_manager else None,
**inputs,
)
except OutputParserException as e:
# 处理输出解析错误...
# 如果选择的工具是终止工具,则结束并返回
if isinstance(output, AgentFinish):
yield output
return
actions: List[AgentAction]
if isinstance(output, AgentAction):
actions = [output]
else:
actions = output
for agent_action in actions:
yield agent_action
for agent_action in actions:
yield self._perform_agent_action(
name_to_tool_map, color_mapping, agent_action, run_manager
)
4. 智能体基类结构
BaseSingleActionAgent(基础单动作智能体)
class BaseSingleActionAgent(BaseModel):
"""基础单动作智能体类"""
def plan(
self,
intermediate_steps: List[Tuple[AgentAction, str]],
callbacks: Callbacks = None,
**kwargs: Any,
) -> Union[AgentAction, AgentFinish]:
"""根据输入决定下一步做什么"""
async def aplan(
self,
intermediate_steps: List[Tuple[AgentAction, str]],
callbacks: Callbacks = None,
**kwargs: Any,
) -> Union[AgentAction, AgentFinish]:
"""异步版本的plan方法"""
BaseMultiActionAgent(基础多动作智能体)
class BaseMultiActionAgent(BaseModel):
"""基础多动作智能体类"""
def plan(
self,
intermediate_steps: List[Tuple[AgentAction, str]],
callbacks: Callbacks = None,
**kwargs: Any,
) -> Union[List[AgentAction], AgentFinish]:
"""根据输入决定下一步做什么,可以返回多个动作"""
5. 实用示例
创建和执行ReAct智能体
from langchain.agents import AgentExecutor, create_react_agent
from langchain_core.prompts import PromptTemplate
from langchain_openai import OpenAI
from langchain.tools import Tool
# 1. 定义工具
tools = [
Tool(
name="Search",
func=lambda x: "搜索结果: " + x,
description="用于搜索信息的工具"
),
Tool(
name="Calculator",
func=lambda x: eval(x),
description="用于执行数学计算的工具"
)
]
# 2. 创建提示词模板
prompt_template = """Answer the following questions as best you can. You have access to the following tools:
{tools}
Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Begin!
Question: {input}
Thought:{agent_scratchpad}"""
prompt = PromptTemplate.from_template(prompt_template)
# 3. 创建语言模型
llm = OpenAI(temperature=0)
# 4. 创建ReAct智能体
agent = create_react_agent(llm, tools, prompt)
# 5. 创建智能体执行器
agent_executor = AgentExecutor.from_agent_and_tools(
agent=agent,
tools=tools,
max_iterations=10,
early_stopping_method="force"
)
# 6. 运行智能体
result = agent_executor.invoke({"input": "巴黎的埃菲尔铁塔有多高?然后将高度乘以2是多少?"})
print(result["output"])
6. 总结
LangChain的智能体框架提供了灵活、强大的工具来构建基于大语言模型的智能体系统。其核心是思考-行动-观察循环(ReAct范式),使模型能够通过推理和使用工具来解决复杂任务。关键组件包括:
- AgentType - 定义不同类型的智能体,如ReAct、对话式智能体等
- AgentExecutor - 管理智能体的执行流程,包括工具调用、处理中间步骤等
- 工具集成 - 允许智能体使用各种工具来扩展其能力
- 提示词工程 - 为不同智能体类型定制专门的提示词模板
这些组件共同构成了一个强大的框架,使开发人员能够构建能够推理、规划和执行的复杂AI应用。