> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://launchdarkly.com/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://launchdarkly.com/docs/_mcp/server.

# Node.js (server-side) AI SDK reference

> This topic documents how to get started with the Node.js (server-side) AI SDK, and links to reference information on all of the supported features. You can use either JavaScript or TypeScript when working with the Node.js (server-side) AI SDK.

This topic documents how to get started with the Node.js (server-side) AI SDK, and links to reference information on all of the supported features. You can use either JavaScript or TypeScript when working with the Node.js (server-side) AI SDK.

The Node.js (server-side) AI SDK is designed for use with AgentControl. It is currently in a pre-1.0 release and under active development. You can follow development or contribute on [GitHub](https://github.com/launchdarkly/js-core/tree/main/packages/sdk/server-ai/).

#### SDK quick links

LaunchDarkly's SDKs are open source. In addition to this reference guide, we provide source, API reference documentation, sample applications, and provider-specific packages:

<table class="fern-table">
  <tr>
    <th>
      Resource
    </th>

    <th>
      Location
    </th>
  </tr>

  <tr>
    <td>
      SDK API documentation
    </td>

    <td>
      [SDK API docs](https://launchdarkly.github.io/js-core/packages/sdk/server-ai/docs/)
    </td>
  </tr>

  <tr>
    <td>
      GitHub repository
    </td>

    <td>
      [node-server-sdk-ai](https://github.com/launchdarkly/js-core/tree/main/packages/sdk/server-ai/)
    </td>
  </tr>

  <tr>
    <td>
      Sample application
    </td>

    <td>
      [Using Bedrock](https://github.com/launchdarkly/js-core/tree/main/packages/sdk/server-ai/examples/getting-started/bedrock/converse)

      , 

      [Using OpenAI](https://github.com/launchdarkly/js-core/tree/main/packages/sdk/server-ai/examples/getting-started/openai/chat-completions)
    </td>
  </tr>

  <tr>
    <td>
      Published module
    </td>

    <td>
      [npm](https://www.npmjs.com/package/@launchdarkly/server-sdk-ai)
    </td>
  </tr>

  <tr>
    <td>
      Provider-specific packages
    </td>

    <td>
      [OpenAI](https://github.com/launchdarkly/js-core/tree/main/packages/ai-providers/server-ai-openai)

      , 

      [LangChain](https://github.com/launchdarkly/js-core/tree/main/packages/ai-providers/server-ai-langchain)

      , 

      [Vercel AI](https://github.com/launchdarkly/js-core/tree/main/packages/ai-providers/server-ai-vercel)
    </td>
  </tr>
</table>

#### For use in server-side applications only

This SDK is intended for use in multi-user Node.js server applications. To learn more about LaunchDarkly's different SDK types, read [Choosing an SDK type](/sdk/concepts/client-side-server-side).

## Get started

LaunchDarkly AI SDKs interact with [AgentControl configs](/home/getting-started/vocabulary#agentcontrol-config). Configs are the LaunchDarkly resources that manage model configurations and messages for your generative AI applications.

#### Try the Quickstart

This reference guide describes working specifically with the Node.js (server-side) AI SDK. For a complete introduction to LaunchDarkly AI SDKs and how they interact with configs, read [Quickstart for AgentControl](/home/agentcontrol/quickstart).

You can use the Node.js (server-side) AI SDK to customize your config based on the [context](/home/getting-started/vocabulary#context) that you provide. This means both the messages and the model evaluation in your generative AI application are specific to each end user, at runtime. You can also use the AI SDKs to record metrics from your AI model generation, including duration and tokens.

Follow these instructions to start using the Node.js (server-side) AI SDK in your application.

### Install the SDK

First, install the AI SDK as a dependency in your application using your application's dependency manager. If you want to depend on a specific version, refer to the [SDK releases page](https://github.com/launchdarkly/js-core/releases?q=ai) to identify the latest version.

The Node.js (server-side) AI SDK is built on the [Node.js (server-side) SDK](/sdk/server-side/node-js), so you'll need to install that as well. Alternatively, you can install a server-side [edge SDK](/sdk/edge) instead.

In addition, you can also use provider-specific AI SDK packages for better integration and improved version management with your preferred AI framework.

The following provider-specific packages are available:

* [OpenAI](https://github.com/launchdarkly/js-core/tree/main/packages/ai-providers/server-ai-openai)
* [LangChain](https://github.com/launchdarkly/js-core/tree/main/packages/ai-providers/server-ai-langchain)
* [Vercel AI](https://github.com/launchdarkly/js-core/tree/main/packages/ai-providers/server-ai-vercel)

These packages require Node.js version 16 or higher.

#### Provider-specific packages are in early development

These provider-specific packages are currently in early development and are not recommended for production use. They may change without notice, including becoming backwards incompatible.

Here's how:

#### Shell

```bash
npm install @launchdarkly/node-server-sdk
npm install @launchdarkly/server-sdk-ai
# If you want to install a provider-specific package
npm install @launchdarkly/server-sdk-ai-openai
# or
npm install @launchdarkly/server-sdk-ai-langchain
# or
npm install @launchdarkly/server-sdk-ai-vercel
```

Next, import `init`, `LDContext`, and `initAi` in your application code. If you are using TypeScript, you can optionally import the LaunchDarkly `LDAIClient` and `LDAIConfig`. These are implied, so are not strictly required.

Here's how:

#### Node.js (server-side) AI SDK (TypeScript)

```ts
import { init, LDContext } from '@launchdarkly/node-server-sdk';
import { initAi, LDAIClient, LDAIConfig } from '@launchdarkly/server-sdk-ai';
```

#### Node.js (server-side) AI SDK (JavaScript)

```js
import { init, LDContext } from '@launchdarkly/node-server-sdk';
import { initAi } from '@launchdarkly/server-sdk-ai';
```

Here's how to import a provider-specific package:

#### OpenAI

```js
import { getAIMetricsFromResponse } from '@launchdarkly/server-sdk-ai-openai';
import { OpenAI } from 'openai';
```

#### LangChain

```js
import {
  convertMessagesToLangChain,
  createLangChainModel,
  getAIMetricsFromResponse,
} from '@launchdarkly/server-sdk-ai-langchain';
import { HumanMessage } from '@langchain/core/messages';
```

#### Vercel AI

```js
import {
  VercelRunnerFactory,
  getAIMetricsFromResponse,
} from '@launchdarkly/server-sdk-ai-vercel';
import { generateText } from 'ai';
```

### Initialize the client

After you install and import the SDK, create a single, shared instance of `LDClient`. When the `LDClient` is initialized, use it to initialize the `LDAIClient`. The `LDAIClient` is how you interact with configs. Specify the SDK key to authorize your application to connect to a particular environment within LaunchDarkly.

#### The Node.js SDKs use an SDK key

Both the Node.js (server-side) AI SDK and the Node.js (server-side) SDK use an SDK key. Keys are specific to each project and environment. They are available on the **SDK keys** page under **Settings**. To learn more about key types, read [Keys](/sdk/concepts/client-side-server-side#keys-and-credentials).

Here's how:

#### Node.js (server-side) AI SDK (TypeScript)

```ts
const ldClient: LDClient = init('YOUR_SDK_KEY');

try {
  await ldClient.waitForInitialization({ timeout: 10 });
  // initialization complete
} catch (error) {
  // timeout or SDK failed to initialize
}

const aiClient: LDAIClient = initAi(ldClient);
```

#### Node.js (server-side) AI SDK (JavaScript)

```js
const ldClient = init('YOUR_SDK_KEY');

try {
  await ldClient.waitForInitialization({ timeout: 10 });
  // initialization complete
} catch (error) {
  // timeout or SDK failed to initialize
}

const aiClient = initAi(ldClient);
```

### Configure the context

Configure the context that will encounter generated AI content in your application. The context attributes determine which variation of the config LaunchDarkly serves to the end user, based on the targeting rules in your config. If you are using template variables in the messages in your config's variations, the context attributes also fill in values for the template variables.

Here's how:

#### Node.js (server-side) AI SDK (TypeScript)

```ts
const context: LDContext = {
  kind: 'user',
  key: 'example-user-key',
  firstName: 'Sandy',
  lastName: 'Smith',
  email: 'sandy@example.com',
  groups: ['Acme', 'Global Health Services'],
};
```

#### Node.js (server-side) AI SDK (JavaScript)

```js
const context = {
  kind: 'user',
  key: 'example-user-key',
  firstName: 'Sandy',
  lastName: 'Smith',
  email: 'sandy@example.com',
  groups: ['Acme', 'Global Health Services'],
};
```

### Customize a config

Customize your config to set values for variables used in messages or instructions based on the context attributes and variables you provide.

The details of customizing a config depend on whether you are using configs in completion mode or agent mode. You set the mode for a particular config when you [create it](/home/agentcontrol/create) in the LaunchDarkly UI.

#### Customize configs in completion mode

In completion mode, each variation in your config includes a single set of roles and messages used to prompt your generative AI model.

In `completion` mode, use `completionConfig()` to customize the config. The `completionConfig()` function takes a config key, a context, a fallback value, and optional variables to use in the customization. It performs the evaluation, then returns the customized messages and model along with a tracker instance for recording metrics. If it cannot perform the evaluation or LaunchDarkly is unreachable, it returns the fallback value. For example, you might use an empty, disabled configuration object as a fallback value, or a fully configured default. Either way, you should make sure to check for this case and handle it appropriately in your application.

Here's how:

#### Customize a config in completion mode (TypeScript)

```ts
const fallbackConfig = { enabled: false };

const aiConfig: LDAIConfig = await aiClient.completionConfig(
  'example-config-key',
  context,
  fallbackConfig,
  { 'exampleCustomVariable': 'exampleCustomValue' },
);
```

#### Customize a config in completion mode (JavaScript)

```js
const fallbackConfig = {
  enabled: false,
};

const aiConfig = await aiClient.completionConfig(
  'example-config-key',
  context,
  fallbackConfig,
  { 'exampleCustomVariable': 'exampleCustomValue' },
);
```

#### Customize configs in agent mode

In agent mode, each variation in your config includes a set of instructions, which enable multi-step workflows.

In `agent` mode, use `agentConfig()` or `agentConfigs()` to customize the config. The `agentConfig()` function customizes a single agent config, while the `agentConfigs()` function customizes an array of agent configurations.

The instructions returned by the SDK come directly from the instructions you define for the config variation in the LaunchDarkly UI. The goal or task shown in the UI is delivered unchanged as the `instructions` field in the SDK.

Customization requires a config key, fallback value, and optional variables for each agent-mode evaluation. Additionally, customization requires a context. Both functions perform the evaluation and then return the customized instructions for each config, along with a tracker instance for recording metrics. If the function cannot perform the evaluation or LaunchDarkly is unreachable, it returns the fallback value.

For example, you might use an empty, disabled configuration object as a fallback value, or a fully configured default. Either way, you should make sure to check for this case and handle it appropriately in your application.

Here's how:

#### Customize a config in agent mode (TypeScript)

```ts
const fallbackConfig = { enabled: false };

const agent: LDAIAgentConfig = await aiClient.agentConfig(
  'example-config-key',
  context,
  fallbackConfig,
  { 'exampleCustomVariable': 'exampleCustomValue' },
);
```

#### Customize a config in agent mode (JavaScript)

```js
const fallbackConfig = {
  enabled: false,
};

const agent = await aiClient.agentConfig(
  'example-config-key',
  context,
  fallbackConfig,
  { 'exampleCustomVariable': 'exampleCustomValue' },
);
```

To learn more, read [Customizing AgentControl configs](/sdk/features/agentcontrol-config#nodejs-server-side-ai).

### Use managed objects

As an alternative to the lower-level flow described in the rest of this guide, the SDK provides higher-level managed objects that combine model invocation, message conversion, and metrics tracking. Use `createModel()`, `createAgent()`, or `createJudge()` on the `LDAIClient` to get a `ManagedModel`, `ManagedAgent`, or `Judge`. This is the recommended pattern for new applications because it handles provider routing and metric extraction automatically.

#### Managed model (TypeScript)

```ts
const fallback: LDAICompletionConfigDefault = { enabled: false };
const model = await aiClient.createModel('example-ai-config-key', context, fallback);

if (model) {
  const result = await model.run('What is the capital of France?');
  console.log(result.content, result.metrics);
}
```

### Create a client or model instance

If you're using a provider-specific package, you can create a client (OpenAI) or a model instance (LangChain and Vercel AI). Here's how:

#### OpenAI

```js
const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});
```

#### LangChain

```js
const llm = await createLangChainModel(aiConfig);
```

#### Vercel AI

```js
const model = await VercelRunnerFactory.createVercelModel(aiConfig);
```

### Combine config messages with user messages

With your model ready, you can now combine the LaunchDarkly-provided messages with user input. If you're using a provider-specific package, you can combine a config message with a user message. Here's how:

#### OpenAI

```js
const configMessages = aiConfig.messages || [];
const userMessage = { role: 'user', content: 'What is the capital of France?' };
const allMessages = [...configMessages, userMessage];
```

#### LangChain

```js
const configMessages = aiConfig.messages || [];
const userMessage = new HumanMessage('What is the capital of France?');
const allMessages = [...convertMessagesToLangChain(configMessages), userMessage];
```

#### Vercel AI

```js
const configMessages = aiConfig.messages || [];
const userMessage = { role: 'user', content: 'What is the capital of France?' };
const allMessages = [...configMessages, userMessage];
```

### Call the provider and record AI metrics

Finally, using a provider-specific package, make a request to your generative AI provider and record metrics from your AI model generation.

Tracking AI metrics does not automatically associate traces with the config.

#### Run model calls inside an active span to associate traces

LaunchDarkly can associate traces with an evaluated config only when the model request runs inside an active OpenTelemetry span. For new application development, we recommend using the LaunchDarkly Observability SDK plugin to create and manage spans.

If the model call does not run inside an active span, LaunchDarkly cannot associate the trace with the config.

To learn more, read [LLM observability](/home/observability/llm-observability) and [Monitor configs](/home/agentcontrol/monitor).

The following example shows how to use the LaunchDarkly Observability SDK plugin to run a model request inside an active span so LaunchDarkly can associate the resulting trace with the evaluated config.

This example assumes you have configured the LaunchDarkly Observability SDK plugin and have access to request headers.

#### Using the LaunchDarkly Observability SDK plugin

```js
const tracker = aiConfig.createTracker();

await LDObserve.runWithHeaders('llm.chat', req.headers, async (span) => {
  return await tracker.trackMetricsOf(
    getAIMetricsFromResponse,
    () => client.chat.completions.create({
      model: aiConfig.model?.name || 'gpt-4',
      messages: aiConfig.messages || [],
    })
  );
});
```

After you ensure your model request runs inside an active span, you can call your provider and record AI metrics as shown in the examples below.

#### OpenAI

```js
const tracker = aiConfig.createTracker();

const response = await tracker.trackMetricsOf(
  getAIMetricsFromResponse,
  () => client.chat.completions.create({
    model: aiConfig.model?.name || 'gpt-4',
    messages: aiConfig.messages || [],
    temperature: (aiConfig.model?.parameters?.temperature as number) ?? 0.5,
  })
);

console.log('AI Response:', response.choices[0].message.content);

```

#### LangChain

```js
const tracker = aiConfig.createTracker();

const response = await tracker.trackMetricsOf(
  getAIMetricsFromResponse,
  () => llm.invoke(allMessages)
);

console.log('AI Response:', response.content);
```

#### Vercel AI

```js
const tracker = aiConfig.createTracker();

const response = await tracker.trackMetricsOf(
  getAIMetricsFromResponse,
  () => generateText({ model, messages: allMessages })
);

console.log('AI Response:', response.text);
```

#### Amazon Bedrock

```js
import { ConverseCommand } from '@aws-sdk/client-bedrock-runtime';

// Use the LaunchDarkly Node.js AI SDK to call an Amazon Bedrock model
// and automatically record metrics such as token usage and latency.

const tracker = aiConfig.createTracker();

const response = tracker.trackBedrockConverseMetrics(
  await awsClient.send(
    new ConverseCommand({
      modelId: aiConfig.model?.name ?? 'anthropic.claude-3',
      messages: mapPromptToConversation(aiConfig.messages ?? []),
      inferenceConfig: {
        temperature: (aiConfig.model?.parameters?.temperature as number) ?? 0.5,
        maxTokens: (aiConfig.model?.parameters?.maxTokens as number) ?? 4096,
      },
    })
  )
);

console.log('AI Response:', response.output?.message?.content);
```

To learn more, read [Tracking AI metrics](/sdk/features/ai-metrics#nodejs-server-side-ai).

## Supported features

This SDK supports the following features:

* [Anonymous contexts](/sdk/features/anonymous#nodejs-server-side-ai)
* [Context configuration](/sdk/features/context-config#nodejs-server-side-ai)
* [Customizing AgentControl configs](/sdk/features/agentcontrol-config#nodejs-server-side-ai)
* [Private attributes](/sdk/features/private-attributes#nodejs-server-side-ai)
* [Tracking AI metrics](/sdk/features/ai-metrics#nodejs-server-side-ai)