维护状态
默认情况下,AgentWorkflow 在运行之间是无状态的。这意味着智能体不会保留之前运行的任何记忆。
为了维护状态,我们需要跟踪之前的状态。在LlamaIndex中,工作流有一个Context类,可用于在运行期间和运行之间维护状态。由于AgentWorkflow只是一个预构建的工作流,我们现在也可以使用它。
from llama_index.core.workflow import Context为了在运行之间保持状态,我们将创建一个名为ctx的新上下文。我们传入工作流以正确配置此上下文对象,供将使用它的工作流使用。
ctx = Context(workflow)通过我们配置的上下文,我们可以将其传递给首次运行。
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!上下文是可序列化的,因此可以保存到数据库、文件等中,并在之后重新加载。
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 中的信息,无需显式传递即可使用。
要访问上下文,上下文参数应作为工具的第一个参数,正如我们在此处所做的那样,在一个简单地将名称添加到状态的工具中:
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}"我们现在可以创建一个使用此工具的智能体。您可以选择性地提供智能体的初始状态,我们将在此处执行:
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"},)现在我们可以创建一个上下文并向智能体询问状态:
ctx = Context(workflow)
# check if it knows a name before setting itresponse = 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你可以查看此示例的完整代码。
接下来我们将学习流式输出与事件。