Skip to content

Commit 66bfa3f

Browse files
authored
chore: Add example for judge usage (#979)
1 parent 0427908 commit 66bfa3f

File tree

12 files changed

+268
-11
lines changed

12 files changed

+268
-11
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,8 @@ yarn-error.log
2222
dump.rdb
2323
.wrangler
2424
stats.html
25+
26+
# Environment files
27+
.env
28+
.env.local
29+
.env.*.local

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"packages/sdk/browser/contract-tests/adapter",
3636
"packages/sdk/server-ai",
3737
"packages/sdk/server-ai/examples/bedrock",
38+
"packages/sdk/server-ai/examples/judge-evaluation",
3839
"packages/sdk/server-ai/examples/openai",
3940
"packages/sdk/server-ai/examples/tracked-chat",
4041
"packages/sdk/server-ai/examples/vercel-ai",
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# LaunchDarkly SDK Key (required)
2+
# Get this from your LaunchDarkly account settings
3+
LAUNCHDARKLY_SDK_KEY=your-launchdarkly-sdk-key-here
4+
5+
# AI Config Key for the main chat configuration (optional)
6+
# This is the key of your AI Config in LaunchDarkly
7+
LAUNCHDARKLY_AI_CONFIG_KEY=sample-ai-config
8+
9+
# Judge Config Key for evaluation (optional)
10+
# This is the key of your Judge AI Config in LaunchDarkly
11+
LAUNCHDARKLY_JUDGE_KEY=ld-ai-judge-accuracy
12+
13+
# OpenAI API Key (required if using OpenAI provider)
14+
# Get this from https://platform.openai.com/api-keys
15+
OPENAI_API_KEY=your-openai-api-key-here
16+
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# LaunchDarkly AI SDK Judge Evaluation Example
2+
3+
This package demonstrates the integration of LaunchDarkly's AI SDK Judge functionality for evaluating AI responses using AI Configs with `mode: "judge"`.
4+
5+
## Installation and Build
6+
7+
When running as part of the js-core mono-repo the project will use local dependencies.
8+
As such those dependencies need built.
9+
10+
In the root of the repository run:
11+
12+
```bash
13+
yarn
14+
```
15+
16+
And then
17+
18+
```bash
19+
yarn build
20+
```
21+
22+
## AI Config Setup
23+
24+
Make sure you have an AI Config configured in LaunchDarkly with `mode: "judge"`:
25+
26+
1. Install Judges in your AI Configs
27+
1. Create an AI Config in LaunchDarkly:
28+
- Navigate to the AI Configs section in your LaunchDarkly dashboard
29+
- Create a new AI Config with the key `sample-ai-config`
30+
- Add a variation with the following settings:
31+
- **Model Selection**: Select "OpenAI" as the provider and "gpt-3.5-turbo" as the model
32+
- **Messages**: Add a system message with the content: "You are a helpful assistant for {{companyName}}. You should be friendly and informative."
33+
- Save the variation
34+
- Update the default target rule to use the newly created variation
35+
- Attach one or more judges to your config
36+
37+
## Configuration
38+
39+
Before running the example, make sure to set the following environment variables:
40+
41+
1. Copy the example environment file:
42+
```bash
43+
cp .env.example .env
44+
```
45+
46+
2. Edit `.env` and set the following environment variables:
47+
- `LAUNCHDARKLY_SDK_KEY`: Your LaunchDarkly SDK key (required)
48+
- `LAUNCHDARKLY_AI_CONFIG_KEY`: Your AI Config key (defaults to 'sample-ai-config')
49+
- `LAUNCHDARKLY_JUDGE_KEY`: Your judge AI Config key (defaults to 'ld-ai-judge-accuracy')
50+
- `OPENAI_API_KEY`: Your OpenAI API key (required if using OpenAI provider)
51+
52+
## Usage
53+
54+
The main script (`index.js`) demonstrates how to:
55+
56+
1. Initialize the LaunchDarkly SDK
57+
1. Set up a user context
58+
1. Initialize the LaunchDarkly AI client
59+
1. Create a chat for an AI Config with attached judges
60+
1. Create a judge for direct evaluation
61+
1. Evaluate AI text using the `evaluate()` method
62+
1. Handle evaluation results and errors
63+
64+
To run the example (in the judge-evaluation directory):
65+
66+
```bash
67+
yarn start
68+
```
69+
70+
## Note
71+
72+
This example uses the Judge functionality to evaluate AI responses. Make sure your LaunchDarkly AI Configs are set up correctly with `mode: "judge"` and include the necessary evaluation prompts and metrics.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "@launchdarkly/server-sdk-ai-judge",
3+
"version": "1.0.0",
4+
"description": "Example demonstrating LaunchDarkly AI SDK judge functionality for evaluating AI responses",
5+
"type": "module",
6+
"scripts": {
7+
"build": "tsc",
8+
"lint": "npx eslint . --ext .ts",
9+
"start": "yarn build && node ./dist/index.js"
10+
},
11+
"dependencies": {
12+
"@launchdarkly/node-server-sdk": "^9.0.0",
13+
"@launchdarkly/server-sdk-ai": "^0.12.3",
14+
"@launchdarkly/server-sdk-ai-langchain": "^0.1.0",
15+
"@launchdarkly/server-sdk-ai-openai": "^0.1.0",
16+
"@launchdarkly/server-sdk-ai-vercel": "^0.1.0",
17+
"dotenv": "^16.0.0"
18+
},
19+
"devDependencies": {
20+
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
21+
"@tsconfig/node20": "20.1.4",
22+
"@typescript-eslint/eslint-plugin": "^6.20.0",
23+
"@typescript-eslint/parser": "^6.20.0",
24+
"eslint": "^8.45.0",
25+
"eslint-config-airbnb-base": "^15.0.0",
26+
"eslint-config-airbnb-typescript": "^17.1.0",
27+
"eslint-config-prettier": "^8.8.0",
28+
"eslint-plugin-import": "^2.27.5",
29+
"eslint-plugin-jest": "^27.6.3",
30+
"eslint-plugin-prettier": "^5.0.0",
31+
"jest": "^29.7.0",
32+
"prettier": "^3.0.0",
33+
"rimraf": "^5.0.5",
34+
"typedoc": "0.25.0",
35+
"typescript": "^5.5.3"
36+
}
37+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/* eslint-disable no-console */
2+
import dotenv from 'dotenv';
3+
4+
import { init, type LDContext } from '@launchdarkly/node-server-sdk';
5+
import { initAi } from '@launchdarkly/server-sdk-ai';
6+
7+
dotenv.config({ override: true });
8+
9+
// Environment variables
10+
const sdkKey = process.env.LAUNCHDARKLY_SDK_KEY;
11+
const aiConfigKey = process.env.LAUNCHDARKLY_AI_CONFIG_KEY || 'sample-ai-config';
12+
const judgeKey = process.env.LAUNCHDARKLY_JUDGE_KEY || 'ld-ai-judge-accuracy';
13+
14+
// Validate required environment variables
15+
if (!sdkKey) {
16+
console.error('*** Please set the LAUNCHDARKLY_SDK_KEY env first');
17+
process.exit(1);
18+
}
19+
20+
// Initialize LaunchDarkly client
21+
const ldClient = init(sdkKey);
22+
23+
// Set up the context properties. This context should appear on your LaunchDarkly contexts dashboard
24+
// soon after you run the demo.
25+
const context: LDContext = {
26+
kind: 'user',
27+
key: 'example-user-key',
28+
name: 'Sandy',
29+
};
30+
31+
async function main(): Promise<void> {
32+
try {
33+
await ldClient.waitForInitialization({ timeout: 10 });
34+
console.log('*** SDK successfully initialized');
35+
} catch (error) {
36+
console.log(`*** SDK failed to initialize: ${error}`);
37+
process.exit(1);
38+
}
39+
40+
const aiClient = initAi(ldClient);
41+
42+
try {
43+
// Example using the chat functionality which automates the judge evaluation
44+
const defaultValue = {
45+
enabled: false,
46+
};
47+
48+
const chat = await aiClient.createChat(aiConfigKey, context, defaultValue, {
49+
companyName: 'LaunchDarkly',
50+
});
51+
52+
if (!chat) {
53+
console.log('*** AI chat configuration is not enabled');
54+
process.exit(0);
55+
}
56+
57+
console.log('\n*** Starting chat:');
58+
const userInput = 'How can LaunchDarkly help me?';
59+
console.log('User Input:', userInput);
60+
61+
// The invoke method will automatically evaluate the chat response with any judges defined in the AI config
62+
const chatResponse = await chat.invoke(userInput);
63+
console.log('Chat Response:', chatResponse.message.content);
64+
65+
// Log judge evaluation results with full detail
66+
const evalResults = await chatResponse.evaluations;
67+
console.log('Judge results:', JSON.stringify(evalResults, null, 2));
68+
69+
// Example of using the judge functionality with direct input and output
70+
// Get AI judge configuration from LaunchDarkly
71+
const judge = await aiClient.createJudge(judgeKey, context, { enabled: false });
72+
73+
if (!judge) {
74+
console.log('*** AI judge configuration is not enabled');
75+
process.exit(0);
76+
}
77+
78+
console.log('\n*** Starting judge evaluation of direct input and output:');
79+
const input = 'You are a helpful assistant for the company LaunchDarkly. How can you help me?';
80+
const output =
81+
'I can answer any question you have except for questions about the company LaunchDarkly.';
82+
83+
console.log('Input:', input);
84+
console.log('Output:', output);
85+
86+
const judgeResponse = await judge.evaluate(input, output);
87+
88+
// Track the judge evaluation scores on the tracker for the aiConfig you are evaluating
89+
// Example:
90+
// aiConfig.tracker.trackEvalScores(judgeResponse?.evals);
91+
92+
console.log('Judge Response:', judgeResponse);
93+
94+
console.log('Success.');
95+
} catch (err) {
96+
console.error('Error:', err);
97+
}
98+
}
99+
100+
main();
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2022",
4+
"module": "ESNext",
5+
"moduleResolution": "node",
6+
"esModuleInterop": true,
7+
"allowSyntheticDefaultImports": true,
8+
"strict": true,
9+
"skipLibCheck": true,
10+
"forceConsistentCasingInFileNames": true,
11+
"outDir": "./dist",
12+
"rootDir": "./src",
13+
"declaration": true,
14+
"sourceMap": true
15+
},
16+
"include": ["src/**/*"],
17+
"exclude": ["node_modules", "dist"]
18+
}

packages/sdk/server-ai/examples/openai/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"dependencies": {
2424
"@launchdarkly/node-server-sdk": "^9.7.1",
2525
"@launchdarkly/server-sdk-ai": "0.13.0",
26+
"@launchdarkly/server-sdk-ai-openai": "^0.1.0",
2627
"openai": "^4.58.1"
2728
},
2829
"devDependencies": {

packages/sdk/server-ai/examples/openai/src/index.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { OpenAI } from 'openai';
33

44
import { init, LDContext } from '@launchdarkly/node-server-sdk';
55
import { initAi } from '@launchdarkly/server-sdk-ai';
6+
import { OpenAIProvider } from '@launchdarkly/server-sdk-ai-openai';
67

78
// Environment variables
89
const sdkKey = process.env.LAUNCHDARKLY_SDK_KEY;
@@ -46,7 +47,7 @@ async function main(): Promise<void> {
4647

4748
const aiClient = initAi(ldClient);
4849

49-
const aiConfig = await aiClient.config(
50+
const aiConfig = await aiClient.completionConfig(
5051
aiConfigKey,
5152
context,
5253
{
@@ -63,13 +64,15 @@ async function main(): Promise<void> {
6364
process.exit(0);
6465
}
6566

66-
const completion = await aiConfig.tracker.trackOpenAIMetrics(async () =>
67-
client.chat.completions.create({
68-
messages: aiConfig.messages || [],
69-
model: aiConfig.model?.name || 'gpt-4',
70-
temperature: (aiConfig.model?.parameters?.temperature as number) ?? 0.5,
71-
max_tokens: (aiConfig.model?.parameters?.maxTokens as number) ?? 4096,
72-
}),
67+
const completion = await aiConfig.tracker.trackMetricsOf(
68+
OpenAIProvider.createAIMetrics,
69+
async () =>
70+
client.chat.completions.create({
71+
messages: aiConfig.messages || [],
72+
model: aiConfig.model?.name || 'gpt-4',
73+
temperature: (aiConfig.model?.parameters?.temperature as number) ?? 0.5,
74+
max_tokens: (aiConfig.model?.parameters?.maxTokens as number) ?? 4096,
75+
}),
7376
);
7477

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

packages/sdk/server-ai/examples/tracked-chat/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ async function main(): Promise<void> {
4646
// };
4747

4848
// Get AI chat configuration from LaunchDarkly
49-
const chat = await aiClient.initChat(aiConfigKey, context, defaultValue, {
49+
const chat = await aiClient.createChat(aiConfigKey, context, defaultValue, {
5050
companyName: 'LaunchDarkly',
5151
});
5252

0 commit comments

Comments
 (0)