> ## Documentation Index
> Fetch the complete documentation index at: https://friendli.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# LangChain Node.js SDK

> Utilize the LangChain Node.js SDK with FriendliAI for seamless integration and enhanced tool calling capabilities in your applications.

You can use [**LangChain Node.js SDK**](https://github.com/langchain-ai/langchainjs) 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](https://friendli.ai/suite/~/setting/keys).
FriendliAI is fully compatible with OpenAI, so you can use the `@langchain/openai` package by pointing it at the FriendliAI `baseURL`.

<CodeGroup>
  ```bash npm theme={null}
  npm i @langchain/core @langchain/openai
  ```

  ```bash yarn theme={null}
  yarn add @langchain/core @langchain/openai
  ```

  ```bash pnpm theme={null}
  pnpm add @langchain/core @langchain/openai
  ```
</CodeGroup>

### Instantiation

Now you can instantiate the model object and generate chat completions.
Choose the example for your endpoint type:

<CodeGroup>
  ```js Model APIs theme={null}
  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",
    },
  });
  ```

  ```js Dedicated Endpoints theme={null}
  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",
    },
  });
  ```

  ```js Fine-tuned Dedicated Endpoints theme={null}
  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",
    },
  });
  ```
</CodeGroup>

### Runnable Interface

FriendliAI supports both synchronous and asynchronous runnable methods to generate a response.

```js theme={null}
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.

```javascript theme={null}
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.

```javascript theme={null}
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.

<CodeGroup>
  ```bash npm theme={null}
  npm i zod
  ```

  ```bash yarn theme={null}
  yarn add zod
  ```

  ```bash pnpm theme={null}
  pnpm add zod
  ```
</CodeGroup>

```js theme={null}
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.

```js theme={null}
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.

```js theme={null}
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](https://js.langchain.com/v0.2/docs/how_to/#tools).
