AI Augmentation with Lucene
AI Augmentation with Lucene
Lucee's AI capabilities can be enhanced with Retrieval-Augmented Generation (RAG) using the Lucene extension. This powerful combination allows AI models to reference your indexed content when responding to queries, creating more accurate and contextually relevant answers.
Overview
The Lucene extension enables you to create searchable collections of content that can be used to augment AI queries with relevant context. This approach improves AI responses by providing domain-specific information from your data sources, whether they're local documentation, databases, external APIs, or other resources.
Requirements
- Lucee 7.0 or higher
- Lucene Extension version 3.0 or higher (Maven-based version)
- Configured AI endpoint (see AI Documentation)
How It Works
- A collection is created to store searchable content
- Content is indexed from various sources (databases, files, web content, APIs, etc.)
- When a query is sent to an AI, it's first used to search the collection for relevant information
- The search results, including content chunks from matches, are added as context to the original query
- The augmented query is sent to the AI endpoint, enabling more informed responses
Implementation
Here's how to implement AI augmentation with Lucene in your Lucee application:
Step 1: Create a Collection
Create a searchable collection to store your indexed content:
// Define collection name
collectionName = "my_knowledge_base";
// Create if needed
collection action="list" name="local.collections";
var hasColl=false;
loop query=collections {
if(collections.name==collectionName) {
hasColl=true;
break;
}
}
if(!hasColl) {
// Define collection directory
var collDirectory=expandPath("{lucee-config-dir}/collections/knowledge");
if(!directoryExists(collDirectory)) {
directoryCreate(collDirectory,true);
}
// Create collection with vector capabilities
collection action="Create"
collection=collectionName
path=collDirectory
mode="hybrid"
embedding="TF-IDF"
ratio="0.5";
}
Step 2: Index Your Content
You can index content from virtually any source you can access in CFML:
// Example 1: Index content from a database
function indexDatabaseContent() {
// Query your data source
var qryContent = queryExecute("
SELECT
id AS url,
title,
description AS summary,
content,
categories AS keywords
FROM knowledge_articles
WHERE is_active = 1
");
// Index the content
index action="update"
type="custom"
collection=collectionName
key="url"
title="title"
body="content,summary"
custom1="keywords"
query="qryContent";
}
// Example 2: Index content from files
function indexFileContent() {
// Get list of files
var files = directoryList(expandPath("./resources/docs"), true, "path", "*.md");
// Create query object to hold file contents
var qryFiles = queryNew("url,title,body,keywords");
// Process each file
for(var filePath in files) {
var content = fileRead(filePath);
var title = listLast(filePath, "/\");
// Extract metadata from file content if applicable
// This is just an example - adapt to your file format
var keywords = "";
if(content contains "Keywords:") {
keywords = reMatch("Keywords:(.+?)[\r\n]", content);
if(arrayLen(keywords)) {
keywords = trim(replace(keywords[1], "Keywords:", ""));
}
}
// Add to query
queryAddRow(qryFiles);
querySetCell(qryFiles, "url", filePath);
querySetCell(qryFiles, "title", title);
querySetCell(qryFiles, "body", content);
querySetCell(qryFiles, "keywords", keywords);
}
// Index the files
index action="update"
type="custom"
collection=collectionName
key="url"
title="title"
body="body"
custom1="keywords"
query="qryFiles";
}
// Example 3: Index web content
function indexWebContent() {
// Define URLs to index
var urls = [
"https://example.com/api/docs",
"https://example.com/api/reference",
"https://example.com/api/tutorials"
];
// Create query object
var qryWeb = queryNew("url,title,body,keywords");
// Process each URL
for(var url in urls) {
var httpService = new http();
httpService.setURL(url);
var result = httpService.send().getPrefix();
if(result.status_code == 200) {
// Extract title and content (simplified example)
var title = reMatchNoCase("<title>(.+?)</title>", result.fileContent);
title = arrayLen(title) ? replaceNoCase(title[1], "<title>", "") : url;
title = replaceNoCase(title, "</title>", "");
// Strip HTML for indexing body
var body = reReplaceNoCase(result.fileContent, "<[^>]*>", " ", "ALL");
// Add to query
queryAddRow(qryWeb);
querySetCell(qryWeb, "url", url);
querySetCell(qryWeb, "title", title);
querySetCell(qryWeb, "body", body);
querySetCell(qryWeb, "keywords", "api,documentation,web");
}
}
// Index the web content
if(qryWeb.recordCount) {
index action="update"
type="custom"
collection=collectionName
key="url"
title="title"
body="body"
custom1="keywords"
query="qryWeb";
}
}
Step 3: Augment AI Queries
Use the indexed content to augment AI queries with the enhanced content chunks feature in Lucene Extension 3.0:
function augmentQuery(userQuery) {
// Escape special characters to ensure proper search
var criteria = rereplace(userQuery, "([+\-&|!(){}\[\]\^""~*?:\\\/])", "\\1", "ALL");
// Perform search with content chunks using the new contextpassages feature
search
contextpassages=5 // Number of passages to retrieve
contextHighlightBegin="<mark>" // Highlighting for matched terms
contextHighlightEnd="</mark>"
contextBytes=4000 // Total bytes of context to retrieve
contextpassageLength=800 // Length of each passage
name="local.searchResults"
collection=collectionName
criteria=criteria
suggestions="always"
maxrows=5; // Limit number of results
// Format the augmented query
var augmentedQuery = "User Query: #userQuery#";
var contextData = [];
// Process search results
loop query=searchResults {
// Access context passages
var contextInfo = searchResults.context;
var passages = contextInfo.passages;
// Prepare source information
var sourceInfo = {
"title": searchResults.title,
"summary": searchResults.summary,
"score": searchResults.score,
"passages": []
};
// Process each passage in the result
loop query=passages {
arrayAppend(sourceInfo.passages, {
"score": passages.score,
"content": passages.original
});
}
// Add this source to our context data
arrayAppend(contextData, sourceInfo);
}
// Only add context if we found relevant information
if(arrayLen(contextData)) {
augmentedQuery &= "
Context Information: #serializeJSON(contextData)#";
}
return augmentedQuery;
}
Usage with AI Functions
You can integrate the augmentation functionality directly with Lucee's AI functions:
// Create an AI session
aiSession = LuceeCreateAISession(name:"myclaude");
// User query
userQuery = "How do I optimize database queries in my application?";
// Augment the query with relevant context from indexed content
augmentedQuery = augmentQuery(userQuery);
// Send to AI with augmented context
response = LuceeInquiryAISession(aiSession, augmentedQuery);
// Display the response
echo(response);
Benefits of AI Augmentation
- Enhanced Relevance: AI responses are informed by your specific content
- Reduced Hallucinations: Grounds responses in factual information from your data
- Domain Knowledge: AI can provide answers specific to your organization or industry
- Content Currency: Responses reflect your latest data, not just the AI's training cutoff
- Customizable Context: Index exactly what matters for your specific use case
- Efficiency: Better initial responses reduce the need for follow-up queries
- Privacy: Sensitive information stays within your system as context
Advanced Features
Content Chunk Optimization
The Lucene Extension 3.0 in Lucee 7 provides enhanced content chunking capabilities that allow for better context extraction:
search
contextpassages=5 // Number of distinct passages to extract
contextHighlightBegin="<mark>" // Optional highlighting for matched terms
contextHighlightEnd="</mark>"
contextBytes=5000 // Total context bytes across all passages
contextpassageLength=1000 // Length of each individual passage
name="local.searchResults"
collection=collectionName
criteria=criteria;
These parameters let you fine-tune how much context is provided to the AI:
contextpassages
: Controls how many separate text segments are returnedcontextBytes
: Sets the maximum total size of all context returnedcontextpassageLength
: Controls the maximum size of each individual passage
Leveraging Vector Search
When creating collections with mode="hybrid"
or mode="vector"
, you can take advantage of semantic search capabilities to find more relevant content:
// Create a hybrid collection
collection action="Create"
collection="semantic_knowledge"
path=collDirectory
mode="hybrid"
embedding="word2vec" // Use word vectors for semantic understanding
ratio="0.7"; // Weight semantic matches higher than keyword matches
The vector search capability helps find conceptually similar content even when exact keywords aren't present, making it especially valuable for AI augmentation.
Security Considerations
- The augmentation process includes indexed content in queries sent to AI providers
- Use local AI endpoints (like Ollama) for sensitive data scenarios
- Implement data filtering to avoid exposing confidential information
- Consider encrypting sensitive indexed content and implementing decryption at query time
- Add audit logging for all AI interactions
Performance Optimization
For best performance with the new Lucene Extension 3.0:
- Index strategically - focus on high-value content
- Use appropriate text segmentation for your domain
- Fine-tune search parameters like
maxrows
andcontextpassages
- Implement caching for frequent queries
- Schedule index maintenance during low-traffic periods
- Monitor performance metrics to optimize configuration
Alternative Storage Options
In addition to Lucene's built-in storage, Redis can be used as an alternative for vector storage:
- Redis includes Redis Stack with the RediSearch module supporting vector similarity search
- It offers high-performance in-memory operations for low-latency vector queries
- The database can scale well for production environments with clustering capabilities
- Redis can be used alongside the Lucene approach or as an alternative
Examples of Use Cases
- Customer Support: Augment AI with product documentation, FAQs, and support history
- Development Assistance: Index code repositories, API docs, and coding standards
- Knowledge Management: Connect AI to your company's internal knowledge base
- Training: Create AI tutors with domain-specific knowledge from your course materials
- Research Assistant: Index research papers and data to enable AI analysis in your field
- Data Analysis: Combine AI with indexed analysis of your business metrics