VKRA Protocol - Open Source Marketing Framework for Contextual Product Matching
Project description
VKRA Protocol
VKRA - Open Source Marketing Framework for Contextual Product Matching in LLM Applications
Vision
Revolutionizing accessible advertisements in LLMs. VKRA is an open-source marketing framework that provides a modular approach to contextual product matching, enabling developers to build monetization into their LLM applications while maintaining user trust and conversation quality.
What is VKRA Protocol?
VKRA Protocol is a modular LLMA (Large Language Model Advertising) framework that implements the "Polite Ad Network" approach. It provides pluggable modules for:
- Presentation: Creating product cards without modifying LLM responses
- Commission: Extracting affiliate commission rates from product data
- Prediction: Calculating conversion probability using personalization
- Ranking: Balancing revenue (commission × conversion) with user satisfaction
The framework is database-agnostic and infrastructure-independent, making it easy to integrate into any application.
Architecture
Module Pipeline
┌─────────────────────────────────────────────────────────┐
│ LLMAOrchestrator │
│ Coordinates the complete matching pipeline │
└─────────────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Presentation │ │ Commission │ │ Prediction │
│ Module │ │ Module │ │ Module │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
└───────────────┼───────────────┘
│
▼
┌──────────────┐
│ Ranking │
│ Module │
└──────────────┘
Core Components
- LLMAOrchestrator: Coordinates all modules in the pipeline
- VectorDatabase Interface: Abstract interface for vector search
- UserProfileStore Interface: Abstract interface for user profile management
- Module Base Classes: Pluggable interfaces for all modules
Key Features
- 🎯 Contextual Matching: Intent-based product recommendations using embeddings
- 🔄 Modular Design: Pluggable modules for easy customization
- 🛡️ Privacy-First: GDPR-compliant with pseudonymization and differential privacy
- ⚡ High Performance: Optimized for sub-200ms latency
- 🔌 Database Agnostic: Works with any vector database implementation
- 📊 Polite Ad Network: Balances revenue with user trust (SR_query metric)
Installation
pip install vkra-protocol
Or install from source:
git clone https://github.com/vkra-project/vkra-python
cd vkra-protocol
pip install -e .
Quick Start
1. Implement Database Interfaces
First, implement the abstract interfaces for your database:
from vkra_protocol import VectorDatabase, UserProfileStore
from typing import Any
from uuid import UUID
class MyVectorDatabase(VectorDatabase):
async def search(
self,
query_embedding: list[float],
limit: int = 10,
filters: dict[str, Any] | None = None,
user_profile_embedding: list[float] | None = None,
query_weight: float = 0.7,
profile_weight: float = 0.3,
) -> tuple[list[dict[str, Any]], int]:
# Your vector search implementation
# Returns (products list, total_matches count)
pass
class MyUserProfileStore(UserProfileStore):
async def get_user_profile(
self,
user_id: UUID,
privacy_level: str = "standard",
) -> dict[str, Any] | None:
# Your user profile retrieval
# Returns profile dict or None
pass
async def update_profile_from_context(
self,
user_id: UUID,
active_context: str,
background: bool = True,
) -> None:
# Your profile update logic
pass
2. Set Up Embedding and LLM Services
Default: Local Ollama (Zero-Friction Setup)
# Install Ollama (if not already installed)
# Visit https://ollama.ai for installation instructions
# Pull the Qwen3 embedding model
ollama pull qwen3-embedding
Option A: Simple Service Usage (Environment Variables)
from vkra_protocol import LLMAOrchestrator, EmbeddingService, LLMService
# Initialize services (defaults to local Ollama)
embedding_service = EmbeddingService() # Uses local Ollama by default
llm_service = LLMService() # Uses local Ollama by default
# Or use OpenAI (optional)
# Set environment variables:
# EMBED_PROVIDER=openai
# LLM_PROVIDER=openai
# OPENAI_API_KEY=your-key
Option B: Advanced Provider Usage (Dependency Injection)
For more control and better testability, use providers directly:
from vkra_protocol import LLMAOrchestrator
from vkra_protocol.providers import (
EmbeddingService,
LLMService,
EmbeddingProviderFactory,
LLMProviderFactory,
)
from vkra_protocol.providers.embedding import OpenAIEmbeddingProvider
from vkra_protocol.providers.llm import OpenAILLMProvider
# Method 1: Use factory with config dict
embedding_provider = EmbeddingProviderFactory.create("openai", {
"api_key": "sk-...",
"model": "text-embedding-3-small"
})
llm_provider = LLMProviderFactory.create("openai", {
"api_key": "sk-...",
"model": "gpt-4o-mini"
})
# Method 2: Create providers directly
embedding_provider = OpenAIEmbeddingProvider(
api_key="sk-...",
model="text-embedding-3-small"
)
llm_provider = OpenAILLMProvider(
api_key="sk-...",
model="gpt-4o-mini"
)
# Wrap in services (or use providers directly if orchestrator supports it)
embedding_service = EmbeddingService(provider=embedding_provider)
llm_service = LLMService(provider=llm_provider)
# Method 3: Factory from environment (same as Option A)
embedding_provider = EmbeddingProviderFactory.create_from_env()
llm_provider = LLMProviderFactory.create_from_env()
embedding_service = EmbeddingService(provider=embedding_provider)
llm_service = LLMService(provider=llm_provider)
Benefits of Provider Pattern:
- ✅ Dependency injection for better testability
- ✅ No hardcoded environment variables
- ✅ Easy to mock in tests
- ✅ Programmatic configuration
- ✅ Consistent error handling (
ProviderError,ProviderConfigurationError,ProviderAPIError)
3. Initialize Orchestrator
from vkra_protocol import LLMAOrchestrator, EmbeddingService, LLMService
# Initialize your implementations
vector_db = MyVectorDatabase()
profile_store = MyUserProfileStore()
embedding_service = EmbeddingService() # Default: local Ollama
llm_service = LLMService() # Default: local Ollama
# Create orchestrator
orchestrator = LLMAOrchestrator(
vector_db=vector_db,
profile_store=profile_store,
embedding_service=embedding_service,
llm_service=llm_service,
)
4. Execute Search
from vkra_protocol.schemas import SearchRequest, UserContext
from uuid import uuid4
# Create search request
request = SearchRequest(
query="wireless headphones for running",
context=UserContext(
user_id=uuid4(), # Optional: for personalization
session_id=uuid4(),
privacy_level="standard",
),
limit=3,
)
# Execute search
response, embedding_time, search_time, cache_hit = await orchestrator.execute_search(request)
# Access results
for result in response.results:
print(f"{result['title']} - {result['price']}")
print(f"Relevance: {result['relevance_score']:.2f}")
print(f"Commission: {result.get('commission_rate', 0):.1%}")
Environment Variables
Default (Local Ollama):
EMBED_PROVIDER=local(default)LOCAL_EMBED_URL=http://localhost:11434/api/embeddings(default)EMBED_MODEL=qwen3-embedding(default)LLM_PROVIDER=local(default)LOCAL_LLM_URL=http://localhost:11434/api/chat(default)LLM_MODEL=qwen3:8b(default)
Optional (OpenAI):
EMBED_PROVIDER=openai(to use OpenAI)OPENAI_API_KEY: Required if using OpenAIOPENAI_EMBED_MODEL=text-embedding-3-small(default)OPENAI_LLM_MODEL=gpt-4o-mini(default)
Optional (Other Providers):
EMBED_PROVIDER=cohere→COHERE_API_KEY,COHERE_EMBED_MODELEMBED_PROVIDER=huggingface→HUGGINGFACE_API_KEY,HUGGINGFACE_EMBED_MODELLLM_PROVIDER=anthropic→ANTHROPIC_API_KEY,ANTHROPIC_LLM_MODELLLM_PROVIDER=gemini→GEMINI_API_KEY,GEMINI_LLM_MODEL
Supported Providers
Embedding Providers
- OpenAI:
text-embedding-3-small(1536 dims, auto-detected) - Cohere:
embed-v4.0(1024-1536 dims, auto-detected) - HuggingFace: Various models (dims vary, auto-detected)
- Local (Ollama/vLLM): Any local model (dims vary, auto-detected)
LLM Providers
- OpenAI:
gpt-4o-mini,gpt-4o, etc. - Anthropic:
claude-3-5-haiku-latest,claude-sonnet-4-5, etc. - Google Gemini:
gemini-2.5-flash,gemini-2.5-pro, etc. - Local (Ollama/vLLM): Any local model
Note on Dimensions: Embedding dimensions are detected automatically from the first API call. No need to hardcode dimension values!
Module Configuration
Customize module behavior per request:
from vkra_protocol.schemas import ModuleConfig, SearchRequest
module_config = ModuleConfig(
presentation_module="product_card",
commission_module="extract",
prediction_module="conversion",
ranking_module="affiliate",
module_params={
"prediction_sr_query_threshold": 0.7, # Polite Ad filter
"prediction_sr_query_weight": 0.3,
"prediction_sr_history_weight": 0.5,
"ranking_sr_query_weight": 0.6,
"ranking_sr_history_weight": 0.4,
},
)
request = SearchRequest(
query="laptop for programming",
module_config=module_config,
limit=5,
)
Module Documentation
Presentation Module
Creates product cards from database results. Does NOT modify LLM response text - preserves agent's voice.
Interface: PresentationModule.create_product_cards()
Implementation: ProductCardPresentationModule
Commission Module
Extracts commission rates from product data. Rates are stored in product metadata (no external lookup).
Interface: CommissionModule.extract_commission_rates()
Implementation: CommissionExtractionModule
Prediction Module
Calculates:
- SR_query: Query-based satisfaction rate (Polite Ad metric - measures interruption)
- SR_history: History-based satisfaction rate (personalization)
- Conversion probability: Combined prediction
Interface: PredictionModule.predict_conversion()
Implementation: ConversionPredictionModule
Polite Ad Filter: Products with SR_query < threshold (default 0.7) are filtered out to maintain conversation quality.
Ranking Module
Ranks products using:
Score = Commission × Conversion × (SR_query × w1 + SR_history × w2)
This balances revenue with user trust.
Interface: RankingModule.rank_products()
Implementation: AffiliateRankingModule
User Preference Module
Handles user profile management with GDPR compliance:
- Profile retrieval and summarization
- Embedding generation
- Privacy safeguards (pseudonymization, differential privacy)
Interface: UserPreferenceModule.get_user_profile(), update_profile_from_context()
Implementation: UserPreferenceMaintenanceModule
Privacy & GDPR Compliance
VKRA Protocol supports three privacy levels:
- minimal: Query-only, no user profile
- standard: Pseudonymized user IDs, profile embeddings
- full: Differential privacy noise added to embeddings
context = UserContext(
user_id=user_id,
privacy_level="standard", # or "minimal", "full"
include_history=True,
)
Examples
See the examples/ directory for complete working examples:
- Basic search
- Personalized search with user profiles
- Custom module configuration
- Integration with FastAPI
Contributing
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
Architecture Principles
- Interface First: All modules use abstract base classes
- Database Agnostic: No hardcoded database dependencies
- Async Everything: All I/O operations are async
- Privacy by Design: GDPR compliance built-in
- Performance First: Optimized for low latency
Performance Targets
- End-to-end latency: < 200ms
- Profile loading: < 50ms (cached)
- Vector search: < 100ms
- Module pipeline: < 50ms
License
This project is licensed under the MIT License - see the LICENSE file for details.
Cloud Offering
For a managed service with:
- Pre-configured databases (LanceDB Cloud, Supabase)
- API key management
- Analytics dashboard
- MCP server integration
Visit: https://www.vkra.org
Support
- Documentation: https://docs.vkra.org
- Issues: GitHub Issues
- Email: hello@vkra.org
Made for developers building the future of AI agents 🤖
Get started today: https://www.vkra.org
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vkra_protocol-0.3.3.tar.gz.
File metadata
- Download URL: vkra_protocol-0.3.3.tar.gz
- Upload date:
- Size: 45.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e64b2cae9b33eca6ef423a6f7e70c16d51f94638e349a5d62a2bf732fc23022b
|
|
| MD5 |
d7a26a1498982abef6576457dd5f11ed
|
|
| BLAKE2b-256 |
8230e73b204bacb2f65c97187fc4a8ce4c82333332bd43d46baf4dbf19d27166
|
Provenance
The following attestation bundles were made for vkra_protocol-0.3.3.tar.gz:
Publisher:
publish.yml on VKRA-Project/vkra-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vkra_protocol-0.3.3.tar.gz -
Subject digest:
e64b2cae9b33eca6ef423a6f7e70c16d51f94638e349a5d62a2bf732fc23022b - Sigstore transparency entry: 867508985
- Sigstore integration time:
-
Permalink:
VKRA-Project/vkra-python@0fb696b5098facd0e355cf94cdc1f7277a5c4b36 -
Branch / Tag:
refs/tags/v0.3.3 - Owner: https://github.com/VKRA-Project
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0fb696b5098facd0e355cf94cdc1f7277a5c4b36 -
Trigger Event:
push
-
Statement type:
File details
Details for the file vkra_protocol-0.3.3-py3-none-any.whl.
File metadata
- Download URL: vkra_protocol-0.3.3-py3-none-any.whl
- Upload date:
- Size: 47.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a0cac6326dc1d396294424c442e2019f9d8b4b97697e95a9988dc1a09cee867f
|
|
| MD5 |
234c3c8b4292a5fee326d84dee6199da
|
|
| BLAKE2b-256 |
35c1fb253505621252b6696decc42231eff243dc80fa064f7ab45044d42511ba
|
Provenance
The following attestation bundles were made for vkra_protocol-0.3.3-py3-none-any.whl:
Publisher:
publish.yml on VKRA-Project/vkra-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vkra_protocol-0.3.3-py3-none-any.whl -
Subject digest:
a0cac6326dc1d396294424c442e2019f9d8b4b97697e95a9988dc1a09cee867f - Sigstore transparency entry: 867509015
- Sigstore integration time:
-
Permalink:
VKRA-Project/vkra-python@0fb696b5098facd0e355cf94cdc1f7277a5c4b36 -
Branch / Tag:
refs/tags/v0.3.3 - Owner: https://github.com/VKRA-Project
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0fb696b5098facd0e355cf94cdc1f7277a5c4b36 -
Trigger Event:
push
-
Statement type: