Skip to main content
You can use LangChain Node.js SDK to interact with FriendliAI. This makes migration of existing applications already using LangChain particularly easy.

How to Use

Before you start, ensure you’ve already obtained the API_KEY from the Friendli Suite > Personal Settings > API Keys. FriendliAI is fully compatible with OpenAI, so you can use the @langchain/openai package by pointing it at the FriendliAI baseURL.
npm i @langchain/core @langchain/openai
yarn add @langchain/core @langchain/openai
pnpm add @langchain/core @langchain/openai

Instantiation

Now you can instantiate the model object and generate chat completions. Choose the example for your endpoint type:
import { ChatOpenAI } from "@langchain/openai";

const model = new ChatOpenAI({
  model: "zai-org/GLM-5.2",
  apiKey: process.env.API_KEY,
  configuration: {
    baseURL: "https://api.friendli.ai/serverless/v1",
  },
});
import { ChatOpenAI } from "@langchain/openai";

const model = new ChatOpenAI({
  model: "YOUR_ENDPOINT_ID",
  apiKey: process.env.API_KEY,
  configuration: {
    baseURL: "https://api.friendli.ai/dedicated/v1",
  },
});
import { ChatOpenAI } from "@langchain/openai";

const model = new ChatOpenAI({
  model: "YOUR_ENDPOINT_ID:YOUR_ADAPTER_ROUTE",
  apiKey: process.env.API_KEY,
  configuration: {
    baseURL: "https://api.friendli.ai/dedicated/v1",
  },
});

Runnable Interface

FriendliAI supports both synchronous and asynchronous runnable methods to generate a response.
import { HumanMessage, SystemMessage } from "@langchain/core/messages";

const messages = [
  new SystemMessage("Translate the following from English into Italian"),
  new HumanMessage("hi!"),
];

const result = await model.invoke(messages);
console.log(result);

Chaining

You can chain the model with a prompt template. Prompt templates convert raw user input to better input to the LLM.
import { ChatPromptTemplate } from "@langchain/core/prompts";

const prompt = ChatPromptTemplate.fromMessages([
  ["system", "You are a world class technical documentation writer."],
  ["user", "{input}"],
]);

const chain = prompt.pipe(model);

console.log(
  await chain.invoke({ input: "how can langsmith help with testing?" })
);
To get the string value instead of the message, add an output parser to the chain.
import { StringOutputParser } from "@langchain/core/output_parsers";

const outputParser = new StringOutputParser();

const chain = prompt.pipe(model).pipe(outputParser);

console.log(
  await chain.invoke({ input: "how can langsmith help with testing?" })
);

Tool Calling

Describe tools and their parameters, and let the model return a tool to invoke with the input arguments. Tool calling is extremely useful for enhancing the model’s capability to provide more comprehensive and actionable responses.

Define Tools to Use

You can define tools with Zod schemas and use them to generate tool calls.
npm i zod
yarn add zod
pnpm add zod
import { tool } from "@langchain/core/tools";
import { z } from "zod";

/**
 * Note that the descriptions here are crucial, as they will be passed along
 * to the model along with the class name.
 */
const calculatorSchema = z.object({
  operation: z
    .enum(["add", "subtract", "multiply", "divide"])
    .describe("The type of operation to execute."),
  number1: z.number().describe("The first number to operate on."),
  number2: z.number().describe("The second number to operate on."),
});

const calculatorTool = tool(
  async ({ operation, number1, number2 }) => {
    // Functions must return strings
    if (operation === "add") {
      return `${number1 + number2}`;
    } else if (operation === "subtract") {
      return `${number1 - number2}`;
    } else if (operation === "multiply") {
      return `${number1 * number2}`;
    } else if (operation === "divide") {
      return `${number1 / number2}`;
    } else {
      throw new Error("Invalid operation.");
    }
  },
  {
    name: "calculator",
    description: "Can perform mathematical operations.",
    schema: calculatorSchema,
  }
);

console.log(
  await calculatorTool.invoke({ operation: "add", number1: 3, number2: 4 })
);

Bind Tools to the Model

Now models can generate a tool calling response.
const modelWithTools = model.bindTools([calculatorTool]);

const messages = [new HumanMessage("What is 3 * 12? Also, what is 11 + 49?")];

const aiMessage = await modelWithTools.invoke(messages);

console.log(aiMessage);

Generate a Tool-Assisted Message

Use the tool call results to generate a message.
messages.push(aiMessage);

const toolsByName = {
  calculator: calculatorTool,
};

for (const toolCall of aiMessage.tool_calls) {
  const selectedTool = toolsByName[toolCall.name];
  const toolMessage = await selectedTool.invoke(toolCall);
  messages.push(toolMessage);
}

console.log(await modelWithTools.invoke(messages));
For more information on how to use tools, check out the LangChain documentation.
Last modified on July 1, 2026