Skip to content
LlamaIndex 文档版本 跟随上游 源快照 a9a6555b 更新于 2026-10-15

默认情况下,AgentWorkflow 在多次运行之间是无状态的,也就是说 agent 不会记得之前的运行。

要维护状态,就得保存先前的状态。在 LlamaIndex 里,Workflows 提供了一个 Context 类,可以在单次运行内部以及多次运行之间维护状态。由于 AgentWorkflow 本身就是一个预置的 Workflow,我们现在也能直接用它。

from llama_index.core.workflow import Context

为了在运行之间保持状态,我们新建一个名为 ctx 的 Context。把 workflow 传进去,以便为这个 Context 对象做好与该工作流的配套配置。

ctx = Context(workflow)

有了配置好的 Context,就可以把它传给第一次运行。

response = await workflow.run(user_msg="Hi, my name is Laurie!", ctx=ctx)
print(response)

得到的结果是:

Hello Laurie! How can I assist you today?

现在我们再运行一次这个工作流、追问一个问题,它就记得刚才的信息了:

response2 = await workflow.run(user_msg="What's my name?", ctx=ctx)
print(response2)

得到的结果是:

Your name is Laurie!

在更长的时间尺度上维护状态

Context 是可序列化的,因此可以存进数据库、文件等地方,之后再加载回来。

JsonSerializer 是一个简单的序列化器,用 json.dumps 和 json.loads 完成上下文的序列化与反序列化。

JsonPickleSerializer 则使用 pickle 完成上下文的序列化与反序列化。如果你的上下文里含有无法序列化的对象,就可以用这个序列化器。

和其他导入一样,先把序列化器引入:

from llama_index.core.workflow import JsonPickleSerializer, JsonSerializer

随后就能把上下文序列化成字典并存进文件:

ctx_dict = ctx.to_dict(serializer=JsonSerializer())

再把它反序列化回 Context 对象,就能像之前一样继续提问:

restored_ctx = Context.from_dict(
    workflow, ctx_dict, serializer=JsonSerializer()
)

response3 = await workflow.run(user_msg="What's my name?", ctx=restored_ctx)

你可以在这里看到这个示例的完整代码。

工具与状态

工具也可以定义为能够访问工作流上下文的形式。这意味着你可以在上下文里读写变量并在工具中使用它们,也可以用它们在工具之间传递信息。

AgentWorkflow 使用一个名为 state 的上下文变量,每个 agent 都能访问它。你可以放心依赖 state 中的信息,而不必显式传入。

要访问 Context,Context 参数必须放在工具函数的第一个参数位置——下面的工具只是往 state 里添加一个名字,正是这样做的:

async def set_name(ctx: Context, name: str) -> str:
    async with ctx.store.edit_state() as ctx_state:
        ctx_state["state"]["name"] = name

    return f"Name set to {name}"

现在我们可以创建使用这个工具的 agent。你可以选择性地提供 agent 的初始状态,这里我们就这么做:

workflow = AgentWorkflow.from_tools_or_functions(
    [set_name],
    llm=llm,
    system_prompt="You are a helpful assistant that can set a name.",
    initial_state={"name": "unset"},
)

接着创建一个 Context,并向 agent 询问状态里的信息:

ctx = Context(workflow)

# check if it knows a name before setting it
response = await workflow.run(user_msg="What's my name?", ctx=ctx)
print(str(response))

得到的结果是:

Your name has been set to "unset."

然后在新的一次运行里显式设置这个名字:

response2 = await workflow.run(user_msg="My name is Laurie", ctx=ctx)
print(str(response2))
Your name has been updated to "Laurie."

之后我们可以再问 agent 这个名字,也可以直接读取 state 里的值:

state = await ctx.store.get("state")
print("Name as stored in state: ", state["name"])

得到的结果是:

Name as stored in state: Laurie

你可以在这里看到这个示例的完整代码。

下一节我们来了解流式输出与事件。

BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。