一键导入
langchain-streaming
Stream outputs from LangChain agents and models - includes stream modes, token streaming, progress updates, and real-time feedback
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Stream outputs from LangChain agents and models - includes stream modes, token streaming, progress updates, and real-time feedback
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | langchain-streaming |
| description | Stream outputs from LangChain agents and models - includes stream modes, token streaming, progress updates, and real-time feedback |
| language | js |
Streaming allows you to surface real-time updates from LangChain agents and models as they run. Instead of waiting for complete responses, you can display output progressively, improving user experience especially for long-running operations.
Key Concepts:
| Scenario | Stream? | Why |
|---|---|---|
| Long model responses | ✅ Yes | Show tokens as generated |
| Multi-step agent tasks | ✅ Yes | Show progress through steps |
| Long-running tools | ✅ Yes | Provide progress updates |
| Simple quick requests | ⚠️ Maybe | Overhead might not be worth it |
| Backend batch processing | ❌ No | No user waiting for updates |
| Mode | Use When | Returns |
|---|---|---|
"values" | Need full state after each step | Complete state object |
"updates" | Need only what changed | State deltas |
"messages" | Need LLM token stream | [token, metadata] tuples |
"custom" | Need custom progress signals | User-defined data |
| Multiple modes | Need combined data | Array of modes |
import { ChatOpenAI } from "@langchain/openai";
const model = new ChatOpenAI({ model: "gpt-4.1" });
// Stream tokens as they arrive
const stream = await model.stream("Explain quantum computing in simple terms");
for await (const chunk of stream) {
process.stdout.write(chunk.content);
}
// Output appears progressively: "Quantum" "computing" "is" ...
import { createAgent } from "langchain";
const agent = createAgent({
model: "gpt-4.1",
tools: [searchTool, calculatorTool],
});
// Stream agent steps with "updates" mode
for await (const chunk of await agent.stream(
{ messages: [{ role: "user", content: "Search for AI news and summarize" }] },
{ streamMode: "updates" }
)) {
console.log("Step:", JSON.stringify(chunk, null, 2));
}
// Shows each step: model call, tool execution, final response
import { createAgent } from "langchain";
const agent = createAgent({
model: "gpt-4.1",
tools: [searchTool],
});
// Stream both LLM tokens AND agent progress
for await (const [mode, chunk] of await agent.stream(
{ messages: [{ role: "user", content: "Research LangChain" }] },
{ streamMode: ["updates", "messages"] }
)) {
if (mode === "messages") {
// LLM token stream
const [token, metadata] = chunk;
if (token.content) {
process.stdout.write(token.content);
}
} else if (mode === "updates") {
// Agent step updates
console.log("\nStep update:", chunk);
}
}
import { createAgent } from "langchain";
const agent = createAgent({
model: "gpt-4.1",
tools: [weatherTool],
});
// Get full state after each step
for await (const state of await agent.stream(
{ messages: [{ role: "user", content: "What's the weather?" }] },
{ streamMode: "values" }
)) {
console.log("Current messages:", state.messages.length);
console.log("Last message:", state.messages[state.messages.length - 1].content);
}
import { tool } from "langchain";
import { z } from "zod";
const processData = tool(
async ({ data }, { runtime }) => {
const total = data.length;
for (let i = 0; i < total; i += 100) {
// Emit custom progress update
await runtime.stream_writer.write({
type: "progress",
data: {
processed: i,
total: total,
percentage: (i / total) * 100,
},
});
// Do actual processing
await processChunk(data.slice(i, i + 100));
}
return "Processing complete";
},
{
name: "process_data",
description: "Process data with progress updates",
schema: z.object({
data: z.array(z.any()),
}),
}
);
// Stream custom updates
for await (const [mode, chunk] of await agent.stream(
{ messages: [{ role: "user", content: "Process this data" }] },
{ streamMode: ["custom", "updates"] }
)) {
if (mode === "custom") {
console.log(`Progress: ${chunk.data.percentage}%`);
}
}
import { createAgent } from "langchain";
const agent = createAgent({
model: "gpt-4.1",
tools: [searchTool],
});
// Express.js endpoint
app.post("/api/chat", async (req, res) => {
// Set headers for Server-Sent Events
res.setHeader("Content-Type", "text/event-stream");
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Connection", "keep-alive");
try {
for await (const [mode, chunk] of await agent.stream(
{ messages: req.body.messages },
{ streamMode: ["messages", "updates"] }
)) {
if (mode === "messages") {
const [token, metadata] = chunk;
if (token.content) {
// Send token to client
res.write(`data: ${JSON.stringify({ type: "token", content: token.content })}\n\n`);
}
} else if (mode === "updates") {
// Send step update to client
res.write(`data: ${JSON.stringify({ type: "step", data: chunk })}\n\n`);
}
}
res.write("data: [DONE]\n\n");
res.end();
} catch (error) {
res.write(`data: ${JSON.stringify({ type: "error", message: error.message })}\n\n`);
res.end();
}
});
import { createAgent } from "langchain";
const agent = createAgent({
model: "gpt-4.1",
tools: [riskyTool],
});
try {
for await (const chunk of await agent.stream(
{ messages: [{ role: "user", content: "Do risky operation" }] },
{ streamMode: "updates" }
)) {
// Check for errors in updates
if ("__error__" in chunk) {
console.error("Error in stream:", chunk.__error__);
break;
}
console.log("Update:", chunk);
}
} catch (error) {
console.error("Stream error:", error);
}
import { createAgent } from "langchain";
const agent = createAgent({
model: "gpt-4.1",
tools: [slowTool],
});
async function streamWithTimeout(timeoutMs: number) {
const timeout = setTimeout(() => {
throw new Error(`Stream timeout after ${timeoutMs}ms`);
}, timeoutMs);
try {
for await (const chunk of await agent.stream(
{ messages: [{ role: "user", content: "Do something slow" }] },
{ streamMode: "updates" }
)) {
clearTimeout(timeout);
console.log(chunk);
// Reset timeout for next chunk
timeout.setTimeout(() => {
throw new Error(`Stream timeout after ${timeoutMs}ms`);
}, timeoutMs);
}
} finally {
clearTimeout(timeout);
}
}
import { ChatOpenAI } from "@langchain/openai";
const model = new ChatOpenAI({ model: "gpt-4.1" });
let buffer = "";
const stream = await model.stream("Write a long essay");
for await (const chunk of stream) {
buffer += chunk.content;
// Update UI every 10 characters or on complete words
if (buffer.length >= 10 || chunk.content.includes(" ")) {
console.log(buffer);
buffer = "";
}
}
// Flush remaining buffer
if (buffer) {
console.log(buffer);
}
✅ Stream modes: Choose which data to stream ✅ Multiple modes: Combine different stream types ✅ Custom updates: Emit user-defined progress data ✅ Chunk processing: Handle each chunk as needed ✅ Error handling: Catch and handle stream errors
❌ Chunk size: Determined by model/provider ❌ Chunk timing: Arrives as provider sends ❌ Guarantee order: Async streams may vary ❌ Modify past chunks: Chunks are immutable
// ❌ Problem: Missing await
const stream = agent.stream(input, { streamMode: "updates" });
for await (const chunk of stream) { // Error: stream is Promise!
console.log(chunk);
}
// ✅ Solution: Await stream initialization
const stream = await agent.stream(input, { streamMode: "updates" });
for await (const chunk of stream) {
console.log(chunk);
}
// ❌ Problem: Wrong property for messages mode
for await (const chunk of await agent.stream(input, { streamMode: "messages" })) {
console.log(chunk.content); // undefined!
}
// ✅ Solution: Messages mode returns [token, metadata] tuple
for await (const chunk of await agent.stream(input, { streamMode: "messages" })) {
const [token, metadata] = chunk;
console.log(token.content); // Correct!
}
// ❌ Problem: Using wrong mode for tokens
for await (const chunk of await agent.stream(input, { streamMode: "updates" })) {
console.log(chunk.content); // Not how updates work!
}
// ✅ Solution: Use "messages" mode for tokens
for await (const chunk of await agent.stream(input, { streamMode: "messages" })) {
const [token, metadata] = chunk;
console.log(token.content);
}
// ❌ Problem: Not properly cleaning up
for await (const chunk of await agent.stream(input)) {
if (someCondition) {
break; // Stream may not clean up properly
}
}
// ✅ Solution: Use try/finally or explicit cleanup
const stream = await agent.stream(input);
try {
for await (const chunk of stream) {
if (someCondition) {
break;
}
}
} finally {
// Cleanup if needed
}
// ❌ Problem: Not handling different modes
for await (const chunk of await agent.stream(
input,
{ streamMode: ["updates", "messages"] }
)) {
console.log(chunk); // Which mode is this?
}
// ✅ Solution: Destructure mode
for await (const [mode, chunk] of await agent.stream(
input,
{ streamMode: ["updates", "messages"] }
)) {
if (mode === "messages") {
const [token, metadata] = chunk;
console.log(token.content);
} else if (mode === "updates") {
console.log("Step:", chunk);
}
}
Using the Deep Agents CLI - terminal interface, persistent memory with AGENTS.md, project conventions, skills directories, and CLI commands.
Understanding Deep Agents framework - what they are, how to create them with createDeepAgent, and the agent harness architecture with built-in middleware for planning, filesystems, and subagents.
Creating and using custom skills with progressive disclosure, SKILL.md format, and the Agent Skills protocol in Deep Agents.
Using the Deep Agents CLI - terminal interface, persistent memory with AGENTS.md, project conventions, skills directories, and CLI commands.
Using FilesystemMiddleware with virtual filesystems, backends (State, Store, Filesystem, Composite), and context management for Deep Agents.
Using FilesystemMiddleware with virtual filesystems, backends (State, Store, Filesystem, Composite), and context management for Deep Agents.