Skip to content
CrewAI 文档版本 跟随上游 源快照 209a9554 更新于 2026-10-18

预测式状态更新

将进行中的工具调用参数流式写入智能体状态,使 UI 在智能体仍在生成时就乐观地更新。

让工作过程实时可见

通常,从 UI 的角度看,工具调用是原子的:智能体决定写什么,而你的界面只有在调用完成后才能看到结果。对于一个会产出大文档的工具来说,这意味着漫长的等待,然后所有内容一次性到位。

预测式状态更新消除了这种等待。你把流式传输的工具参数投射到智能体状态的某个字段上,于是当模型逐个 token 生成参数时,该状态字段会实时填充。智能体正在写的文档会随着输入出现在编辑器中,而不是等到最后。

NOTE

预测式状态依赖带有自定义状态的 Flow(Flow[AgentState])。它把流式工具参数投射到状态字段上,因此裸 Crew 没有对应的实现。

与共享状态的对比

两种模式都从前端读取智能体状态,但它们解决的问题不同:

模式作用
预测式状态单向。将进行中的工具参数流式写入状态字段,使 UI 在生成期间、调用完成之前就更新。
共享状态双向。UI 读取并写入智能体已提交的状态,使应用与智能体在多轮之间保持同步。

当你想要对智能体正在产出的内容做乐观的、生成中的预览时,选用预测式状态。当用户需要把状态编辑回去时,选用共享状态。

分步讲解

这里假设你已经有一个通过 AG-UI 提供服务的 Crew 或 Flow,并已接好 CopilotKit 前端。如果没有,请先看前端概览。

Define a Flow with custom state

预测式状态会把工具参数投射到状态字段上,因此你的 Flow 需要一个有类型的字段来接收它。将你想流式写入的字段添加到 CopilotKitState 子类中。

python
from typing import Optional
from crewai.flow.flow import Flow, start, router, listen
from litellm import acompletion
from ag_ui_crewai.sdk import copilotkit_stream, copilotkit_predict_state, CopilotKitState

WRITE_DOCUMENT_TOOL = {
    "type": "function",
    "function": {
        "name": "write_document",
        "description": "Write the full document in markdown.",
        "parameters": {
            "type": "object",
            "properties": {
                "document": {"type": "string", "description": "The document to write"},
            },
        },
    },
}

class AgentState(CopilotKitState):
    document: Optional[str] = None

class DocumentFlow(Flow[AgentState]):
    @start()
    @listen("route_follow_up")
    async def start_flow(self):
        pass

Map a state field to a tool argument

在开始流式输出补全内容之前调用 copilotkit_predict_state。它告诉运行时把指定的工具参数投射到指定的状态字段上:当 write_document 调用流式输出其 document 参数时,document 状态字段会实时更新。

python
    @router(start_flow)
    async def chat(self):
        # Map the `document` state field to the `document` argument of write_document.
        # As the tool call streams, the state field updates live.
        await copilotkit_predict_state({
            "document": {"tool_name": "write_document", "tool_argument": "document"},
        })

        response = await copilotkit_stream(
            await acompletion(
                model="openai/gpt-4o",
                messages=[
                    {"role": "system", "content": "Write and edit the document with write_document."},
                    *self.state.messages,
                ],
                tools=[*self.state.copilotkit.actions, WRITE_DOCUMENT_TOOL],
                parallel_tool_calls=False,
                stream=True,
            )
        )
        message = response.choices[0].message
        self.state.messages.append(message)

关键在于 copilotkit_predict_state({ "<state_field>": {"tool_name": ..., "tool_argument": ...} })。没有它,前端只有在工具调用完成后才能看到 document。有了它,部分参数会在智能体仍在生成时流式写入该字段。

如前端概览所示,用 add_crewai_flow_fastapi_endpoint(...) 为该 Flow 提供服务。

Read the predicted state on the frontend

在前端,用 useAgent 读取该字段并订阅状态变化。由于后端正在把流式参数投射到 document,该组件会随着智能体“打字”而重新渲染。

tsx
"use client";
import { useAgent, UseAgentUpdate } from "@copilotkit/react-core/v2";

function DocumentView() {
  const { agent } = useAgent({
    agentId: "document",
    updates: [UseAgentUpdate.OnStateChanged],
  });
  const document = (agent?.state as { document?: string })?.document ?? "";
  return <article>{document}</article>; // updates as the agent types
}

document 字段会随着智能体生成 write_document 调用而逐步填充,因此编辑器会实时更新,而不是在最后一次性到位。

相关

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