import { createAgent, createMiddleware, tool } from "langchain";import * as z from "zod";// A tool that will be added dynamically at runtimeconst calculateTip = tool( ({ billAmount, tipPercentage = 20 }) => { const tip = billAmount * (tipPercentage / 100); return `Tip: $${tip.toFixed(2)}, Total: $${(billAmount + tip).toFixed(2)}`; }, { name: "calculate_tip", description: "Calculate the tip amount for a bill", schema: z.object({ billAmount: z.number().describe("The bill amount"), tipPercentage: z.number().default(20).describe("Tip percentage"), }), });const dynamicToolMiddleware = createMiddleware({ name: "DynamicToolMiddleware", wrapModelCall: (request, handler) => { // Add dynamic tool to the request // This could be loaded from an MCP server, database, etc. return handler({ ...request, tools: [...request.tools, calculateTip], }); }, wrapToolCall: (request, handler) => { // Handle execution of the dynamic tool if (request.toolCall.name === "calculate_tip") { return handler({ ...request, tool: calculateTip }); } return handler(request); },});const agent = createAgent({ model: "gpt-4o", tools: [getWeather], // Only static tools registered here middleware: [dynamicToolMiddleware],});// The agent can now use both getWeather AND calculateTipconst result = await agent.invoke({ messages: [{ role: "user", content: "Calculate a 20% tip on $85" }],});
================================ Human Message =================================Find the most popular wireless headphones right now and check if they're in stock
================================= Tool Message =================================Product WH-1000XM5: 10 units in stock
推理:“我已经获得了最受欢迎的型号及其库存状态。现在可以回答用户的问题了。”
行动:生成最终答案
================================== Ai Message ==================================I found wireless headphones (model WH-1000XM5) with 10 units in stock...
import { createAgent } from "langchain";import { SystemMessage, HumanMessage } from "@langchain/core/messages";const literaryAgent = createAgent({ model: "google_genai:gemini-3.1-pro-preview", systemPrompt: new SystemMessage({ content: [ { type: "text", text: "You are an AI assistant tasked with analyzing literary works.", }, { type: "text", text: "<the entire contents of 'Pride and Prejudice'>", cache_control: { type: "ephemeral" } } ] })});const result = await literaryAgent.invoke({ messages: [new HumanMessage("Analyze the major themes in 'Pride and Prejudice'.")]});
const stream = await agent.stream( { messages: [{ role: "user", content: "Search for AI news and summarize the findings" }], }, { streamMode: "values" });for await (const chunk of stream) { // Each chunk contains the full state at that point const latestMessage = chunk.messages.at(-1); if (latestMessage?.content) { console.log(`Agent: ${latestMessage.content}`); } else if (latestMessage?.tool_calls) { const toolCallNames = latestMessage.tool_calls.map((tc) => tc.name); console.log(`Calling tools: ${toolCallNames.join(", ")}`); }}