跳到主要内容

维护状态#

默认情况下,AgentWorkflow 在各次运行之间是无状态的。这意味着 Agent 不会记住先前的运行信息。

为了维护状态,我们需要跟踪先前的状态。在 LlamaIndex 中,Workflow 有一个 Context 类,可用于在运行内部和运行之间维护状态。由于 AgentWorkflow 只是一个预构建的 Workflow,我们现在也可以使用它。

from llama_index.core.workflow import Context

为了维护运行之间的状态,我们将创建一个名为 ctx 的新 Context。我们将 Workflow 传入其中,以便为将使用此 Context 对象的 Workflow 正确配置它。

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?

现在,如果我们再次运行 Workflow 来询问一个后续问题,它会记住这些信息

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

结果如下

Your name is Laurie!

维护更长时间的状态#

Context 是可序列化的,因此可以保存到数据库、文件等位置,稍后重新加载。

JsonSerializer 是一个简单的序列化器,它使用 json.dumpsjson.loads 来序列化和反序列化 Context。

JsonPickleSerializer 是一个使用 pickle 来序列化和反序列化 Context 的序列化器。如果你的 Context 中包含不可序列化的对象,可以使用此序列化器。

我们可以像导入其他模块一样导入我们的序列化器

from llama_index.core.workflow import JsonPickleSerializer, JsonSerializer

然后我们可以将 Context 序列化为字典并保存到文件中

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)

你可以查看此示例的完整代码

工具与状态#

工具也可以定义为可以访问 Workflow Context。这意味着你可以从 Context 中设置和检索变量并在工具中使用它们,或者在工具之间传递信息。

AgentWorkflow 使用一个名为 state 的 Context 变量,该变量对每个 Agent 都可用。你可以依赖 state 中的信息而无需显式传入。

要访问 Context,Context 参数应该是工具的第一个参数,就像我们在这里所做的,在一个简单地向状态添加名称的工具中

async def set_name(ctx: Context, name: str) -> str:
    state = await ctx.get("state")
    state["name"] = name
    await ctx.set("state", state)
    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."

然后我们可以显式地在 Agent 的新运行中设置名称

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

我们现在可以再次询问 Agent 名称,或者直接访问状态的值

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

结果如下

Name as stored in state: Laurie

你可以查看此示例的完整代码

接下来我们将了解流式输出和事件