跳到内容

如何从工具内部流式传输事件

如果您的 LangGraph 图需要使用调用 LLM(或任何其他 LangChain Runnable 对象 -- 其他图、LCEL 链、检索器等)的工具,您可能希望从底层的 Runnable 流式传输事件。本指南展示了如何做到这一点。

设置

npm install @langchain/langgraph @langchain/anthropic @langchain/core zod
process.env.ANTHROPIC_API_KEY = 'YOUR_API_KEY'

定义图和工具

在本指南中,我们将使用预构建的 ReAct agent

import { z } from "zod";
import { tool } from "@langchain/core/tools";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { ChatAnthropic } from "@langchain/anthropic";

const model = new ChatAnthropic({
  model: "claude-3-5-sonnet-20240620",
  temperature: 0,
});

const getItems = tool(
  async (input, config) => {
    const template = ChatPromptTemplate.fromMessages([
      [
        "human",
        "Can you tell me what kind of items i might find in the following place: '{place}'. " +
          "List at least 3 such items separating them by a comma. And include a brief description of each item..",
      ],
    ]);

    const modelWithConfig = model.withConfig({
      runName: "Get Items LLM",
      tags: ["tool_llm"],
    });

    const chain = template.pipe(modelWithConfig);
    const result = await chain.invoke(input, config);
    return result.content;
  },
  {
    name: "get_items",
    description: "Use this tool to look up which items are in the given place.",
    schema: z.object({
      place: z.string().describe("The place to look up items for. E.g 'shelf'"),
    }),
  }
);

我们在工具内的 LLM runnable 中添加了一个自定义标签 (tool_llm)。这将允许我们过滤我们将从下面编译的图 (agent) Runnable 中流式传输的事件

import { createReactAgent } from "@langchain/langgraph/prebuilt";

const agent = createReactAgent({
  llm: model,
  tools: [getItems],
});

从图中流式传输事件

let finalEvent;

for await (const event of agent.streamEvents(
  {
    messages: [
      [
        "human",
        "what items are on the shelf? You should call the get_items tool.",
      ],
    ],
  },
  {
    version: "v2",
  },
  {
    includeTags: ["tool_llm"],
  }
)) {
  if ("chunk" in event.data) {
    console.dir({
      type: event.data.chunk._getType(),
      content: event.data.chunk.content,
    })
  }
  finalEvent = event;
}
{ type: 'ai', content: 'Here' }
{ type: 'ai', content: ' are three items you might' }
{ type: 'ai', content: ' find on a shelf,' }
{ type: 'ai', content: ' along with brief' }
{ type: 'ai', content: ' descriptions:\n\n1.' }
{ type: 'ai', content: ' Books' }
{ type: 'ai', content: ': Boun' }
{ type: 'ai', content: 'd collections of printe' }
{ type: 'ai', content: 'd pages' }
{ type: 'ai', content: ' containing' }
{ type: 'ai', content: ' various' }
{ type: 'ai', content: ' forms' }
{ type: 'ai', content: ' of literature, information' }
{ type: 'ai', content: ', or reference' }
{ type: 'ai', content: ' material.\n\n2.' }
{ type: 'ai', content: ' Picture' }
{ type: 'ai', content: ' frames: Decorative' }
{ type: 'ai', content: ' borders' }
{ type: 'ai', content: ' used to display an' }
{ type: 'ai', content: 'd protect photographs, artwork' }
{ type: 'ai', content: ', or other visual memor' }
{ type: 'ai', content: 'abilia.\n\n3' }
{ type: 'ai', content: '. Pot' }
{ type: 'ai', content: 'ted plants: Small' }
{ type: 'ai', content: ' indoor' }
{ type: 'ai', content: ' plants in' }
{ type: 'ai', content: ' containers, often used for' }
{ type: 'ai', content: ' decoration or to add a' }
{ type: 'ai', content: ' touch of nature to indoor' }
{ type: 'ai', content: ' spaces.' }
让我们检查最后一个事件,以获取来自 agent 的最终消息列表

const finalMessage = finalEvent?.data.output;
console.dir(
  {
    type: finalMessage._getType(),
    content: finalMessage.content,
    tool_calls: finalMessage.tool_calls,
  },
  { depth: null }
);
{
  type: 'ai',
  content: 'Here are three items you might find on a shelf, along with brief descriptions:\n' +
    '\n' +
    '1. Books: Bound collections of printed pages containing various forms of literature, information, or reference material.\n' +
    '\n' +
    '2. Picture frames: Decorative borders used to display and protect photographs, artwork, or other visual memorabilia.\n' +
    '\n' +
    '3. Potted plants: Small indoor plants in containers, often used for decoration or to add a touch of nature to indoor spaces.',
  tool_calls: []
}
您可以看到 ToolMessage 的内容与我们上面流式传输的输出相同