Getting Started
Guides
- Prompts
- Monitoring
- Experiments
- Datasets
Learn more
Examples
Practical examples of monitoring AI interactions with Basalt.
This page provides practical examples of how to use Basalt’s monitoring capabilities in common scenarios. These examples demonstrate different approaches to monitoring based on your specific use case.
Basic Prompt Monitoring
The simplest way to monitor AI interactions is with the basic monitoring approach when using Basalt-managed prompts:
// Get a prompt from Basalt (already includes monitoring)
const { value, generation } = await basalt.prompt.get('customer-reply', {
variables: {
customerName: 'John Smith',
inquiry: 'When will my order arrive?'
}
})
// Generate content with your LLM provider
const response = await generateWithLLM(value.text)
// Record the completion
generation.end(response)
Customer Support Workflow
This example monitors a customer support interaction with user identification:
async function handleCustomerQuery(user, query) {
// Create a trace for the entire interaction
const trace = basalt.monitor.createTrace('customer-support', {
name: 'Customer Support Interaction',
input: query,
user: {
id: user.id,
name: user.name
},
organization: {
id: user.companyId,
name: user.companyName
}
})
try {
// Get the query classification prompt
const { value: classifierPrompt, generation: classifyGeneration } =
await basalt.prompt.get('query-classifier')
// Append the generation to our trace
trace.append(classifyGeneration)
// Classify the query
const category = await classifyQuery(query, classifierPrompt.text)
// Record the classification result
classifyGeneration.end(category)
// Create a response generation
const responseLog = trace.createGeneration({
name: 'generate-response',
prompt: {
slug: 'support-response',
tag: category
},
input: query,
variables: {
query: query,
category: category,
userName: user.name
}
})
// Generate the response
const responseText = await generateResponse(query, category, user.name)
// Record the response generation
responseLog.end(responseText)
// End the trace
trace.end(responseText)
return {
category: category,
response: responseText
}
} catch (error) {
trace.update({
metadata: {
error: error.message
}
})
trace.end(`Error: ${error.message}`)
throw error
}
}
Content Moderation
This example monitors content moderation with evaluation:
async function moderateUserContent(content) {
// Create a trace for content moderation
const trace = basalt.monitor.createTrace('content-moderation', {
name: 'Content Moderation',
input: content,
evaluators: [
{ slug: 'content-policy' }
]
})
// Create a generation for moderation check
const generation = trace.createGeneration({
name: 'moderation-check',
prompt: {
slug: 'content-moderator'
},
input: content
})
try {
// Check content with your moderation system
const result = await checkContentModeration(content)
const isSafe = result.includes('safe')
// Record the moderation result with metadata
generation.end({
output: result,
metadata: {
isSafe: isSafe,
contentType: 'text'
}
})
// End the trace
trace.end(result)
return {
isSafe: isSafe,
result: result
}
} catch (error) {
generation.end({
output: `Error: ${error.message}`,
metadata: {
error: error.message
}
})
trace.end(`Error: ${error.message}`)
throw error
}
}
Document Processing
This example tracks a simple document processing workflow:
async function processDocument(document) {
// Create a trace for document processing
const trace = basalt.monitor.createTrace('document-processing', {
name: 'Document Processing',
input: document.title,
metadata: {
documentId: document.id,
documentType: document.type
}
})
try {
// Create a log for text extraction
const extractionLog = trace.createLog({
name: 'text-extraction',
type: 'function',
input: `Document: ${document.title}`
})
// Extract key information
const extractedInfo = await extractDocumentInfo(document)
// Record extraction
extractionLog.end(extractedInfo)
// Create a generation for summary
const summaryGeneration = trace.createGeneration({
name: 'document-summary',
prompt: {
slug: 'document-summarizer'
},
input: extractedInfo,
variables: {
documentType: document.type,
maxLength: '250 words'
}
})
// Generate summary
const summaryText = await generateSummary(extractedInfo)
// Record summary generation
summaryGeneration.end(summaryText)
// End trace
trace.end(summaryText)
return {
extractedInfo: extractedInfo,
summary: summaryText
}
} catch (error) {
trace.update({
metadata: {
error: error.message,
status: 'failed'
}
})
trace.end(`Error: ${error.message}`)
throw error
}
}
RAG Application
This example tracks a simple Retrieval-Augmented Generation (RAG) application:
async function answerWithRAG(question) {
// Create a trace for the RAG workflow
const trace = basalt.monitor.createTrace('rag-query', {
name: 'RAG Query Processing',
input: question
})
try {
// Create a log for retrieval
const retrievalLog = trace.createLog({
name: 'document-retrieval',
type: 'retrieval',
input: question
})
// Retrieve relevant documents
const relevantDocs = await retrieveDocuments(question)
// Record retrieval metrics
retrievalLog.update({
metadata: {
documentCount: relevantDocs.length
}
})
// Compile context from retrieved documents
const context = combineDocuments(relevantDocs)
retrievalLog.end(context)
// Create a generation for answer
const answerGeneration = trace.createGeneration({
name: 'answer-generation',
prompt: {
slug: 'rag-answer-generator'
},
input: question,
variables: {
question: question,
context: context
}
})
// Generate answer using retrieved context
const answerText = await generateAnswer(question, context)
// Record answer generation
answerGeneration.end(answerText)
// End trace
trace.end(answerText)
return {
answer: answerText,
sources: relevantDocs.map(doc => doc.title)
}
} catch (error) {
trace.update({
metadata: {
error: error.message
}
})
trace.end(`Error: ${error.message}`)
throw error
}
}
Chat Interface
This example tracks a simple chat conversation:
async function processChatMessage(userId, sessionId, message, history) {
// Create or get trace for this chat session
let trace = sessionTraces[sessionId] || basalt.monitor.createTrace('chat-session', {
name: 'Chat Conversation',
input: message,
user: { id: userId }
})
if (!sessionTraces[sessionId]) {
sessionTraces[sessionId] = trace
}
// Create a log for this message exchange
const turnLog = trace.createLog({
name: `message-exchange`,
type: 'span',
input: message
})
try {
// Create a generation for the assistant's response
const responseGeneration = turnLog.createGeneration({
name: 'assistant-response',
prompt: { slug: 'chat-response' },
variables: {
userMessage: message,
chatHistory: formatHistory(history)
}
})
// Generate the response
const responseText = await generateChatResponse(message, history)
// Record the response
responseGeneration.end(responseText)
turnLog.end(responseText)
// Add to history
history.push({
user: message,
assistant: responseText
})
return responseText
} catch (error) {
turnLog.end(`Error: ${error.message}`)
throw error
}
}
// Storage for session traces
const sessionTraces = {}
These examples demonstrate different ways to use Basalt’s monitoring capabilities across various common use cases. You can adapt these patterns to your specific needs, combining approaches as needed.
For more complex scenarios, refer to the Tracing and Evaluations documentation.