ChatOpenAI
This will help you getting started with ChatOpenAI chat models. For detailed documentation of all ChatOpenAI features and configurations head to the API reference.
Overviewβ
Integration detailsβ
| Class | Package | Local | Serializable | PY support | Package downloads | Package latest | 
|---|---|---|---|---|---|---|
| ChatOpenAI | @langchain/openai | β | β | β |  |  | 
Model featuresβ
| Tool calling | Structured output | JSON mode | Image input | Audio input | Video input | Token-level streaming | Token usage | Logprobs | 
|---|---|---|---|---|---|---|---|---|
| β | β | β | β | β | β | β | β | β | 
Setupβ
To access ChatOpenAI models youβll need to create a ChatOpenAI account,
get an API key, and install the @langchain/openai integration package.
Credentialsβ
Head to OpenAIβs website to sign up to
ChatOpenAI and generate an API key. Once youβve done this set the
OPENAI_API_KEY environment variable:
export OPENAI_API_KEY="your-api-key"
If you want to get automated tracing of your model calls you can also set your LangSmith API key by uncommenting below:
# export LANGCHAIN_TRACING_V2="true"
# export LANGCHAIN_API_KEY="your-api-key"
Installationβ
The LangChain ChatOpenAI integration lives in the @langchain/openai
package:
- npm
- yarn
- pnpm
npm i @langchain/openai
yarn add @langchain/openai
pnpm add @langchain/openai
Instantiationβ
Now we can instantiate our model object and generate chat completions:
import { ChatOpenAI } from "@langchain/openai";
const llm = new ChatOpenAI({
  model: "gpt-4o",
  temperature: 0,
  maxTokens: undefined,
  timeout: undefined,
  maxRetries: 2,
  // other params...
});
Invocationβ
const aiMsg = await llm.invoke([
  [
    "system",
    "You are a helpful assistant that translates English to French. Translate the user sentence.",
  ],
  ["human", "I love programming."],
]);
aiMsg;
AIMessage {
  "id": "chatcmpl-9rB4GvhlRb0x3hxupLBQYOKKmTxvV",
  "content": "J'adore la programmation.",
  "additional_kwargs": {},
  "response_metadata": {
    "tokenUsage": {
      "completionTokens": 8,
      "promptTokens": 31,
      "totalTokens": 39
    },
    "finish_reason": "stop"
  },
  "tool_calls": [],
  "invalid_tool_calls": [],
  "usage_metadata": {
    "input_tokens": 31,
    "output_tokens": 8,
    "total_tokens": 39
  }
}
console.log(aiMsg.content);
J'adore la programmation.
Chainingβ
We can chain our model with a prompt template like so:
import { ChatPromptTemplate } from "@langchain/core/prompts";
const prompt = ChatPromptTemplate.fromMessages([
  [
    "system",
    "You are a helpful assistant that translates {input_language} to {output_language}.",
  ],
  ["human", "{input}"],
]);
const chain = prompt.pipe(llm);
await chain.invoke({
  input_language: "English",
  output_language: "German",
  input: "I love programming.",
});
AIMessage {
  "id": "chatcmpl-9rB4JD9rVBLzTuMee9AabulowEH0d",
  "content": "Ich liebe das Programmieren.",
  "additional_kwargs": {},
  "response_metadata": {
    "tokenUsage": {
      "completionTokens": 6,
      "promptTokens": 26,
      "totalTokens": 32
    },
    "finish_reason": "stop"
  },
  "tool_calls": [],
  "invalid_tool_calls": [],
  "usage_metadata": {
    "input_tokens": 26,
    "output_tokens": 6,
    "total_tokens": 32
  }
}
Multimodal messagesβ
This feature is currently in preview. The message schema may change in future releases.
OpenAI supports interleaving images with text in input messages with
their gpt-4-vision-preview. Hereβs an example of how this looks:
import * as fs from "node:fs/promises";
import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage } from "@langchain/core/messages";
const imageData2 = await fs.readFile("../../../../../examples/hotdog.jpg");
const llm2 = new ChatOpenAI({
  model: "gpt-4-vision-preview",
  maxTokens: 1024,
  apiKey: process.env.OPENAI_API_KEY,
});
const message2 = new HumanMessage({
  content: [
    {
      type: "text",
      text: "What's in this image?",
    },
    {
      type: "image_url",
      image_url: {
        url: `data:image/jpeg;base64,${imageData2.toString("base64")}`,
      },
    },
  ],
});
const res2 = await llm2.invoke([message2]);
console.log(res2);
AIMessage {
  "id": "chatcmpl-9rB59AKTPDrSHuTv0y7BNUcM0QDV2",
  "content": "The image shows a classic hot dog, consisting of a grilled or steamed sausage served in the slit of a partially sliced bun. The sausage appears to have grill marks, indicating it may have been cooked on a grill. This is a typical and popular snack or fast food item often enjoyed at sporting events, barbecues, and fairs.",
  "additional_kwargs": {},
  "response_metadata": {
    "tokenUsage": {
      "completionTokens": 69,
      "promptTokens": 438,
      "totalTokens": 507
    },
    "finish_reason": "stop"
  },
  "tool_calls": [],
  "invalid_tool_calls": [],
  "usage_metadata": {
    "input_tokens": 438,
    "output_tokens": 69,
    "total_tokens": 507
  }
}
const hostedImageMessage3 = new HumanMessage({
  content: [
    {
      type: "text",
      text: "What does this image say?",
    },
    {
      type: "image_url",
      image_url:
        "https://www.freecodecamp.org/news/content/images/2023/05/Screenshot-2023-05-29-at-5.40.38-PM.png",
    },
  ],
});
const res3 = await llm2.invoke([hostedImageMessage3]);
console.log(res3);
AIMessage {
  "id": "chatcmpl-9rB5EWz5AyOHg6UiFkt4HC8H4UZJu",
  "content": "The image contains text that reads \"LangChain\". Additionally, there is an illustration of a parrot on the left side and two interlinked rings on the right.",
  "additional_kwargs": {},
  "response_metadata": {
    "tokenUsage": {
      "completionTokens": 33,
      "promptTokens": 778,
      "totalTokens": 811
    },
    "finish_reason": "stop"
  },
  "tool_calls": [],
  "invalid_tool_calls": [],
  "usage_metadata": {
    "input_tokens": 778,
    "output_tokens": 33,
    "total_tokens": 811
  }
}
const lowDetailImage4 = new HumanMessage({
  content: [
    {
      type: "text",
      text: "Summarize the contents of this image.",
    },
    {
      type: "image_url",
      image_url: {
        url: "https://blog.langchain.dev/content/images/size/w1248/format/webp/2023/10/Screenshot-2023-10-03-at-4.55.29-PM.png",
        detail: "low",
      },
    },
  ],
});
const res4 = await llm2.invoke([lowDetailImage4]);
console.log(res4);
AIMessage {
  "id": "chatcmpl-9rB5IUbzvMo5nsOGYW3jvrQjaCiCg",
  "content": "The image shows a user interface of a digital service or platform called \"WebLangChain\" which appears to be powered by \"Tailify.\" There is a prompt that encourages users to \"Ask me anything about anything!\" Alongside this, there is a text input field labeled \"Ask anything...\" which also features some example questions or search queries such as \"what is langchain?\", \"history of mesopotamia\", \"how to build a discord bot\", \"leonardo dicaprio girlfriend\", \"fun gift ideas for software engineers\", \"how does a prism separate light\", and \"what bear is best\". The overall design is clean, with a dark background and a send button represented by a blue icon with a paper airplane, which typically symbolizes sending a message or submitting a query.",
  "additional_kwargs": {},
  "response_metadata": {
    "tokenUsage": {
      "completionTokens": 158,
      "promptTokens": 101,
      "totalTokens": 259
    },
    "finish_reason": "stop"
  },
  "tool_calls": [],
  "invalid_tool_calls": [],
  "usage_metadata": {
    "input_tokens": 101,
    "output_tokens": 158,
    "total_tokens": 259
  }
}
Tool callingβ
OpenAI chat models support calling multiple functions to get all required data to answer a question. Hereβs an example how a conversation turn with this functionality might look:
import { ChatOpenAI } from "@langchain/openai";
// Bind function to the model as a tool
const llm5 = new ChatOpenAI({
  model: "gpt-3.5-turbo-1106",
  maxTokens: 128,
}).bind({
  tools: [
    {
      type: "function",
      function: {
        name: "get_current_weather",
        description: "Get the current weather in a given location",
        parameters: {
          type: "object",
          properties: {
            location: {
              type: "string",
              description: "The city and state, e.g. San Francisco, CA",
            },
            unit: { type: "string", enum: ["celsius", "fahrenheit"] },
          },
          required: ["location"],
        },
      },
    },
  ],
  tool_choice: "auto",
});
// Ask initial question that requires multiple tool calls
const res5 = await llm5.invoke([
  ["human", "What's the weather like in San Francisco, Tokyo, and Paris?"],
]);
console.log(res5.tool_calls);
[
  {
    name: 'get_current_weather',
    args: { location: 'San Francisco', unit: 'celsius' },
    type: 'tool_call',
    id: 'call_2ytmjITA18j3kLOzzjF5QSC4'
  },
  {
    name: 'get_current_weather',
    args: { location: 'Tokyo', unit: 'celsius' },
    type: 'tool_call',
    id: 'call_3sU2dCNZ8e8A8wrYlYa7Xq0G'
  },
  {
    name: 'get_current_weather',
    args: { location: 'Paris', unit: 'celsius' },
    type: 'tool_call',
    id: 'call_Crmc0QG4x1VHRUyiwPsqzmQS'
  }
]
import { ToolMessage } from "@langchain/core/messages";
// Mocked out function, could be a database/API call in production
function getCurrentWeather(location: string, _unit?: string) {
  if (location.toLowerCase().includes("tokyo")) {
    return JSON.stringify({ location, temperature: "10", unit: "celsius" });
  } else if (location.toLowerCase().includes("san francisco")) {
    return JSON.stringify({
      location,
      temperature: "72",
      unit: "fahrenheit",
    });
  } else {
    return JSON.stringify({ location, temperature: "22", unit: "celsius" });
  }
}
// Format the results from calling the tool calls back to OpenAI as ToolMessages
const toolMessages5 = res5.additional_kwargs.tool_calls?.map((toolCall) => {
  const toolCallResult5 = getCurrentWeather(
    JSON.parse(toolCall.function.arguments).location
  );
  return new ToolMessage({
    tool_call_id: toolCall.id,
    name: toolCall.function.name,
    content: toolCallResult5,
  });
});
// Send the results back as the next step in the conversation
const finalResponse5 = await llm5.invoke([
  ["human", "What's the weather like in San Francisco, Tokyo, and Paris?"],
  res5,
  ...(toolMessages5 ?? []),
]);
console.log(finalResponse5);
AIMessage {
  "id": "chatcmpl-9rB5Sc3ERHpRymmAAsGS67zczVhAl",
  "content": "The current weather in:\n- San Francisco is 72Β°F\n- Tokyo is 10Β°C\n- Paris is 22Β°C",
  "additional_kwargs": {},
  "response_metadata": {
    "tokenUsage": {
      "completionTokens": 27,
      "promptTokens": 236,
      "totalTokens": 263
    },
    "finish_reason": "stop",
    "system_fingerprint": "fp_adbef9f124"
  },
  "tool_calls": [],
  "invalid_tool_calls": [],
  "usage_metadata": {
    "input_tokens": 236,
    "output_tokens": 27,
    "total_tokens": 263
  }
}
.withStructuredOutput({ ... })β
You can also use the .withStructuredOutput({ ... }) method to coerce
ChatOpenAI into returning a structured output.
The method allows for passing in either a Zod object, or a valid JSON
schema (like what is returned from
zodToJsonSchema).
Using the method is simple. Just define your LLM and call
.withStructuredOutput({ ... }) on it, passing the desired schema.
Here is an example using a Zod schema and the functionCalling mode
(default mode):
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { ChatOpenAI } from "@langchain/openai";
import { z } from "zod";
const llm6 = new ChatOpenAI({
  temperature: 0,
  model: "gpt-4-turbo-preview",
});
const calculatorSchema6 = z.object({
  operation: z.enum(["add", "subtract", "multiply", "divide"]),
  number1: z.number(),
  number2: z.number(),
});
const modelWithStructuredOutput6 = llm6.withStructuredOutput(calculatorSchema6);
const prompt6 = ChatPromptTemplate.fromMessages([
  ["system", "You are VERY bad at math and must always use a calculator."],
  ["human", "Please help me!! What is 2 + 2?"],
]);
const chain6 = prompt6.pipe(modelWithStructuredOutput6);
const result6 = await chain6.invoke({});
console.log(result6);
{ operation: 'add', number1: 2, number2: 2 }
You can also specify includeRaw to return the parsed and raw output in
the result.
const includeRawModel6 = llm6.withStructuredOutput(calculatorSchema6, {
  name: "calculator",
  includeRaw: true,
});
const includeRawChain6 = prompt6.pipe(includeRawModel6);
const includeRawResult6 = await includeRawChain6.invoke({});
console.log(includeRawResult6);
{
  raw: AIMessage {
    "id": "chatcmpl-9rB5emIYRslBFrUIsC2368dXltljw",
    "content": "",
    "additional_kwargs": {
      "tool_calls": [
        {
          "id": "call_JaH5OB3KYvKF76TUOt6Lp8mu",
          "type": "function",
          "function": "[Object]"
        }
      ]
    },
    "response_metadata": {
      "tokenUsage": {
        "completionTokens": 15,
        "promptTokens": 93,
        "totalTokens": 108
      },
      "finish_reason": "stop"
    },
    "tool_calls": [
      {
        "name": "calculator",
        "args": {
          "number1": 2,
          "number2": 2,
          "operation": "add"
        },
        "type": "tool_call",
        "id": "call_JaH5OB3KYvKF76TUOt6Lp8mu"
      }
    ],
    "invalid_tool_calls": [],
    "usage_metadata": {
      "input_tokens": 93,
      "output_tokens": 15,
      "total_tokens": 108
    }
  },
  parsed: { operation: 'add', number1: 2, number2: 2 }
}
Additionally, you can pass in an OpenAI function definition or JSON schema directly:
If using jsonMode as the method you must include context in your prompt about the structured output you want. This must include the keyword: JSON.
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { ChatOpenAI } from "@langchain/openai";
const llm7 = new ChatOpenAI({
  temperature: 0,
  model: "gpt-4-turbo-preview",
});
const calculatorSchema7 = {
  type: "object",
  properties: {
    operation: {
      type: "string",
      enum: ["add", "subtract", "multiply", "divide"],
    },
    number1: { type: "number" },
    number2: { type: "number" },
  },
  required: ["operation", "number1", "number2"],
};
// Default mode is "functionCalling"
const modelWithStructuredOutput7 = llm7.withStructuredOutput(calculatorSchema7);
const prompt7 = ChatPromptTemplate.fromMessages([
  [
    "system",
    `You are VERY bad at math and must always use a calculator.
Respond with a JSON object containing three keys:
'operation': the type of operation to execute, either 'add', 'subtract', 'multiply' or 'divide',
'number1': the first number to operate on,
'number2': the second number to operate on.
`,
  ],
  ["human", "Please help me!! What is 2 + 2?"],
]);
const chain7 = prompt7.pipe(modelWithStructuredOutput7);
const result7 = await chain7.invoke({});
console.log(result7);
{ number1: 2, number2: 2, operation: 'add' }
You can also specify βincludeRawβ to return the parsed and raw output in the result, as well as a βnameβ field to give the LLM additional context as to what you are generating.
const includeRawModel7 = llm7.withStructuredOutput(calculatorSchema7, {
  name: "calculator",
  includeRaw: true,
  method: "jsonMode",
});
const includeRawChain7 = prompt7.pipe(includeRawModel7);
const includeRawResult7 = await includeRawChain7.invoke({});
console.log(includeRawResult7);
{
  raw: AIMessage {
    "id": "chatcmpl-9rB5lkylQMLSP9CQ4SaQB9zGw1rP1",
    "content": "{\n  \"operation\": \"add\",\n  \"number1\": 2,\n  \"number2\": 2\n}",
    "additional_kwargs": {},
    "response_metadata": {
      "tokenUsage": {
        "completionTokens": 25,
        "promptTokens": 91,
        "totalTokens": 116
      },
      "finish_reason": "stop"
    },
    "tool_calls": [],
    "invalid_tool_calls": [],
    "usage_metadata": {
      "input_tokens": 91,
      "output_tokens": 25,
      "total_tokens": 116
    }
  },
  parsed: { operation: 'add', number1: 2, number2: 2 }
}
Disabling parallel tool callsβ
If you have multiple tools bound to the model, but youβd only like for a
single tool to be called at a time, you can pass the
parallel_tool_calls call option to enable/disable this behavior. By
default, parallel_tool_calls is set to true.
import { ChatOpenAI } from "@langchain/openai";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
const llm8 = new ChatOpenAI({
  temperature: 0,
  model: "gpt-4o",
});
// Define your tools
const calculatorSchema8 = z
  .object({
    operation: z.enum(["add", "subtract", "multiply", "divide"]),
    number1: z.number(),
    number2: z.number(),
  })
  .describe("A tool to perform basic arithmetic operations");
const weatherSchema8 = z
  .object({
    city: z.string(),
  })
  .describe("A tool to get the weather in a city");
// Bind tools to the model
const modelWithTools8 = llm8.bindTools([
  {
    type: "function",
    function: {
      name: "calculator",
      description: calculatorSchema8.description,
      parameters: zodToJsonSchema(calculatorSchema8),
    },
  },
  {
    type: "function",
    function: {
      name: "weather",
      description: weatherSchema8.description,
      parameters: zodToJsonSchema(weatherSchema8),
    },
  },
]);
// Invoke the model with `parallel_tool_calls` set to `true`
const response8 = await modelWithTools8.invoke(
  ["What is the weather in san francisco and what is 23716 times 27342?"],
  {
    parallel_tool_calls: true,
  }
);
We can see it called two tools:
console.log(response8.tool_calls);
[
  {
    name: 'weather',
    args: { city: 'san francisco' },
    type: 'tool_call',
    id: 'call_FyxazII0M0OgKMnk2UuXDhjv'
  },
  {
    name: 'calculator',
    args: { operation: 'multiply', number1: 23716, number2: 27342 },
    type: 'tool_call',
    id: 'call_raQz2ABUtVpbkruA2K6vBNYd'
  }
]
Invoke the model with parallel_tool_calls set to false
const response9 = await modelWithTools8.invoke(
  ["What is the weather in san francisco and what is 23716 times 27342?"],
  {
    parallel_tool_calls: false,
  }
);
We can see it called one tool
console.log(response9.tool_calls);
[
  {
    name: 'weather',
    args: { city: 'san francisco' },
    type: 'tool_call',
    id: 'call_xFbViRUVYj8BFnJIVedU7GVn'
  }
]
Custom URLsβ
You can customize the base URL the SDK sends requests to by passing a
configuration parameter like this:
import { ChatOpenAI } from "@langchain/openai";
const llm10 = new ChatOpenAI({
  temperature: 0.9,
  configuration: {
    baseURL: "https://your_custom_url.com",
  },
});
const message10 = await llm10.invoke("Hi there!");
You can also pass other ClientOptions parameters accepted by the
official SDK.
If you are hosting on Azure OpenAI, see the dedicated page instead.
Calling fine-tuned modelsβ
You can call fine-tuned OpenAI models by passing in your corresponding
modelName parameter.
This generally takes the form of
ft:{OPENAI_MODEL_NAME}:{ORG_NAME}::{MODEL_ID}. For example:
import { ChatOpenAI } from "@langchain/openai";
const llm11 = new ChatOpenAI({
  temperature: 0.9,
  model: "ft:gpt-3.5-turbo-0613:{ORG_NAME}::{MODEL_ID}",
});
const message11 = await llm11.invoke("Hi there!");
Generation metadataβ
If you need additional information like logprobs or token usage, these
will be returned directly in the .invoke response.
Requires @langchain/core version >=0.1.48.
import { ChatOpenAI } from "@langchain/openai";
// See https://cookbook.openai.com/examples/using_logprobs for details
const llm12 = new ChatOpenAI({
  logprobs: true,
  // topLogprobs: 5,
});
const responseMessage12 = await llm12.invoke("Hi there!");
console.dir(responseMessage12.response_metadata.logprobs, { depth: null });
{
  content: [
    {
      token: 'Hello',
      logprob: -0.0004585519,
      bytes: [ 72, 101, 108, 108, 111 ],
      top_logprobs: []
    },
    {
      token: '!',
      logprob: -0.000049305523,
      bytes: [ 33 ],
      top_logprobs: []
    },
    {
      token: ' How',
      logprob: -0.000029517714,
      bytes: [ 32, 72, 111, 119 ],
      top_logprobs: []
    },
    {
      token: ' can',
      logprob: -0.00073185476,
      bytes: [ 32, 99, 97, 110 ],
      top_logprobs: []
    },
    {
      token: ' I',
      logprob: -9.0883464e-7,
      bytes: [ 32, 73 ],
      top_logprobs: []
    },
    {
      token: ' assist',
      logprob: -0.104538105,
      bytes: [
         32,  97, 115,
        115, 105, 115,
        116
      ],
      top_logprobs: []
    },
    {
      token: ' you',
      logprob: -6.704273e-7,
      bytes: [ 32, 121, 111, 117 ],
      top_logprobs: []
    },
    {
      token: ' today',
      logprob: -0.000052643223,
      bytes: [ 32, 116, 111, 100, 97, 121 ],
      top_logprobs: []
    },
    {
      token: '?',
      logprob: -0.00001247159,
      bytes: [ 63 ],
      top_logprobs: []
    }
  ]
}
With callbacksβ
You can also use the callbacks system:
import { ChatOpenAI } from "@langchain/openai";
// See https://cookbook.openai.com/examples/using_logprobs for details
const llm13 = new ChatOpenAI({
  logprobs: true,
  // topLogprobs: 5,
});
const result13 = await llm13.invoke("Hi there!", {
  callbacks: [
    {
      handleLLMEnd(output) {
        console.dir(output.generations[0][0].generationInfo.logprobs, {
          depth: null,
        });
      },
    },
  ],
});
{
  content: [
    {
      token: 'Hello',
      logprob: -0.0005182436,
      bytes: [ 72, 101, 108, 108, 111 ],
      top_logprobs: []
    },
    {
      token: '!',
      logprob: -0.000040246043,
      bytes: [ 33 ],
      top_logprobs: []
    },
    {
      token: ' How',
      logprob: -0.000035716304,
      bytes: [ 32, 72, 111, 119 ],
      top_logprobs: []
    },
    {
      token: ' can',
      logprob: -0.0006764544,
      bytes: [ 32, 99, 97, 110 ],
      top_logprobs: []
    },
    {
      token: ' I',
      logprob: -0.0000010280384,
      bytes: [ 32, 73 ],
      top_logprobs: []
    },
    {
      token: ' assist',
      logprob: -0.12827769,
      bytes: [
         32,  97, 115,
        115, 105, 115,
        116
      ],
      top_logprobs: []
    },
    {
      token: ' you',
      logprob: -4.3202e-7,
      bytes: [ 32, 121, 111, 117 ],
      top_logprobs: []
    },
    {
      token: ' today',
      logprob: -0.000059914648,
      bytes: [ 32, 116, 111, 100, 97, 121 ],
      top_logprobs: []
    },
    {
      token: '?',
      logprob: -0.000012352386,
      bytes: [ 63 ],
      top_logprobs: []
    }
  ]
}
console.dir(result13.response_metadata.logprobs, { depth: null });
{
  content: [
    {
      token: 'Hello',
      logprob: -0.0005182436,
      bytes: [ 72, 101, 108, 108, 111 ],
      top_logprobs: []
    },
    {
      token: '!',
      logprob: -0.000040246043,
      bytes: [ 33 ],
      top_logprobs: []
    },
    {
      token: ' How',
      logprob: -0.000035716304,
      bytes: [ 32, 72, 111, 119 ],
      top_logprobs: []
    },
    {
      token: ' can',
      logprob: -0.0006764544,
      bytes: [ 32, 99, 97, 110 ],
      top_logprobs: []
    },
    {
      token: ' I',
      logprob: -0.0000010280384,
      bytes: [ 32, 73 ],
      top_logprobs: []
    },
    {
      token: ' assist',
      logprob: -0.12827769,
      bytes: [
         32,  97, 115,
        115, 105, 115,
        116
      ],
      top_logprobs: []
    },
    {
      token: ' you',
      logprob: -4.3202e-7,
      bytes: [ 32, 121, 111, 117 ],
      top_logprobs: []
    },
    {
      token: ' today',
      logprob: -0.000059914648,
      bytes: [ 32, 116, 111, 100, 97, 121 ],
      top_logprobs: []
    },
    {
      token: '?',
      logprob: -0.000012352386,
      bytes: [ 63 ],
      top_logprobs: []
    }
  ]
}
Streaming tokensβ
OpenAI supports streaming token counts via an opt-in call option. This
can be set by passing { stream_options: { include_usage: true } }.
Setting this call option will cause the model to return an additional
chunk at the end of the stream, containing the token usage.
import type { AIMessageChunk } from "@langchain/core/messages";
import { ChatOpenAI } from "@langchain/openai";
import { concat } from "@langchain/core/utils/stream";
// Instantiate the model
const llm14 = new ChatOpenAI();
const response14 = await llm14.stream("Hello, how are you?", {
  // Pass the stream options
  stream_options: {
    include_usage: true,
  },
});
// Iterate over the response, only saving the last chunk
let finalResult14: AIMessageChunk | undefined;
for await (const chunk14 of response14) {
  finalResult14 = !finalResult14 ? chunk14 : concat(finalResult14, chunk14);
}
console.log(finalResult14?.usage_metadata);
{ input_tokens: 13, output_tokens: 33, total_tokens: 46 }
API referenceβ
For detailed documentation of all ChatOpenAI features and configurations head to the API reference: https://api.js.langchain.com/classes/langchain_openai.ChatOpenAI.html