以编程方式使用文档

本页面介绍 Deep Agents 特有的流式传输问题——最重要的是,通过以下方式从委托的子代理进行流式传输 stream.subagents。有关常规代理流式传输(stream.messages, stream.values、工具调用、自定义更新),请参阅 LangChain 事件流.

流式传输子代理

Deep Agents 在 LangGraph 流式传输之上添加了子代理投影。当您希望每个委托 stream.subagents 使用一个流句柄时,请使用 task 调用。该投影是轻量级的:它首先发现子代理任务,只有在您访问子代理句柄上的这些流时,才会打开消息、工具调用和值流。

每个句柄的 name 是子代理的配置名称:协调器在调用 subagent_type 时传递的 task 工具时传递的。Deep Agents 将该名称绑定到委托的运行,因此您在子代理规范中定义的相同标签就是您在流中过滤和路由的依据。

const stream = await agent.streamEvents(
  { messages: [{ role: "user", content: "Write me a haiku about the sea" }] },
  { version: "v3" }
);

for await (const subagent of stream.subagents) {
  console.log(subagent.name);
  console.log(await subagent.taskInput);

  for await (const message of subagent.messages) {
    console.log(await message.text);
  }
}

子代理流字段

每个子代理流公开与父运行相同类型的投影,例如消息、工具调用、嵌套子代理和最终输出。有关常规父运行流式传输模型,请参阅 LangChain 事件流.

TypeScript 使用 camelCase 投影名称,例如 toolCallstaskInput。每个子代理流可以公开 .messages, .toolCalls, .values, .subagents.output.

字段描述
name子代理名称,取自 subagent_type 协调器在其 task 调用中选择的内容。
messages子代理发出的消息。
subagents嵌套子代理调用。
output子代理的最终状态,或委托任务的完成信号。
taskInput传递给任务工具的提示的 Promise。
toolCalls作用域限定为子代理的工具调用。

跟踪子代理生命周期

当您只需要显示哪些子代理启动和完成时,请使用 stream.subagents 。除非您访问单个子代理上的那些投影,否则无需订阅消息或值流。

const stream = await agent.streamEvents(input, { version: "v3" });

let running = 0;
let completed = 0;
let failed = 0;
const watchers: Promise<void>[] = [];

for await (const subagent of stream.subagents) {
  running += 1;
  console.log(`${subagent.name}: started`);

  watchers.push(
    subagent.output.then(
      () => {
        running -= 1;
        completed += 1;
        console.log(`${subagent.name}: completed`);
      },
      () => {
        running -= 1;
        failed += 1;
        console.log(`${subagent.name}: failed`);
      }
    )
  );
}

await Promise.all(watchers);
console.log({ running, completed, failed });

流式传输消息

Deep Agents 可以从协调器代理和委托的子代理发出消息。使用 stream.messages 获取顶级消息,使用 subagent.messages 获取每个委托的子代理。

const stream = await agent.streamEvents(input, { version: "v3" });

for await (const message of stream.messages) {
  console.log("[coordinator]", await message.text);
}

for await (const subagent of stream.subagents) {
  for await (const message of subagent.messages) {
    console.log(`[${subagent.name}]`, await message.text);
  }
}

流式传输工具调用

Deep Agents 在代理树的每个层级公开工具调用。使用顶级 stream.tool_calls 用于协调器工具和每个 subagent.tool_calls 用于委托工作。

const stream = await agent.streamEvents(input, { version: "v3" });

for await (const call of stream.toolCalls) {
  console.log("[coordinator tool]", call.name, call.input);
  console.log(await call.status);
}

for await (const subagent of stream.subagents) {
  for await (const call of subagent.toolCalls) {
    console.log(`[${subagent.name} tool]`, call.name, call.input);

    const status = await call.status;
    if (status === "finished") {
      console.log(await call.output);
    } else if (status === "error") {
      console.error(await call.error);
    }
  }
}

流式处理嵌套工作

您可以递归进入子代理流以观察嵌套的子代理、消息和工具调用。

const stream = await agent.streamEvents(input, { version: "v3" });

for await (const subagent of stream.subagents) {
  console.log(`subagent ${subagent.name}: started`);

  for await (const toolCall of subagent.toolCalls) {
    console.log(`${toolCall.name}(${JSON.stringify(toolCall.input)})`);

    const status = await toolCall.status;
    if (status === "finished") {
      console.log(await toolCall.output);
    } else if (status === "error") {
      console.error(await toolCall.error);
    }
  }

  for await (const nested of subagent.subagents) {
    console.log(`nested subagent ${nested.name}: started`);
  }
}

并发消费

协调器和子代理输出经常交织。当您需要实时UI更新时,并发消费投影。

在JavaScript中使用并发消费者:

const stream = await agent.streamEvents(input, { version: "v3" });

await Promise.all([
  (async () => {
    for await (const message of stream.messages) {
      console.log("[coordinator]", await message.text);
    }
  })(),
  (async () => {
    for await (const subagent of stream.subagents) {
      void (async () => {
        for await (const message of subagent.messages) {
          console.log(`[${subagent.name}]`, await message.text);
        }
      })();
    }
  })(),
]);

当您需要协调器和所有子代理之间的精确到达顺序时,迭代原始协议事件并使用 namespace 来识别来源:

const stream = await agent.streamEvents(input, { version: "v3" });

for await (const event of stream) {
  if (event.method !== "messages") continue;

  const data = event.params.data;
  if (data.event !== "content-block-delta") continue;

  const block = data.delta ?? {};
  if (block.type === "text-delta") {
    const isSubagent = event.params.namespace.some((seg) => seg.startsWith("tools:"));
    const source = isSubagent ? "subagent" : "coordinator";
    console.log(`[${source}] ${block.text}`);
  }
}

子代理与子图

stream.subgraphs 显示图执行结构。 stream.subagents 显示产品级Deep Agents任务委托。使用 stream.subagents 用于面向用户的UI,因为它隐藏内部图节点并直接公开子代理概念。

相关