web用例集合
环境安装
npm i @langchain/core
Node环境安装
npm i langchain⚠️:如果在 web 环境直接引用
langchain,会出现报错:Uncaught TypeError: import_browser_external_node_async_hooks.AsyncLocalStorage is not a constructor
Chat Model 格外安装
deepseek:@langchain/deepseekopenai:@langchain/openaigemini:@langchain/google-genai
Chat 基础对话
import { HumanMessage } from '@langchain/core/messages'
import { ChatDeepSeek } from '@langchain/deepseek'
async function main() {
// 初始化模型
const model = new ChatDeepSeek({
apiKey: process.env.DEEPSEEK_API_KEY,
model: 'deepseek-chat'
})
// invoke调用
const result = await model.invoke([
new HumanMessage('你好')
])
// AIMessage
console.log(result)
}
Chat 基础流式对话
import { HumanMessage } from '@langchain/core/messages'
import { ChatDeepSeek } from '@langchain/deepseek'
async function main() {
const model = new ChatDeepSeek({
apiKey: process.env.DEEPSEEK_API_KEY,
model: 'deepseek-chat',
streaming: true // 使用流式输出
})
const stream = await baseModel.stream([
new HumanMessage('你是谁?')
])
// 汇总AI返回
let content = ''
for await (const chunk of stream) {
let chunkText = ''
// 尝试多种方式获取内容
if (typeof chunk.content === 'string') {
chunkText = chunk.content
} else if (Array.isArray(chunk.content)) {
// 处理多模态内容数组
chunkText = chunk.content
.map((item: any) => {
if (typeof item === 'string') return item
if (item && typeof item === 'object' && item.type === 'text' && item.text) {
return item.text
}
return ''
})
.join('')
} else if (chunk.content) {
chunkText = String(chunk.content)
}
if (chunkText) {
content += chunkText
}
}
console.log(content)
}
main()
结构化输出
一、withStructuredOutput
import { z } from 'zod'
import { HumanMessage } from '@langchain/core/messages'
import { ChatDeepSeek } from '@langchain/deepseek'
async function main() {
// 定义结构
const schema = z.object({
name: z.string().describe('你的名字'),
age: z.number().describe('你的年龄'),
})
const baseModel = new ChatDeepSeek({
apiKey: process.env.DEEPSEEK_API_KEY,
model: 'deepseek-chat'
})
// 绑定结构
const model = baseModel.withStructuredOutput(schema)
const result = await model.invoke([
new HumanMessage('你是谁?')
])
// {name: 'AI助手', age: 0}
console.log(result)
}
main()
二、StructuredOutputParser
import { z } from 'zod'
import { HumanMessage } from '@langchain/core/messages'
import { ChatDeepSeek } from '@langchain/deepseek'
import { StructuredOutputParser } from '@langchain/core/output_parsers'
async function main() {
// 定义结构
const schema = z.object({
name: z.string().describe('你的名字'),
age: z.number().describe('你的年龄'),
})
// 构建 StructuredOutputParser
const parser = StructuredOutputParser.fromZodSchema(schema)
// 获取规范输出的提示词
const formatInstructions = parser.getFormatInstructions()
const model = new ChatDeepSeek({
apiKey: process.env.DEEPSEEK_API_KEY,
model: 'deepseek-chat'
})
// 在提示词中加入规范输出的提示词
const result = await model.invoke([
new HumanMessage(`你是谁?\n\n输出要求:\n${formatInstructions}`)
])
// 使用 StructuredOutputParser 解析 AI 输出内容
const output = await parser.parse(result.content as string)
// {name: 'DeepSeek', age: 2}
console.log(output)
}
Agent
⚠️:langchain 的 agent 是不支持、不建议在 web 环境使用 agent 的
如果一定要在 web 环境使用,需要给打包器注入
node:async_hooks、async_hooks的 polyfills// async_hooks.ts export class AsyncLocalStorage<T = unknown> { private _store: T | undefined getStore(): T | undefined { return this._store } enterWith(store: T) { this._store = store } disable() { this._store = undefined } run<R>(store: T, callback: (...args: any[]) => R, ...args: any[]): R { const prev = this._store this._store = store try { return callback(...args) } finally { this._store = prev } } }// vite.config.ts export default defineConfig({ resolve: { alias: { 'node:async_hooks': path.resolve(__dirname, 'polyfills/async_hooks.ts'), 'async_hooks': path.resolve(__dirname, 'polyfills/async_hooks.ts'), } } })
普通输出
import { HumanMessage } from '@langchain/core/messages'
import { ChatDeepSeek } from '@langchain/deepseek'
import { createAgent } from 'langchain'
async function main() {
const model = new ChatDeepSeek({
apiKey: process.env.DEEPSEEK_API_KEY,
model: 'deepseek-chat'
})
const agent = createAgent({
model: model,
tools: [],
})
const result = await agent.invoke({
messages: [
new HumanMessage('你是谁?')
]
})
// [HumanMessage, AIMessage]
console.log(result)
}
工具调用
import { z } from 'zod'
import { HumanMessage } from '@langchain/core/messages'
import { ChatDeepSeek } from '@langchain/deepseek'
import { DynamicStructuredTool } from '@langchain/core/tools'
import { createAgent } from 'langchain'
async function main() {
const model = new ChatDeepSeek({
apiKey: process.env.DEEPSEEK_API_KEY,
model: 'deepseek-chat'
})
// 创建工具
const mockTool = new DynamicStructuredTool({
name: 'weather',
description: 'Get the weather of a city',
func: async (city: string) => {
return `The weather of ${city} is sunny`
},
schema: z.object({
city: z.string().describe('The city to get the weather of')
})
})
const agent = createAgent({
model: model,
tools: [mockTool], // 注入工具
})
const result = await agent.invoke({
messages: [
new HumanMessage('今天北京天气怎么样?')
]
})
// [HumangMessage, AIMessage, ToolMessage, AIMessage]
console.log(result)
}
main()
工具 + 结构化输出
官方说如下使用,但是亲测不太好用,有些模型可能入参的key不叫这个,有的会和tools冲突
const agent = createAgent({ model: "gpt-5", tools: [], responseFormat: providerStrategy(schema) });
import { z } from 'zod'
import { AIMessage, HumanMessage } from '@langchain/core/messages'
import { ChatDeepSeek } from '@langchain/deepseek'
import { DynamicStructuredTool } from '@langchain/core/tools'
import { createAgent } from 'langchain'
import { StructuredOutputParser } from '@langchain/core/output_parsers'
async function main() {
const model = new ChatDeepSeek({
apiKey: process.env.DEEPSEEK_API_KEY,
model: 'deepseek-chat'
})
const mockTool = new DynamicStructuredTool({
name: 'weather',
description: 'Get the weather of a city',
func: async (city: string) => {
return `The weather of ${city} is sunny`
},
schema: z.object({
city: z.string().describe('The city to get the weather of')
})
})
// 使用 StructuredOutputParser
const schema = z.object({
weather: z.string().describe('The weather of the city'),
description: z.string().describe('The description of the weather')
})
const parser = StructuredOutputParser.fromZodSchema(schema)
const formatInstructions = parser.getFormatInstructions()
const agent = createAgent({
model: model,
tools: [mockTool],
})
const result = await agent.invoke({
messages: [
new HumanMessage(`今天北京天气怎么样?\n\n输出要求:\n${formatInstructions}`)
]
})
const lastMessage = result.messages[result.messages.length - 1] as AIMessage
const output = await parser.parse(lastMessage.content as string)
// {weather: 'sunny', description: '北京今天天气晴朗'}
console.log(output)
}
main()
记忆
import { HumanMessage } from '@langchain/core/messages'
import { ChatDeepSeek } from '@langchain/deepseek'
import { createAgent } from 'langchain'
import { MemorySaver } from '@langchain/langgraph'
// 在内存中创建记忆管理
const checkpointer = new MemorySaver()
async function main() {
const model = new ChatDeepSeek({
apiKey: process.env.DEEPSEEK_API_KEY,
model: 'deepseek-chat',
})
const agent = createAgent({
model: model,
tools: [],
checkpointer // 追加记忆管理
})
await agent.invoke({
messages: [
new HumanMessage(`我叫小明`)
],
// 请求时带上 thread_id
}, { configurable: { thread_id: "1" } })
const result = await agent.invoke({
messages: [
new HumanMessage(`我叫什么名字?`)
],
}, { configurable: { thread_id: "1" } })
// [HumanMessage, AIMessage, HumanMessage, AIMessage(你刚刚告诉我,你的名字是**小明**!😊)]
console.log(result)
}
main()