代理¶
类
名称 | 描述 |
---|---|
AgentState |
代理的状态。 |
函数
名称 | 描述 |
---|---|
create_react_agent |
创建一个代理图,它循环调用工具直到满足停止条件。 |
AgentState ¶
基础: TypedDict
代理的状态。
create_react_agent ¶
create_react_agent(
model: Union[str, LanguageModelLike],
tools: Union[
Sequence[Union[BaseTool, Callable]], ToolNode
],
*,
prompt: Optional[Prompt] = None,
response_format: Optional[
Union[
StructuredResponseSchema,
tuple[str, StructuredResponseSchema],
]
] = None,
pre_model_hook: Optional[RunnableLike] = None,
state_schema: Optional[StateSchemaType] = None,
config_schema: Optional[Type[Any]] = None,
checkpointer: Optional[Checkpointer] = None,
store: Optional[BaseStore] = None,
interrupt_before: Optional[list[str]] = None,
interrupt_after: Optional[list[str]] = None,
debug: bool = False,
version: Literal["v1", "v2"] = "v1",
name: Optional[str] = None
) -> CompiledGraph
创建一个代理图,它循环调用工具直到满足停止条件。
有关使用 create_react_agent
的更多详细信息,请访问 代理 文档。
参数
名称 | 类型 | 描述 | 默认 |
---|---|---|---|
model
|
Union[str, LanguageModelLike]
|
支持工具调用的 |
必需的 |
tools
|
Union[Sequence[Union[BaseTool, Callable]], ToolNode]
|
工具列表或 ToolNode 实例。如果提供空列表,则代理将仅包含一个不进行工具调用的 LLM 节点。 |
必需的 |
prompt
|
Optional[Prompt]
|
LLM 的可选 prompt。可以采用几种不同的形式
|
None
|
response_format
|
Optional[Union[StructuredResponseSchema, tuple[str, StructuredResponseSchema]]]
|
最终代理输出的可选 schema。 如果提供,输出将根据给定的 schema 进行格式化,并在 'structured_response' 状态键中返回。如果未提供,则输出状态中将不包含 `structured_response`。可以按如下方式传递
重要
注意 图谱将在代理循环结束后单独调用 LLM 来生成结构化响应。这并不是获取结构化响应的唯一策略,请参阅 本指南 中的更多选项。 |
None
|
pre_model_hook
|
Optional[RunnableLike]
|
一个可选的节点,添加到 `agent` 节点(即调用 LLM 的节点)之前。对于管理长消息历史记录(例如,消息修剪、摘要等)非常有用。Pre-model hook 必须是可调用对象或 runnable,它接收当前的图状态并以以下形式返回状态更新
重要 必须提供 `messages` 或 `llm_input_messages` 中的至少一个,并将其用作 `agent` 节点的输入。其余键将添加到图状态。 |
None
|
state_schema
|
Optional[StateSchemaType]
|
一个定义图状态的可选状态 schema。必须具有 `messages` 和 `remaining_steps` 键。默认为定义这两个键的 `AgentState`。 |
None
|
config_schema
|
Optional[Type[Any]]
|
一个可选的配置 schema。使用它通过 agent.config_specs 暴露可配置参数。 |
None
|
checkpointer
|
Optional[Checkpointer]
|
一个可选的检查点保存对象。用于持久化单线程(例如,单次对话)的图状态(例如,作为聊天记忆)。 |
None
|
store
|
Optional[BaseStore]
|
一个可选的存储对象。用于在多个线程(例如,多个对话/用户)中持久化数据。 |
None
|
interrupt_before
|
Optional[list[str]]
|
在中断之前要中断的节点名称的可选列表。应为以下之一:"agent", "tools"。如果您想在执行操作之前添加用户确认或其他中断,这很有用。 |
None
|
interrupt_after
|
Optional[list[str]]
|
在中断之后要中断的节点名称的可选列表。应为以下之一:"agent", "tools"。如果您想直接返回或对输出进行额外处理,这很有用。 |
None
|
debug
|
bool
|
指示是否启用调试模式的标志。 |
False
|
version
|
Literal['v1', 'v2']
|
确定要创建的图的版本。可以是以下之一
|
'v1'
|
name
|
Optional[str]
|
CompiledStateGraph 的可选名称。将 ReAct 代理图添加为另一个图的子图节点时,将自动使用此名称 - 对于构建多代理系统特别有用。 |
None
|
返回值
类型 | 描述 |
---|---|
CompiledGraph
|
可用于聊天交互的已编译 LangChain runnable。 |
"agent" 节点使用消息列表(应用 prompt 后)调用语言模型。如果生成的 AIMessage 包含 `tool_calls`,则图谱将调用 "tools" 节点。"tools" 节点执行工具(每个 `tool_call` 对应一个工具),并将响应作为 `ToolMessage` 对象添加到消息列表中。然后 agent 节点再次调用语言模型。这个过程会重复,直到响应中不再包含 `tool_calls`。然后 agent 将完整的消息列表作为包含键 "messages" 的字典返回。
sequenceDiagram
participant U as User
participant A as LLM
participant T as Tools
U->>A: Initial input
Note over A: Prompt + LLM
loop while tool_calls present
A->>T: Execute tools
T-->>A: ToolMessage for each tool_calls
end
A->>U: Return final state
示例
from langgraph.prebuilt import create_react_agent
def check_weather(location: str) -> str:
'''Return the weather forecast for the specified location.'''
return f"It's always sunny in {location}"
graph = create_react_agent(
"anthropic:claude-3-7-sonnet-latest",
tools=[check_weather],
prompt="You are a helpful assistant",
)
inputs = {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
for chunk in graph.stream(inputs, stream_mode="updates"):
print(chunk)
ToolNode ¶
基础: RunnableCallable
执行最后一条 AIMessage 中调用的工具的节点。
它可以在 StateGraph 中使用,带有 "messages" 状态键(或通过 ToolNode 的 'messages_key' 传递的自定义键)。如果请求了多个工具调用,它们将并行运行。输出将是 ToolMessages 列表,每个工具调用一个。
工具调用也可以直接作为 `ToolCall` dicts 列表传递。
参数
名称 | 类型 | 描述 | 默认 |
---|---|---|---|
tools
|
Sequence[Union[BaseTool, Callable]]
|
ToolNode 可以调用的工具序列。 |
必需的 |
name
|
str
|
图中 ToolNode 的名称。默认为 "tools"。 |
'tools'
|
tags
|
Optional[list[str]]
|
与节点关联的可选标签。默认为 None。 |
None
|
handle_tool_errors
|
Union[bool, str, Callable[..., str], tuple[type[Exception], ...]]
|
如何处理节点内工具引发的工具错误。默认为 True。必须是以下之一
|
True
|
messages_key
|
str
|
输入中包含消息列表的状态键。ToolNode 的输出将使用相同的键。默认为 "messages"。 |
'messages'
|
ToolNode
大致类似于
tools_by_name = {tool.name: tool for tool in tools}
def tool_node(state: dict):
result = []
for tool_call in state["messages"][-1].tool_calls:
tool = tools_by_name[tool_call["name"]]
observation = tool.invoke(tool_call["args"])
result.append(ToolMessage(content=observation, tool_call_id=tool_call["id"]))
return {"messages": result}
工具调用也可以直接传递给 ToolNode。在使用 Send API 时这很有用,例如,在条件边中
def example_conditional_edge(state: dict) -> List[Send]:
tool_calls = state["messages"][-1].tool_calls
# If tools rely on state or store variables (whose values are not generated
# directly by a model), you can inject them into the tool calls.
tool_calls = [
tool_node.inject_tool_args(call, state, store)
for call in last_message.tool_calls
]
return [Send("tools", [tool_call]) for tool_call in tool_calls]
重要
- 输入状态可以是以下之一
- 一个包含消息列表的 dict,带有 messages 键。
- 一个消息列表。
- 一个工具调用列表。
- 如果对消息列表进行操作,最后一条消息必须是填充了 `tool_calls` 的 `AIMessage`。
方法
名称 | 描述 |
---|---|
inject_tool_args |
将状态和存储注入工具调用。 |
inject_tool_args ¶
inject_tool_args(
tool_call: ToolCall,
input: Union[
list[AnyMessage], dict[str, Any], BaseModel
],
store: Optional[BaseStore],
) -> ToolCall
将状态和存储注入工具调用。
在生成工具 schema 时,将类型标注为 `InjectedState` 和 `InjectedStore` 的工具参数将被忽略。此方法将它们注入工具调用以进行工具调用。
参数
名称 | 类型 | 描述 | 默认 |
---|---|---|---|
tool_call
|
ToolCall
|
要注入状态和存储的工具调用。 |
必需的 |
input
|
Union[list[AnyMessage], dict[str, Any], BaseModel]
|
要注入的输入状态。 |
必需的 |
store
|
Optional[BaseStore]
|
要注入的存储。 |
必需的 |
返回值
名称 | 类型 | 描述 |
---|---|---|
ToolCall |
ToolCall
|
注入了状态和存储的工具调用。 |
类
名称 | 描述 |
---|---|
InjectedState |
用于工具参数的注解,表示应使用图状态填充该参数。 |
InjectedStore |
用于工具参数的注解,表示应使用 LangGraph 存储填充该参数。 |
函数
名称 | 描述 |
---|---|
tools_condition |
在 conditional_edge 中使用,如果最后一条消息 |
InjectedState ¶
基础: InjectedToolArg
用于工具参数的注解,表示应使用图状态填充该参数。
任何用 InjectedState 标注的工具参数将对工具调用模型隐藏,以便模型不会尝试生成该参数。如果使用 ToolNode,相应的图状态字段将自动注入模型生成的工具参数中。
参数
名称 | 类型 | 描述 | 默认 |
---|---|---|---|
field
|
Optional[str]
|
要插入的状态中的键。如果为 None,则预期会传入整个状态。 |
None
|
示例
from typing import List
from typing_extensions import Annotated, TypedDict
from langchain_core.messages import BaseMessage, AIMessage
from langchain_core.tools import tool
from langgraph.prebuilt import InjectedState, ToolNode
class AgentState(TypedDict):
messages: List[BaseMessage]
foo: str
@tool
def state_tool(x: int, state: Annotated[dict, InjectedState]) -> str:
'''Do something with state.'''
if len(state["messages"]) > 2:
return state["foo"] + str(x)
else:
return "not enough messages"
@tool
def foo_tool(x: int, foo: Annotated[str, InjectedState("foo")]) -> str:
'''Do something else with state.'''
return foo + str(x + 1)
node = ToolNode([state_tool, foo_tool])
tool_call1 = {"name": "state_tool", "args": {"x": 1}, "id": "1", "type": "tool_call"}
tool_call2 = {"name": "foo_tool", "args": {"x": 1}, "id": "2", "type": "tool_call"}
state = {
"messages": [AIMessage("", tool_calls=[tool_call1, tool_call2])],
"foo": "bar",
}
node.invoke(state)
InjectedStore ¶
基础: InjectedToolArg
用于工具参数的注解,表示应使用 LangGraph 存储填充该参数。
任何用 InjectedStore 标注的工具参数将对工具调用模型隐藏,以便模型不会尝试生成该参数。如果使用 ToolNode,相应的存储字段将自动注入模型生成的工具参数中。注意:如果使用存储对象编译图谱,则在使用 ToolNode 时,存储将自动传播到带有 InjectedStore 参数的工具。
警告
InjectedStore
标注需要 langchain-core >= 0.3.8
示例
from typing import Any
from typing_extensions import Annotated
from langchain_core.messages import AIMessage
from langchain_core.tools import tool
from langgraph.store.memory import InMemoryStore
from langgraph.prebuilt import InjectedStore, ToolNode
store = InMemoryStore()
store.put(("values",), "foo", {"bar": 2})
@tool
def store_tool(x: int, my_store: Annotated[Any, InjectedStore()]) -> str:
'''Do something with store.'''
stored_value = my_store.get(("values",), "foo").value["bar"]
return stored_value + x
node = ToolNode([store_tool])
tool_call = {"name": "store_tool", "args": {"x": 1}, "id": "1", "type": "tool_call"}
state = {
"messages": [AIMessage("", tool_calls=[tool_call])],
}
node.invoke(state, store=store)
tools_condition ¶
tools_condition(
state: Union[
list[AnyMessage], dict[str, Any], BaseModel
],
messages_key: str = "messages",
) -> Literal["tools", "__end__"]
在 conditional_edge 中使用,如果最后一条消息
包含工具调用。否则,路由到末尾。
参数
名称 | 类型 | 描述 | 默认 |
---|---|---|---|
state
|
Union[list[AnyMessage], dict[str, Any], BaseModel]
|
检查工具调用的状态。必须包含消息列表 (MessageGraph) 或包含 "messages" 键 (StateGraph)。 |
必需的 |
返回值
类型 | 描述 |
---|---|
Literal['tools', '__end__']
|
要路由到的下一个节点。 |
示例
创建一个带工具的自定义 ReAct 风格代理。
>>> from langchain_anthropic import ChatAnthropic
>>> from langchain_core.tools import tool
...
>>> from langgraph.graph import StateGraph
>>> from langgraph.prebuilt import ToolNode, tools_condition
>>> from langgraph.graph.message import add_messages
...
>>> from typing import Annotated
>>> from typing_extensions import TypedDict
...
>>> @tool
>>> def divide(a: float, b: float) -> int:
... """Return a / b."""
... return a / b
...
>>> llm = ChatAnthropic(model="claude-3-haiku-20240307")
>>> tools = [divide]
...
>>> class State(TypedDict):
... messages: Annotated[list, add_messages]
>>>
>>> graph_builder = StateGraph(State)
>>> graph_builder.add_node("tools", ToolNode(tools))
>>> graph_builder.add_node("chatbot", lambda state: {"messages":llm.bind_tools(tools).invoke(state['messages'])})
>>> graph_builder.add_edge("tools", "chatbot")
>>> graph_builder.add_conditional_edges(
... "chatbot", tools_condition
... )
>>> graph_builder.set_entry_point("chatbot")
>>> graph = graph_builder.compile()
>>> graph.invoke({"messages": {"role": "user", "content": "What's 329993 divided by 13662?"}})
ValidationNode ¶
基础: RunnableCallable
验证来自最后一条 AIMessage 的所有工具请求的节点。
它可以在带有 "messages" 键的 StateGraph 中使用,也可以在 MessageGraph 中使用。
注意
此节点实际上不运行工具,它只验证工具调用,这对于提取和需要生成符合复杂 schema 的结构化输出而又不丢失原始消息和工具 ID(用于多轮对话)的其他用例非常有用。
参数
名称 | 类型 | 描述 | 默认 |
---|---|---|---|
schemas
|
Sequence[Union[BaseTool, Type[BaseModel], Callable]]
|
用于验证工具调用的 schema 列表。可以是以下任何一种:- pydantic BaseModel 类 - BaseTool 实例(将使用 args_schema) - 函数(将从函数签名创建 schema) |
必需的 |
format_error
|
Optional[Callable[[BaseException, ToolCall, Type[BaseModel]], str]]
|
一个函数,接收异常、ToolCall 和 schema,并返回格式化的错误字符串。默认情况下,它返回异常的 repr 和一条在修复验证错误后应响应的消息。 |
None
|
name
|
str
|
节点的名称。 |
'validation'
|
tags
|
Optional[list[str]]
|
要添加到节点的标签列表。 |
None
|
返回值
类型 | 描述 |
---|---|
Union[Dict[str, List[ToolMessage]], Sequence[ToolMessage]]
|
带有验证内容或错误消息的 ToolMessages 列表。 |
示例
from typing import Literal, Annotated
from typing_extensions import TypedDict
from langchain_anthropic import ChatAnthropic
from pydantic import BaseModel, field_validator
from langgraph.graph import END, START, StateGraph
from langgraph.prebuilt import ValidationNode
from langgraph.graph.message import add_messages
class SelectNumber(BaseModel):
a: int
@field_validator("a")
def a_must_be_meaningful(cls, v):
if v != 37:
raise ValueError("Only 37 is allowed")
return v
builder = StateGraph(Annotated[list, add_messages])
llm = ChatAnthropic(model="claude-3-5-haiku-latest").bind_tools([SelectNumber])
builder.add_node("model", llm)
builder.add_node("validation", ValidationNode([SelectNumber]))
builder.add_edge(START, "model")
def should_validate(state: list) -> Literal["validation", "__end__"]:
if state[-1].tool_calls:
return "validation"
return END
builder.add_conditional_edges("model", should_validate)
def should_reprompt(state: list) -> Literal["model", "__end__"]:
for msg in state[::-1]:
# None of the tool calls were errors
if msg.type == "ai":
return END
if msg.additional_kwargs.get("is_error"):
return "model"
return END
builder.add_conditional_edges("validation", should_reprompt)
graph = builder.compile()
res = graph.invoke(("user", "Select a number, any number"))
# Show the retry logic
for msg in res:
msg.pretty_print()
类
名称 | 描述 |
---|---|
HumanInterruptConfig |
定义允许人类中断的操作的配置。 |
ActionRequest |
表示在图执行中请求人类操作。 |
HumanInterrupt |
表示由图触发的需要人工干预的中断。 |
HumanResponse |
人类对中断提供的响应,图执行恢复时返回该响应。 |
HumanInterruptConfig ¶
ActionRequest ¶
HumanInterrupt ¶
基础: TypedDict
表示由图触发的需要人工干预的中断。
当执行因人工输入而暂停时,这将传递给 `interrupt` 函数。
属性
名称 | 类型 | 描述 |
---|---|---|
action_request |
ActionRequest
|
正向人类请求的具体操作 |
config |
HumanInterruptConfig
|
定义允许哪些操作的配置 |
description |
Optional[str]
|
所需输入的详细描述(可选) |
示例
# Extract a tool call from the state and create an interrupt request
request = HumanInterrupt(
action_request=ActionRequest(
action="run_command", # The action being requested
args={"command": "ls", "args": ["-l"]} # Arguments for the action
),
config=HumanInterruptConfig(
allow_ignore=True, # Allow skipping this step
allow_respond=True, # Allow text feedback
allow_edit=False, # Don't allow editing
allow_accept=True # Allow direct acceptance
),
description="Please review the command before execution"
)
# Send the interrupt request and get the response
response = interrupt([request])[0]
HumanResponse ¶
基础: TypedDict
人类对中断提供的响应,图执行恢复时返回该响应。
属性
名称 | 类型 | 描述 |
---|---|---|
type |
Literal['accept', 'ignore', 'response', 'edit']
|
响应类型:- "accept":接受当前状态而不进行更改 - "ignore":跳过/忽略当前步骤 - "response":提供文本反馈或指令 - "edit":修改当前状态/内容 |
arg |
Literal['accept', 'ignore', 'response', 'edit']
|
响应载荷:- None:用于忽略/接受操作 - str:用于文本响应 - ActionRequest:用于带有更新内容的编辑操作 |