状态保持#
默认情况下,AgentWorkflow
在每次运行之间是无状态的。这意味着智能体不会记住之前的运行记录。
要维持状态,我们需要跟踪之前的状态。在 LlamaIndex 中,工作流有一个 Context
类,可用于在运行期间和运行之间保持状态。由于 AgentWorkflow 只是一个预构建的工作流,我们现在也可以使用它。
from llama_index.core.workflow import Context
为了在运行之间保持状态,我们将创建一个名为 ctx 的新 Context。我们传入工作流以正确配置这个 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
的上下文变量,每个智能体都可以使用。你可以依赖 state
中的信息而无需显式传递它。
要访问 Context,Context 参数应该是工具的第一个参数,就像我们在这里做的那样,在一个简单地将名称添加到状态的工具中:
async def set_name(ctx: Context, name: str) -> str:
state = await ctx.store.get("state")
state["name"] = name
await ctx.store.set("state", state)
return f"Name set to {name}"
我们现在可以创建一个使用这个工具的智能体。你可以选择性地提供智能体的初始状态,我们在这里这样做:
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 并询问智能体关于状态:
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."
我们现在可以再次询问智能体名称,或者直接访问状态的值:
state = await ctx.store.get("state")
print("Name as stored in state: ", state["name"])
这将输出:
Name as stored in state: Laurie
你可以查看这个示例的完整代码。
接下来我们将学习流式输出和事件。