Skip to content

Commit

Permalink
docs: ab test cookbook
Browse files Browse the repository at this point in the history
  • Loading branch information
joschkabraun committed Jul 31, 2024
1 parent b2f543e commit 9022d0d
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
77 changes: 77 additions & 0 deletions cookbook/ab_testing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// checkout the associated tutorial at https://docs.parea.ai//tutorials/running-ab-tests/llm-generated-emails

import * as dotenv from 'dotenv';
import { OpenAI } from 'openai';
import { Parea, patchOpenAI, trace, getCurrentTraceId, traceInsert, pareaLogger } from '../src';

dotenv.config();
new Parea(process.env.PAREA_API_KEY);
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
// wrap OpenAI client to trace LLM calls
patchOpenAI(openai);

const abTestName = 'long-vs-short-emails';

// use trace to capture inputs, outputs of your function
const generateEmail = trace(
'generate_email',
async (user: string): Promise<[string | null, string | undefined, string]> => {
// randomly choose to generate a long or short email
const variant = Math.random() < 0.5 ? 'variant_0' : 'variant_1';
let prompt;
if (variant === 'variant_0') {
prompt = `Generate a long email for ${user}`;
} else {
prompt = `Generate a short email for ${user}`;
}
// tag the requests with the A/B test name & chosen variant
traceInsert({
metadata: {
ab_test_name: abTestName,
[`ab_test_${abTestName}`]: variant,
},
});

const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{
role: 'user',
content: prompt,
},
],
});
return [response.choices[0].message.content, getCurrentTraceId(), variant];
},
);

const captureFeedback = async (
feedback: number,
traceId: string,
abTestVariant: string,
userCorrectEmail: string = '',
): Promise<void> => {
await pareaLogger.updateLog({
trace_id: traceId,
field_name_to_value_map: {
scores: [
{
name: `ab_test_${abTestVariant}`,
score: feedback,
reason: "any additional user feedback on why it's good/bad",
},
],
target: userCorrectEmail,
},
});
};

const main = async () => {
const [email, traceId, abTestVariant] = await generateEmail('Max Mustermann');
console.log('email:', email);
const userFeedback =
abTestVariant === 'variant_1' ? (Math.random() < 0.7 ? 0.0 : 1.0) : Math.random() < 0.3 ? 0.0 : 1.0;
await captureFeedback(userFeedback, traceId || '', abTestVariant, 'Hi Max');
};

main().then(() => console.log('Done!'));
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { Parea } from './client';
export { pareaLogger } from './parea_logger';

export { trace, getCurrentTraceId, traceInsert } from './utils/trace';
export { patchOpenAI } from './utils/wrappers/OpenAIWrapper';
Expand Down

0 comments on commit 9022d0d

Please sign in to comment.