UNPKG

@dooor-ai/toolkit

Version:

Guards, Evals & Observability for AI applications - works seamlessly with LangChain/LangGraph

233 lines (190 loc) 6.17 kB
# RAG (Retrieval-Augmented Generation) - Usage Examples ## Basic Usage ```typescript import { dooorChatGuard, RAGContext, RAGStrategy, buildRAGPrompt, PromptInjectionGuard, ToxicityGuard, LatencyEval, } from "@dooor-ai/toolkit"; import { ChatGoogleGenerativeAI } from "@langchain/google-genai"; import fs from "fs/promises"; // Setup LLM with guards and evals const baseProvider = new ChatGoogleGenerativeAI({ model: "gemini-2.0-flash-exp", apiKey: process.env.GEMINI_API_KEY, temperature: 0, }); const llm = dooorChatGuard(baseProvider, { apiKey: "cortexdb://cortexdb_admin_...@35.223.201.25:8000/ai", providerName: "gemini", project: "my-project", guards: [ new PromptInjectionGuard({ threshold: 0.8 }), new ToxicityGuard({ threshold: 0.7 }), ], evals: [new LatencyEval({ threshold: 3000 })], observability: true, }); // Create RAG context with PDF files const manualPdf = await fs.readFile("./docs/manual.pdf"); const apiDocsPdf = await fs.readFile("./docs/api-reference.pdf"); const ragContext = new RAGContext({ files: [ { name: "manual.pdf", data: manualPdf, type: "application/pdf" }, { name: "api-reference.pdf", data: apiDocsPdf, type: "application/pdf" }, ], embeddingProvider: "prod-gemini", // Internal name configured in /settings/embeddings strategy: RAGStrategy.HYDE, topK: 5, chunkSize: 1000, chunkOverlap: 200, }); // Use buildRAGPrompt to automatically inject context const userQuery = "How do I authenticate users in the system?"; const promptWithContext = await buildRAGPrompt(userQuery, ragContext); const result = await llm.invoke([ { role: "user", content: promptWithContext } ]); console.log("Answer:", result.content); ``` ## Mixing Different Sources ```typescript const ragContext = new RAGContext({ // PDF files files: [ { name: "manual.pdf", data: pdfBuffer, type: "application/pdf" }, { name: "api-docs.md", data: mdBuffer, type: "text/markdown" }, ], // Plain text documents documents: [ { content: "Authentication uses JWT tokens. Tokens expire after 24h.", metadata: { source: "internal-notes" } }, { content: "Users can reset passwords via /auth/reset endpoint.", metadata: { source: "support-docs" } }, ], // Pre-computed embeddings (if you already have them) embeddings: [ { text: "OAuth 2.0 is supported for third-party integrations.", vector: [0.1, 0.2, 0.3, ...], // Your pre-computed embedding metadata: { source: "oauth-spec" } }, ], embeddingProvider: "prod-gemini", strategy: RAGStrategy.RERANK, topK: 10, }); ``` ## Different RAG Strategies ```typescript // 1. SIMPLE - Basic semantic search const simpleRAG = new RAGContext({ files: [pdfFile], embeddingProvider: "prod-gemini", strategy: RAGStrategy.SIMPLE, topK: 5, }); // 2. HYDE - Hypothetical Document Embeddings (best for complex queries) const hydeRAG = new RAGContext({ files: [pdfFile], embeddingProvider: "prod-gemini", strategy: RAGStrategy.HYDE, topK: 5, }); // 3. RERANK - Retrieve more candidates, rerank with LLM const rerankRAG = new RAGContext({ files: [pdfFile], embeddingProvider: "prod-gemini", strategy: RAGStrategy.RERANK, topK: 10, }); // 4. FUSION - Combine multiple retrieval methods const fusionRAG = new RAGContext({ files: [pdfFile], embeddingProvider: "prod-gemini", strategy: RAGStrategy.FUSION, topK: 5, }); // 5. MULTI_QUERY - Generate multiple queries for better coverage const multiQueryRAG = new RAGContext({ files: [pdfFile], embeddingProvider: "prod-gemini", strategy: RAGStrategy.MULTI_QUERY, topK: 5, }); ``` ## Manual Context Retrieval ```typescript import { retrieveContext } from "@dooor-ai/toolkit"; // Get context without building prompt const { context, results, metadata } = await retrieveContext( "How to authenticate?", ragContext ); console.log("Retrieved context:", context); console.log("Chunks used:", metadata.chunks_retrieved); console.log("Latency:", metadata.took_ms, "ms"); console.log("Strategy:", metadata.strategy_used); console.log("Similarity scores:", metadata.similarity_scores); // Build custom prompt const customPrompt = ` Here is relevant documentation: ${context} Based ONLY on the documentation above, answer this question: ${userQuery} If the documentation doesn't contain the answer, say "I don't know based on the provided documentation." `; const result = await llm.invoke([{ role: "user", content: customPrompt }]); ``` ## With LangGraph Agents ```typescript import { createReactAgent } from "@langchain/langgraph/prebuilt"; const agent = createReactAgent({ llm: llm, tools: [], prompt: `You are a helpful assistant. Use the provided context to answer questions.`, }); // Build RAG prompt before calling agent const promptWithContext = await buildRAGPrompt(userQuery, ragContext); const result = await agent.invoke({ messages: [{ role: "user", content: promptWithContext }] }); console.log(result); ``` ## Error Handling ```typescript try { const ragContext = new RAGContext({ files: [pdfFile], embeddingProvider: "my-embedding-provider", strategy: RAGStrategy.HYDE, }); const prompt = await buildRAGPrompt(userQuery, ragContext); const result = await llm.invoke([{ role: "user", content: prompt }]); console.log(result.content); } catch (error) { if (error.message.includes("Embedding provider")) { console.error("Configure embedding provider at /settings/embeddings"); } else if (error.message.includes("not found")) { console.error("Embedding provider 'my-embedding-provider' not found"); } else { console.error("RAG failed:", error.message); } } ``` ## Observability RAG metrics are automatically tracked in observability: - **Retrieval latency** - Time to retrieve and process documents - **Chunks retrieved** - Number of document chunks used - **Similarity scores** - Relevance scores for retrieved chunks - **Strategy used** - Which RAG strategy was applied - **Embedding provider** - Which provider generated embeddings All metrics are visible in the CortexDB Studio observability dashboard.