[LangGraph] 元数据标记
元数据标记,就是在创建模型时附加tag,这些tag会出现在流式输出或metadata中,从而用于标记、归类不同模型调用。
举个例子,假设一个节点里调用了两个模型:
- 一个模型负责写笑话
- 一个模型负责写诗
它们都是流式输出token。
这个时候就会遇到一个问题:
如果前端想“只显示笑话模型的 token”,就必须知道:每个token来自哪个模型?
这就是tags的作用:模型被打上tag后,所有token的metadata中都会附带这些tag。
前端可以在流式监听中写:
if (metadata.tags?.includes("joke")) {
// 只处理 joke 模型的 token
}
这意味着:
- tags = LLM 调用的身份标记
- tags可以在流式输出中精准识别模型来源
这在一个节点内、多模型并行情况下尤为关键 。
Server:
async function streamModelTokens(
res: express.Response,
topic: string,
model: ChatOpenAI,
kind: "joke" | "poem",
) {
// 该方法很简单,请求模型,拿到模型的回复,返回给前端
// 提示词
const prompt =
kind === "joke"
? `使用中文写一个关于${topic}的笑话`
: `使用中文写一个关于${topic}的诗歌`;
const events = await model.streamEvents(
[{ role: "human", content: prompt }],
{
version: "v2",
},
);
for await (const event of events) {
// 遍历事件流,对特定的事件类型做处理
if (event.event === "on_chat_model_stream") {
const token = event.data.chunk?.content;
// 说明当前触发的事件,能够拿到对应的token
// 将这个token交给前端
if (token) {
res.write(
`data: ${JSON.stringify({
msg: { content: token },
metadata: { tags: event.tags },
})}\n\n`,
);
}
}
}
}```
frontend:
```ts
function startStream() {
// 1. 获取当前用户在输入框输入的内容
const currentTopic = topic.value.trim();
if (!currentTopic) {
window.alert("请先输入一个主题,例如猫、狗....");
return;
}
jokeTokens.value = "";
poemTokens.value = "";
// 代码来到这里,说明输入框有东西
// 建立SSE连接
if (sse) {
sse.close();
sse = null;
}
const url = `http://localhost:3002/stream-messages?topic=${encodeURIComponent(currentTopic)}`;
sse = new EventSource(url);
sse.onmessage = (ev) => {
const data: StreamEvent = JSON.parse(ev.data);
const { msg, metadata } = data;
// 关键:根据metadata上面的tag来判断当前传递过来的token是哪一个模型
if (metadata.tags?.includes("joke")) {
// 说明是笑话的token
jokeTokens.value += msg.content;
}
if (metadata.tags?.includes("poem")) {
// 说明是诗歌的token
poemTokens.value += msg.content;
}
};
sse.onerror = () => {
console.log("SSE连接失败!");
sse?.close();
};
}

浙公网安备 33010602011771号