import { setupObservability } from "langwatch/observability/node";
import { getLangWatchTracer } from "langwatch";
import type { LangWatchSpanRAGContext } from "langwatch/observability";
// Setup observability
setupObservability();
const tracer = getLangWatchTracer("rag-example");
async function generateAnswerFromContext(contexts: string[], userQuery: string): Promise<string> {
return await tracer.withActiveSpan("GenerateAnswerFromContext", async (span) => {
span.setType("llm");
span.setRequestModel("gpt-5-mini");
// Simulate LLM call using the contexts
await new Promise(resolve => setTimeout(resolve, 500));
const response = `Based on the context, the answer to '${userQuery}' is...`;
// You can update the LLM span with model details, token counts, etc.
span.setInput("text", `Contexts: ${contexts.join(", ")}\nQuery: ${userQuery}`);
span.setOutput("text", response);
return response;
});
}
async function performRAG(userQuery: string): Promise<string> {
return await tracer.withActiveSpan("My Custom RAG Process", async (span) => {
span.setType("rag");
// 1. Retrieve contexts
// Simulate retrieval from a vector store or other source
await new Promise(resolve => setTimeout(resolve, 300));
const retrievedDocs = [
"LangWatch helps monitor LLM applications.",
"RAG combines retrieval with generation for better answers.",
"TypeScript is a popular language for AI development."
];
// Update the current RAG span with the retrieved contexts
// You can pass a list of strings directly
const ragContexts: LangWatchSpanRAGContext[] = retrievedDocs.map((content, index) => ({
document_id: `doc${index + 1}`,
chunk_id: `chunk${index + 1}`,
content
}));
span.setRAGContexts(ragContexts);
// Alternatively, for simpler context information:
// span.setRAGContexts(retrievedDocs.map(content => ({
// document_id: "unknown",
// chunk_id: "unknown",
// content
// })));
// 2. Generate answer using the contexts
const finalAnswer = await generateAnswerFromContext(contexts: retrievedDocs, userQuery: userQuery);
// The RAG span automatically captures its input (userQuery) and output (finalAnswer)
// if dataCapture is not set to "none".
return finalAnswer;
});
}
async function handleUserQuestion(question: string): Promise<string> {
return await tracer.withActiveSpan("User Question Handler", async (span) => {
span.setInput("text", question);
span.setAttributes({ "user_id": "example_user_123" });
const answer = await performRAG(userQuery: question);
span.setOutput("text", answer);
return answer;
});
}
// Example usage
async function main() {
const userQuestion = "What is LangWatch used for?";
const response = await handleUserQuestion(userQuestion);
console.log(`Question: ${userQuestion}`);
console.log(`Answer: ${response}`);
}
main().catch(console.error);