docs: Rename NL2SQL documentation to LLM Bridge

- Rename doc/NL2SQL/ to doc/LLM_Bridge/
- Update README.md for generic LLM bridge functionality
- Replace NL2SQL terminology with LLM Bridge
- Update variable references from ai_nl2sql_* to genai_llm_*
- Add migration guide from NL2SQL to LLM Bridge
- Document new use cases (summarization, code generation, etc.)
pull/5310/head
Rene Cannao 3 months ago
parent a3f0bade4e
commit 5afb71ca90

@ -1,4 +1,4 @@
# NL2SQL API Reference
# LLM Bridge API Reference
## Complete API Documentation
@ -8,17 +8,17 @@ This document provides a comprehensive reference for all NL2SQL APIs, including
- [Configuration Variables](#configuration-variables)
- [Data Structures](#data-structures)
- [NL2SQL_Converter Class](#nl2sql_converter-class)
- [LLM_Bridge Class](#nl2sql_converter-class)
- [AI_Features_Manager Class](#ai_features_manager-class)
- [MySQL Protocol Integration](#mysql-protocol-integration)
## Configuration Variables
All NL2SQL variables use the `ai_nl2sql_` prefix and are accessible via the ProxySQL admin interface.
All LLM variables use the `genai_llm_` prefix and are accessible via the ProxySQL admin interface.
### Master Switch
#### `ai_nl2sql_enabled`
#### `genai_llm_enabled`
- **Type**: Boolean
- **Default**: `true`
@ -26,13 +26,13 @@ All NL2SQL variables use the `ai_nl2sql_` prefix and are accessible via the Prox
- **Runtime**: Yes
- **Example**:
```sql
SET ai_nl2sql_enabled='true';
SET genai_llm_enabled='true';
LOAD MYSQL VARIABLES TO RUNTIME;
```
### Query Detection
#### `ai_nl2sql_query_prefix`
#### `genai_llm_query_prefix`
- **Type**: String
- **Default**: `NL2SQL:`
@ -40,13 +40,13 @@ All NL2SQL variables use the `ai_nl2sql_` prefix and are accessible via the Prox
- **Runtime**: Yes
- **Example**:
```sql
SET ai_nl2sql_query_prefix='SQL:';
SET genai_llm_query_prefix='SQL:';
-- Now use: SQL: Show customers
```
### Model Selection
#### `ai_nl2sql_provider`
#### `genai_llm_provider`
- **Type**: Enum (`openai`, `anthropic`)
- **Default**: `openai`
@ -54,11 +54,11 @@ All NL2SQL variables use the `ai_nl2sql_` prefix and are accessible via the Prox
- **Runtime**: Yes
- **Example**:
```sql
SET ai_nl2sql_provider='openai';
SET genai_llm_provider='openai';
LOAD MYSQL VARIABLES TO RUNTIME;
```
#### `ai_nl2sql_provider_url`
#### `genai_llm_provider_url`
- **Type**: String
- **Default**: `http://localhost:11434/v1/chat/completions`
@ -67,16 +67,16 @@ All NL2SQL variables use the `ai_nl2sql_` prefix and are accessible via the Prox
- **Example**:
```sql
-- For OpenAI
SET ai_nl2sql_provider_url='https://api.openai.com/v1/chat/completions';
SET genai_llm_provider_url='https://api.openai.com/v1/chat/completions';
-- For Ollama (via OpenAI-compatible endpoint)
SET ai_nl2sql_provider_url='http://localhost:11434/v1/chat/completions';
SET genai_llm_provider_url='http://localhost:11434/v1/chat/completions';
-- For Anthropic
SET ai_nl2sql_provider_url='https://api.anthropic.com/v1/messages';
SET genai_llm_provider_url='https://api.anthropic.com/v1/messages';
```
#### `ai_nl2sql_provider_model`
#### `genai_llm_provider_model`
- **Type**: String
- **Default**: `llama3.2`
@ -84,10 +84,10 @@ All NL2SQL variables use the `ai_nl2sql_` prefix and are accessible via the Prox
- **Runtime**: Yes
- **Example**:
```sql
SET ai_nl2sql_provider_model='gpt-4o';
SET genai_llm_provider_model='gpt-4o';
```
#### `ai_nl2sql_provider_key`
#### `genai_llm_provider_key`
- **Type**: String (sensitive)
- **Default**: NULL
@ -95,12 +95,12 @@ All NL2SQL variables use the `ai_nl2sql_` prefix and are accessible via the Prox
- **Runtime**: Yes
- **Example**:
```sql
SET ai_nl2sql_provider_key='sk-your-api-key';
SET genai_llm_provider_key='sk-your-api-key';
```
### Cache Configuration
#### `ai_nl2sql_cache_similarity_threshold`
#### `genai_llm_cache_similarity_threshold`
- **Type**: Integer (0-100)
- **Default**: `85`
@ -108,12 +108,12 @@ All NL2SQL variables use the `ai_nl2sql_` prefix and are accessible via the Prox
- **Runtime**: Yes
- **Example**:
```sql
SET ai_nl2sql_cache_similarity_threshold='90';
SET genai_llm_cache_similarity_threshold='90';
```
### Performance
#### `ai_nl2sql_timeout_ms`
#### `genai_llm_timeout_ms`
- **Type**: Integer
- **Default**: `30000` (30 seconds)
@ -121,12 +121,12 @@ All NL2SQL variables use the `ai_nl2sql_` prefix and are accessible via the Prox
- **Runtime**: Yes
- **Example**:
```sql
SET ai_nl2sql_timeout_ms='60000';
SET genai_llm_timeout_ms='60000';
```
### Routing
#### `ai_nl2sql_prefer_local`
#### `genai_llm_prefer_local`
- **Type**: Boolean
- **Default**: `true`
@ -134,12 +134,12 @@ All NL2SQL variables use the `ai_nl2sql_` prefix and are accessible via the Prox
- **Runtime**: Yes
- **Example**:
```sql
SET ai_nl2sql_prefer_local='false';
SET genai_llm_prefer_local='false';
```
## Data Structures
### NL2SQLRequest
### LLM BridgeRequest
```cpp
struct NL2SQLRequest {
@ -187,11 +187,11 @@ struct NL2SQLRequest {
| `retry_multiplier` | double | 2.0 | Exponential backoff multiplier |
| `retry_max_backoff_ms` | int | 30000 | Maximum backoff in milliseconds |
### NL2SQLResult
### LLM BridgeResult
```cpp
struct NL2SQLResult {
std::string sql_query; // Generated SQL query
std::string text_response; // Generated SQL query
float confidence; // Confidence score 0.0-1.0
std::string explanation; // Which model generated this
std::vector<std::string> tables_used; // Tables referenced in SQL
@ -212,7 +212,7 @@ struct NL2SQLResult {
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `sql_query` | string | "" | Generated SQL query |
| `text_response` | string | "" | Generated SQL query |
| `confidence` | float | 0.0 | Confidence score (0.0-1.0) |
| `explanation` | string | "" | Model/provider info |
| `tables_used` | vector<string> | {} | Tables referenced in SQL |
@ -233,7 +233,7 @@ enum class ModelProvider {
};
```
### NL2SQLErrorCode Enum
### LLM BridgeErrorCode Enum
```cpp
enum class NL2SQLErrorCode {
@ -260,12 +260,12 @@ const char* nl2sql_error_code_to_string(NL2SQLErrorCode code);
Converts error code enum to string representation for logging and display purposes.
## NL2SQL_Converter Class
## LLM Bridge_Converter Class
### Constructor
```cpp
NL2SQL_Converter::NL2SQL_Converter();
LLM_Bridge::LLM_Bridge();
```
Initializes with default configuration values.
@ -273,7 +273,7 @@ Initializes with default configuration values.
### Destructor
```cpp
NL2SQL_Converter::~NL2SQL_Converter();
LLM_Bridge::~LLM_Bridge();
```
Frees allocated resources.
@ -283,7 +283,7 @@ Frees allocated resources.
#### `init()`
```cpp
int NL2SQL_Converter::init();
int LLM_Bridge::init();
```
Initialize the NL2SQL converter.
@ -293,7 +293,7 @@ Initialize the NL2SQL converter.
#### `close()`
```cpp
void NL2SQL_Converter::close();
void LLM_Bridge::close();
```
Shutdown and cleanup resources.
@ -301,7 +301,7 @@ Shutdown and cleanup resources.
#### `convert()`
```cpp
NL2SQLResult NL2SQL_Converter::convert(const NL2SQLRequest& req);
NL2SQLResult LLM_Bridge::convert(const NL2SQLRequest& req);
```
Convert natural language to SQL.
@ -318,14 +318,14 @@ req.natural_language = "Show top 10 customers";
req.allow_cache = true;
NL2SQLResult result = converter->convert(req);
if (result.confidence > 0.7f) {
execute_sql(result.sql_query);
execute_sql(result.text_response);
}
```
#### `clear_cache()`
```cpp
void NL2SQL_Converter::clear_cache();
void LLM_Bridge::clear_cache();
```
Clear all cached NL2SQL conversions.
@ -333,7 +333,7 @@ Clear all cached NL2SQL conversions.
#### `get_cache_stats()`
```cpp
std::string NL2SQL_Converter::get_cache_stats();
std::string LLM_Bridge::get_cache_stats();
```
Get cache statistics as JSON.
@ -356,16 +356,16 @@ Get cache statistics as JSON.
#### `get_nl2sql()`
```cpp
NL2SQL_Converter* AI_Features_Manager::get_nl2sql();
LLM_Bridge* AI_Features_Manager::get_nl2sql();
```
Get the NL2SQL converter instance.
**Returns**: Pointer to NL2SQL_Converter or NULL
**Returns**: Pointer to LLM_Bridge or NULL
**Example**:
```cpp
NL2SQL_Converter* nl2sql = GloAI->get_nl2sql();
LLM_Bridge* nl2sql = GloAI->get_nl2sql();
if (nl2sql) {
NL2SQLResult result = nl2sql->convert(req);
}
@ -380,7 +380,7 @@ char* AI_Features_Manager::get_variable(const char* name);
Get configuration variable value.
**Parameters**:
- `name`: Variable name (without `ai_nl2sql_` prefix)
- `name`: Variable name (without `genai_llm_` prefix)
**Returns**: Variable value or NULL
@ -398,7 +398,7 @@ bool AI_Features_Manager::set_variable(const char* name, const char* value);
Set configuration variable value.
**Parameters**:
- `name`: Variable name (without `ai_nl2sql_` prefix)
- `name`: Variable name (without `genai_llm_` prefix)
- `value`: New value
**Returns**: true on success, false on failure
@ -424,7 +424,7 @@ Results are returned as a standard MySQL resultset with columns:
| Column | Type | Description |
|--------|------|-------------|
| `sql_query` | TEXT | Generated SQL query |
| `text_response` | TEXT | Generated SQL query |
| `confidence` | FLOAT | Confidence score |
| `explanation` | TEXT | Model info |
| `cached` | BOOLEAN | From cache |
@ -440,7 +440,7 @@ Results are returned as a standard MySQL resultset with columns:
mysql> USE my_database;
mysql> NL2SQL: Show top 10 customers by revenue;
+---------------------------------------------+------------+-------------------------+--------+----------+
| sql_query | confidence | explanation | cached | cache_id |
| text_response | confidence | explanation | cached | cache_id |
+---------------------------------------------+------------+-------------------------+--------+----------+
| SELECT * FROM customers ORDER BY revenue | 0.850 | Generated by Ollama | 0 | 0 |
| DESC LIMIT 10 | | llama3.2 | | |
@ -456,9 +456,9 @@ These error codes are returned in the `error_code` field of NL2SQLResult:
| Code | Description | HTTP Status | Action |
|------|-------------|-------------|--------|
| `ERR_API_KEY_MISSING` | API key not configured | N/A | Configure API key via `ai_nl2sql_provider_key` |
| `ERR_API_KEY_MISSING` | API key not configured | N/A | Configure API key via `genai_llm_provider_key` |
| `ERR_API_KEY_INVALID` | API key format is invalid | N/A | Verify API key format |
| `ERR_TIMEOUT` | Request timed out | N/A | Increase `ai_nl2sql_timeout_ms` |
| `ERR_TIMEOUT` | Request timed out | N/A | Increase `genai_llm_timeout_ms` |
| `ERR_CONNECTION_FAILED` | Network connection failed | 0 | Check network connectivity |
| `ERR_RATE_LIMITED` | Rate limited by provider | 429 | Wait and retry, or use different endpoint |
| `ERR_SERVER_ERROR` | Server error (5xx) | 500-599 | Retry or check provider status |
@ -473,8 +473,8 @@ These error codes are returned in the `error_code` field of NL2SQLResult:
| Code | Description | Action |
|------|-------------|--------|
| `ER_NL2SQL_DISABLED` | NL2SQL feature is disabled | Enable via `ai_nl2sql_enabled` |
| `ER_NL2SQL_TIMEOUT` | LLM request timed out | Increase `ai_nl2sql_timeout_ms` |
| `ER_NL2SQL_DISABLED` | NL2SQL feature is disabled | Enable via `genai_llm_enabled` |
| `ER_NL2SQL_TIMEOUT` | LLM request timed out | Increase `genai_llm_timeout_ms` |
| `ER_NL2SQL_NO_MODEL` | No LLM model available | Configure API key or Ollama |
| `ER_NL2SQL_API_ERROR` | LLM API returned error | Check logs and API key |
| `ER_NL2SQL_INVALID_QUERY` | Query doesn't start with prefix | Use correct prefix format |
@ -486,7 +486,7 @@ Monitor NL2SQL performance via status variables:
```sql
-- View all AI status variables
SELECT * FROM runtime_mysql_servers
WHERE variable_name LIKE 'ai_nl2sql_%';
WHERE variable_name LIKE 'genai_llm_%';
-- Key metrics
SELECT * FROM stats_ai_nl2sql;
@ -495,7 +495,7 @@ SELECT * FROM stats_ai_nl2sql;
| Variable | Description |
|----------|-------------|
| `nl2sql_total_requests` | Total NL2SQL conversions |
| `nl2sql_cache_hits` | Cache hit count |
| `llm_cache_hits` | Cache hit count |
| `nl2sql_local_model_calls` | Ollama API calls |
| `nl2sql_cloud_model_calls` | Cloud API calls |

@ -1,4 +1,4 @@
# NL2SQL Architecture
# LLM Bridge Architecture
## System Overview
@ -13,7 +13,7 @@ GenAI Module (async via socketpair)
├─ GenAI worker thread processes request
└─ AI_Features_Manager::get_nl2sql()
NL2SQL_Converter::convert()
LLM_Bridge::convert()
├─ check_vector_cache() ← sqlite-vec similarity search
├─ build_prompt() ← Schema context via MySQL_Tool_Handler
├─ select_model() ← Ollama/OpenAI/Anthropic selection
@ -22,7 +22,7 @@ GenAI Module (async via socketpair)
Async response back to MySQL_Session
Return Resultset (sql_query, confidence, ...)
Return Resultset (text_response, confidence, ...)
```
**Important**: NL2SQL uses an **asynchronous, non-blocking architecture**. The MySQL thread is not blocked while waiting for the LLM response. The request is sent via socketpair to the GenAI module, which processes it in a worker thread and delivers the result asynchronously.
@ -39,7 +39,7 @@ Return Resultset (sql_query, confidence, ...)
2. **GenAI Worker Thread**:
- Receives request via socketpair
- Calls `process_json_query()` with nl2sql operation type
- Invokes `NL2SQL_Converter::convert()`
- Invokes `LLM_Bridge::convert()`
- Processes LLM response (HTTP via libcurl)
- Sends result back via socketpair
@ -50,9 +50,9 @@ Return Resultset (sql_query, confidence, ...)
## Components
### 1. NL2SQL_Converter
### 1. LLM_Bridge
**Location**: `include/NL2SQL_Converter.h`, `lib/NL2SQL_Converter.cpp`
**Location**: `include/LLM_Bridge.h`, `lib/LLM_Bridge.cpp`
Main class coordinating the NL2SQL conversion pipeline.
@ -186,17 +186,17 @@ HTTP clients for each LLM provider using libcurl.
```sql
-- Cache entries
CREATE TABLE nl2sql_cache (
CREATE TABLE llm_cache (
id INTEGER PRIMARY KEY AUTOINCREMENT,
natural_language TEXT NOT NULL,
sql_query TEXT NOT NULL,
text_response TEXT NOT NULL,
model_provider TEXT,
confidence REAL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- Virtual table for similarity search
CREATE VIRTUAL TABLE nl2sql_cache_vec USING vec0(
CREATE VIRTUAL TABLE llm_cache_vec USING vec0(
embedding FLOAT[1536], -- Dimension depends on embedding model
id INTEGER PRIMARY KEY
);
@ -204,9 +204,9 @@ CREATE VIRTUAL TABLE nl2sql_cache_vec USING vec0(
**Similarity Search:**
```sql
SELECT nc.sql_query, nc.confidence, distance
FROM nl2sql_cache_vec
JOIN nl2sql_cache nc ON nl2sql_cache_vec.id = nc.id
SELECT nc.text_response, nc.confidence, distance
FROM llm_cache_vec
JOIN llm_cache nc ON llm_cache_vec.id = nc.id
WHERE embedding MATCH ?
AND k = 10 -- Return top 10 matches
ORDER BY distance
@ -233,8 +233,8 @@ Coordinates all AI features including NL2SQL.
**Responsibilities:**
- Initialize vector database
- Create and manage NL2SQL_Converter instance
- Handle configuration variables with `ai_nl2sql_` prefix
- Create and manage LLM_Bridge instance
- Handle configuration variables with `genai_llm_` prefix
- Provide thread-safe access to components
## Flow Diagrams
@ -292,7 +292,7 @@ Coordinates all AI features including NL2SQL.
┌──────────────────┐
│ Return Result │
│ - sql_query
│ - text_response
│ - confidence │
│ - explanation │
└──────────────────┘
@ -341,7 +341,7 @@ Coordinates all AI features including NL2SQL.
## Data Structures
### NL2SQLRequest
### LLM BridgeRequest
```cpp
struct NL2SQLRequest {
@ -353,11 +353,11 @@ struct NL2SQLRequest {
};
```
### NL2SQLResult
### LLM BridgeResult
```cpp
struct NL2SQLResult {
std::string sql_query; // Generated SQL
std::string text_response; // Generated SQL
float confidence; // 0.0-1.0 score
std::string explanation; // Model info
std::vector<std::string> tables_used; // Referenced tables
@ -370,20 +370,20 @@ struct NL2SQLResult {
### Variable Namespacing
All NL2SQL variables use `ai_nl2sql_` prefix:
All LLM variables use `genai_llm_` prefix:
```
ai_nl2sql_enabled
ai_nl2sql_query_prefix
ai_nl2sql_model_provider
ai_nl2sql_ollama_model
ai_nl2sql_openai_model
ai_nl2sql_anthropic_model
ai_nl2sql_cache_similarity_threshold
ai_nl2sql_timeout_ms
ai_nl2sql_openai_key
ai_nl2sql_anthropic_key
ai_nl2sql_prefer_local
genai_llm_enabled
genai_llm_query_prefix
genai_llm_model_provider
genai_llm_ollama_model
genai_llm_openai_model
genai_llm_anthropic_model
genai_llm_cache_similarity_threshold
genai_llm_timeout_ms
genai_llm_openai_key
genai_llm_anthropic_key
genai_llm_prefer_local
```
### Variable Persistence
@ -393,7 +393,7 @@ Runtime (memory)
| LOAD MYSQL VARIABLES TO RUNTIME
|
| SET ai_nl2sql_... = 'value'
| SET genai_llm_... = 'value'
|
| SAVE MYSQL VARIABLES TO DISK
@ -402,7 +402,7 @@ Disk (config file)
## Thread Safety
- **NL2SQL_Converter**: NOT thread-safe by itself
- **LLM_Bridge**: NOT thread-safe by itself
- **AI_Features_Manager**: Provides thread-safe access via `wrlock()`/`wrunlock()`
- **Vector Cache**: Thread-safe via SQLite mutex
@ -439,7 +439,7 @@ NL2SQL: Conversion complete. Confidence: 0.85
1. **Caching**: Enable for repeated queries
2. **Local First**: Prefer Ollama for lower latency
3. **Timeout**: Set appropriate `ai_nl2sql_timeout_ms`
3. **Timeout**: Set appropriate `genai_llm_timeout_ms`
4. **Batch Requests**: Not yet implemented (planned)
### Resource Usage

@ -0,0 +1,474 @@
# LLM Bridge - Generic LLM Access for ProxySQL
## Overview
LLM Bridge is a ProxySQL feature that provides generic access to Large Language Models (LLMs) through the MySQL protocol. It allows you to send any prompt to an LLM and receive the response as a MySQL resultset.
**Note:** This feature was previously called "NL2SQL" (Natural Language to SQL) but has been converted to a generic LLM bridge. Future NL2SQL functionality will be implemented as a Web UI using external agents (Claude Code + MCP server).
## Features
- **Generic Provider Support**: Works with any OpenAI-compatible or Anthropic-compatible endpoint
- **Semantic Caching**: Vector-based cache for similar prompts using sqlite-vec
- **Multi-Provider**: Switch between LLM providers seamlessly
- **Versatile**: Use LLMs for summarization, code generation, translation, analysis, etc.
**Supported Endpoints:**
- Ollama (via OpenAI-compatible `/v1/chat/completions` endpoint)
- OpenAI
- Anthropic
- vLLM
- LM Studio
- Z.ai
- Any other OpenAI-compatible or Anthropic-compatible endpoint
## Quick Start
### 1. Enable LLM Bridge
```sql
-- Via admin interface
SET genai-llm_enabled='true';
LOAD GENAI VARIABLES TO RUNTIME;
```
### 2. Configure LLM Provider
ProxySQL uses a **generic provider configuration** that supports any OpenAI-compatible or Anthropic-compatible endpoint.
**Using Ollama (default):**
Ollama is used via its OpenAI-compatible endpoint:
```sql
SET genai-llm_provider='openai';
SET genai-llm_provider_url='http://localhost:11434/v1/chat/completions';
SET genai-llm_provider_model='llama3.2';
SET genai-llm_provider_key=''; -- Empty for local Ollama
LOAD GENAI VARIABLES TO RUNTIME;
```
**Using OpenAI:**
```sql
SET genai-llm_provider='openai';
SET genai-llm_provider_url='https://api.openai.com/v1/chat/completions';
SET genai-llm_provider_model='gpt-4';
SET genai-llm_provider_key='sk-...'; -- Your OpenAI API key
LOAD GENAI VARIABLES TO RUNTIME;
```
**Using Anthropic:**
```sql
SET genai-llm_provider='anthropic';
SET genai-llm_provider_url='https://api.anthropic.com/v1/messages';
SET genai-llm_provider_model='claude-3-opus-20240229';
SET genai-llm_provider_key='sk-ant-...'; -- Your Anthropic API key
LOAD GENAI VARIABLES TO RUNTIME;
```
**Using any OpenAI-compatible endpoint:**
This works with **any** OpenAI-compatible API (vLLM, LM Studio, Z.ai, etc.):
```sql
SET genai-llm_provider='openai';
SET genai-llm_provider_url='https://your-endpoint.com/v1/chat/completions';
SET genai-llm_provider_model='your-model-name';
SET genai-llm_provider_key='your-api-key'; -- Empty for local endpoints
LOAD GENAI VARIABLES TO RUNTIME;
```
### 3. Use the LLM Bridge
Once configured, you can send prompts using the `/* LLM: */` prefix:
```sql
-- Summarize text
mysql> /* LLM: */ Summarize the customer feedback from last week
-- Explain SQL queries
mysql> /* LLM: */ Explain this query: SELECT COUNT(*) FROM users WHERE active = 1
-- Generate code
mysql> /* LLM: */ Generate a Python function to validate email addresses
-- Translate text
mysql> /* LLM: */ Translate "Hello world" to Spanish
-- Analyze data
mysql> /* LLM: */ Analyze the following sales data and provide insights
```
**Important**: LLM queries are executed in the **MySQL module** (your regular SQL client), not in the ProxySQL Admin interface. The Admin interface is only for configuration.
## Response Format
The LLM Bridge returns a resultset with the following columns:
| Column | Description |
|--------|-------------|
| `text_response` | The LLM's text response |
| `explanation` | Which model/provider generated the response |
| `cached` | Whether the response was from cache (true/false) |
| `provider` | The provider used (openai/anthropic) |
## Configuration Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `genai-llm_enabled` | false | Master enable for LLM bridge |
| `genai-llm_provider` | openai | Provider type (openai/anthropic) |
| `genai-llm_provider_url` | http://localhost:11434/v1/chat/completions | LLM endpoint URL |
| `genai-llm_provider_model` | llama3.2 | Model name |
| `genai-llm_provider_key` | (empty) | API key (optional for local) |
| `genai-llm_cache_enabled` | true | Enable semantic cache |
| `genai-llm_cache_similarity_threshold` | 85 | Cache similarity threshold (0-100) |
| `genai-llm_timeout_ms` | 30000 | Request timeout in milliseconds |
### Request Configuration (Advanced)
When using LLM bridge programmatically, you can configure retry behavior:
| Parameter | Default | Description |
|-----------|---------|-------------|
| `max_retries` | 3 | Maximum retry attempts for transient failures |
| `retry_backoff_ms` | 1000 | Initial backoff in milliseconds |
| `retry_multiplier` | 2.0 | Backoff multiplier for exponential backoff |
| `retry_max_backoff_ms` | 30000 | Maximum backoff in milliseconds |
| `allow_cache` | true | Enable semantic cache lookup |
### Error Handling
LLM Bridge provides structured error information to help diagnose issues:
| Error Code | Description | HTTP Status |
|-----------|-------------|-------------|
| `ERR_API_KEY_MISSING` | API key not configured | N/A |
| `ERR_API_KEY_INVALID` | API key format is invalid | N/A |
| `ERR_TIMEOUT` | Request timed out | N/A |
| `ERR_CONNECTION_FAILED` | Network connection failed | 0 |
| `ERR_RATE_LIMITED` | Rate limited by provider | 429 |
| `ERR_SERVER_ERROR` | Server error | 500-599 |
| `ERR_EMPTY_RESPONSE` | Empty response from LLM | N/A |
| `ERR_INVALID_RESPONSE` | Malformed response from LLM | N/A |
| `ERR_VALIDATION_FAILED` | Input validation failed | N/A |
| `ERR_UNKNOWN_PROVIDER` | Invalid provider name | N/A |
| `ERR_REQUEST_TOO_LARGE` | Request exceeds size limit | 413 |
**Result Fields:**
- `error_code`: Structured error code (e.g., "ERR_API_KEY_MISSING")
- `error_details`: Detailed error context with query, provider, URL
- `http_status_code`: HTTP status code if applicable
- `provider_used`: Which provider was attempted
### Request Correlation
Each LLM request generates a unique request ID for log correlation:
```
LLM [a1b2c3d4-e5f6-7890-abcd-ef1234567890]: REQUEST url=http://... model=llama3.2
LLM [a1b2c3d4-e5f6-7890-abcd-ef1234567890]: RESPONSE status=200 duration_ms=1234
```
This allows tracing a single request through all log lines for debugging.
## Use Cases
### 1. Text Summarization
```sql
/* LLM: */ Summarize this text: [long text...]
```
### 2. Code Generation
```sql
/* LLM: */ Write a Python function to check if a number is prime
/* LLM: */ Generate a SQL query to find duplicate users
```
### 3. Query Explanation
```sql
/* LLM: */ Explain what this query does: SELECT * FROM orders WHERE status = 'pending'
/* LLM: */ Why is this query slow: SELECT * FROM users JOIN orders ON...
```
### 4. Data Analysis
```sql
/* LLM: */ Analyze this CSV data and identify trends: [data...]
/* LLM: */ What insights can you derive from these sales figures?
```
### 5. Translation
```sql
/* LLM: */ Translate "Good morning" to French, German, and Spanish
/* LLM: */ Convert this SQL query to PostgreSQL dialect
```
### 6. Documentation
```sql
/* LLM: */ Write documentation for this function: [code...]
/* LLM: */ Generate API documentation for the users endpoint
```
### 7. Code Review
```sql
/* LLM: */ Review this code for security issues: [code...]
/* LLM: */ Suggest optimizations for this query
```
## Examples
### Basic Usage
```sql
-- Get a summary
mysql> /* LLM: */ What is machine learning?
-- Generate code
mysql> /* LLM: */ Write a function to calculate fibonacci numbers in JavaScript
-- Explain concepts
mysql> /* LLM: */ Explain the difference between INNER JOIN and LEFT JOIN
```
### Complex Prompts
```sql
-- Multi-step reasoning
mysql> /* LLM: */ Analyze the performance implications of using VARCHAR(255) vs TEXT in MySQL
-- Code with specific requirements
mysql> /* LLM: */ Write a Python script that reads a CSV file, filters rows where amount > 100, and outputs to JSON
-- Technical documentation
mysql> /* LLM: */ Create API documentation for a user registration endpoint with validation rules
```
### Results
LLM Bridge returns a resultset with:
| Column | Type | Description |
|--------|------|-------------|
| `text_response` | TEXT | LLM's text response |
| `explanation` | TEXT | Which model was used |
| `cached` | BOOLEAN | Whether from semantic cache |
| `error_code` | TEXT | Structured error code (if error) |
| `error_details` | TEXT | Detailed error context (if error) |
| `http_status_code` | INT | HTTP status code (if applicable) |
| `provider` | TEXT | Which provider was used |
**Example successful response:**
```
+-------------------------------------------------------------+----------------------+------+----------+
| text_response | explanation | cached | provider |
+-------------------------------------------------------------+----------------------+------+----------+
| Machine learning is a subset of artificial intelligence | Generated by llama3.2 | 0 | openai |
| that enables systems to learn from data... | | | |
+-------------------------------------------------------------+----------------------+------+----------+
```
**Example error response:**
```
+-----------------------------------------------------------------------+
| text_response |
+-----------------------------------------------------------------------+
| -- LLM processing failed |
| |
| error_code: ERR_API_KEY_MISSING |
| error_details: LLM processing failed: |
| Query: What is machine learning? |
| Provider: openai |
| URL: https://api.openai.com/v1/chat/completions |
| Error: API key not configured |
| |
| http_status_code: 0 |
| provider_used: openai |
+-----------------------------------------------------------------------+
```
## Troubleshooting
### LLM Bridge returns empty result
1. Check AI module is initialized:
```sql
SELECT * FROM runtime_mysql_servers WHERE variable_name LIKE 'ai_%';
```
2. Verify LLM is accessible:
```bash
# For Ollama
curl http://localhost:11434/api/tags
# For cloud APIs, check your API keys
```
3. Check logs with request ID:
```bash
# Find all log lines for a specific request
tail -f proxysql.log | grep "LLM \[a1b2c3d4"
```
4. Check error details:
- Review `error_code` for structured error type
- Review `error_details` for full context including query, provider, URL
- Review `http_status_code` for HTTP-level errors (429 = rate limit, 500+ = server error)
### Retry Behavior
LLM Bridge automatically retries on transient failures:
- **Rate limiting (HTTP 429)**: Retries with exponential backoff
- **Server errors (500-504)**: Retries with exponential backoff
- **Network errors**: Retries with exponential backoff
**Default retry behavior:**
- Maximum retries: 3
- Initial backoff: 1000ms
- Multiplier: 2.0x
- Maximum backoff: 30000ms
**Log output during retry:**
```
LLM [request-id]: ERROR phase=llm error=Empty response status=0
LLM [request-id]: Retryable error (status=0), retrying in 1000ms (attempt 1/4)
LLM [request-id]: Request succeeded after 1 retries
```
### Slow Responses
1. **Try a different model:**
```sql
SET genai-llm_provider_model='llama3.2'; -- Faster than GPT-4
LOAD GENAI VARIABLES TO RUNTIME;
```
2. **Use local Ollama for faster responses:**
```sql
SET genai-llm_provider_url='http://localhost:11434/v1/chat/completions';
LOAD GENAI VARIABLES TO RUNTIME;
```
3. **Increase timeout for complex prompts:**
```sql
SET genai-llm_timeout_ms=60000;
LOAD GENAI VARIABLES TO RUNTIME;
```
### Cache Issues
```sql
-- Check cache stats
SHOW STATUS LIKE 'llm_%';
-- Cache is automatically managed based on semantic similarity
-- Adjust similarity threshold if needed
SET genai-llm_cache_similarity_threshold=80; -- Lower = more matches
LOAD GENAI VARIABLES TO RUNTIME;
```
## Status Variables
Monitor LLM bridge usage:
```sql
SELECT * FROM stats_mysql_global WHERE variable_name LIKE 'llm_%';
```
Available status variables:
- `llm_total_requests` - Total number of LLM requests
- `llm_cache_hits` - Number of cache hits
- `llm_cache_misses` - Number of cache misses
- `llm_local_model_calls` - Calls to local models
- `llm_cloud_model_calls` - Calls to cloud APIs
- `llm_total_response_time_ms` - Total response time
- `llm_cache_total_lookup_time_ms` - Total cache lookup time
- `llm_cache_total_store_time_ms` - Total cache store time
## Performance
| Operation | Typical Latency |
|-----------|-----------------|
| Local Ollama | ~1-2 seconds |
| Cloud API | ~2-5 seconds |
| Cache hit | < 50ms |
**Tips for better performance:**
- Use local Ollama for faster responses
- Enable caching for repeated prompts
- Use `genai-llm_timeout_ms` to limit wait time
- Consider pre-warming cache with common prompts
## Migration from NL2SQL
If you were using the old `/* NL2SQL: */` prefix:
1. Update your queries from `/* NL2SQL: */` to `/* LLM: */`
2. Update configuration variables from `genai-nl2sql_*` to `genai-llm_*`
3. Note that the response format has changed:
- Removed: `sql_query`, `confidence` columns
- Added: `text_response`, `provider` columns
4. The `ai_nl2sql_convert` MCP tool is deprecated and will return an error
### Old NL2SQL Usage:
```sql
/* NL2SQL: */ Show top 10 customers by revenue
-- Returns: sql_query, confidence, explanation, cached
```
### New LLM Bridge Usage:
```sql
/* LLM: */ Show top 10 customers by revenue
-- Returns: text_response, explanation, cached, provider
```
For true NL2SQL functionality (schema-aware SQL generation with iteration), consider using external agents that can:
1. Analyze your database schema
2. Iterate on query refinement
3. Validate generated queries
4. Execute and review results
## Security
### Important Notes
- LLM responses are **NOT executed automatically**
- Text responses are returned for review
- Always validate generated code before execution
- Keep API keys secure (use environment variables)
### Best Practices
1. **Review generated code**: Always check output before running
2. **Use read-only accounts**: Test with limited permissions first
3. **Keep API keys secure**: Don't commit them to version control
4. **Use caching wisely**: Balance speed vs. data freshness
5. **Monitor usage**: Check status variables regularly
## API Reference
For complete API documentation, see [API.md](API.md).
## Architecture
For system architecture details, see [ARCHITECTURE.md](ARCHITECTURE.md).
## Testing
For testing information, see [TESTING.md](TESTING.md).
## Version History
- **1.0.0** (2025-01-17): Converted from NL2SQL to generic LLM Bridge
- Renamed from NL2SQL_Converter to LLM_Bridge
- Changed prefix from `/* NL2SQL: */` to `/* LLM: */`
- Removed SQL-specific fields (sql_query, confidence, tables_used)
- Added generic text_response field
- Updated all genai_nl2sql_* variables to genai_llm_*
- **0.2.0** (2025-01-16): NL2SQL with structured errors and retry logic
- **0.1.0** (2025-01-16): Initial NL2SQL release
## License
This feature is part of ProxySQL and follows the same license.

@ -1,4 +1,4 @@
# NL2SQL Testing Guide
# LLM Bridge Testing Guide
## Test Suite Overview
@ -355,7 +355,7 @@ gdb ./nl2sql_unit_base
diag("Generated SQL: %s", sql.c_str());
// Check MySQL errors
if (mysql_query(admin, query)) {
if (mytext_response(admin, query)) {
diag("MySQL error: %s", mysql_error(admin));
}
```

@ -1,370 +0,0 @@
# NL2SQL - Natural Language to SQL for ProxySQL
## Overview
NL2SQL (Natural Language to SQL) is a ProxySQL feature that converts natural language questions into SQL queries using Large Language Models (LLMs).
## Features
- **Generic Provider Support**: Works with any OpenAI-compatible or Anthropic-compatible endpoint
- **Semantic Caching**: Vector-based cache for similar queries using sqlite-vec
- **Schema Awareness**: Understands your database schema for better conversions
- **Multi-Provider**: Switch between LLM providers seamlessly
- **Security**: Generated SQL is returned for review before execution
**Supported Endpoints:**
- Ollama (via OpenAI-compatible `/v1/chat/completions` endpoint)
- OpenAI
- Anthropic
- vLLM
- LM Studio
- Z.ai
- Any other OpenAI-compatible or Anthropic-compatible endpoint
## Quick Start
### 1. Enable NL2SQL
```sql
-- Via admin interface
SET genai-nl2sql_enabled='true';
LOAD GENAI VARIABLES TO RUNTIME;
```
### 2. Configure LLM Provider
ProxySQL uses a **generic provider configuration** that supports any OpenAI-compatible or Anthropic-compatible endpoint.
**Using Ollama (default):**
Ollama is used via its OpenAI-compatible endpoint:
```sql
SET genai-nl2sql_provider='openai';
SET genai-nl2sql_provider_url='http://localhost:11434/v1/chat/completions';
SET genai-nl2sql_provider_model='llama3.2';
SET genai-nl2sql_provider_key=''; -- Empty for local Ollama
LOAD GENAI VARIABLES TO RUNTIME;
```
**Using OpenAI:**
```sql
SET genai-nl2sql_provider='openai';
SET genai-nl2sql_provider_url='https://api.openai.com/v1/chat/completions';
SET genai-nl2sql_provider_model='gpt-4o-mini';
SET genai-nl2sql_provider_key='sk-...';
LOAD GENAI VARIABLES TO RUNTIME;
```
**Using Anthropic:**
```sql
SET genai-nl2sql_provider='anthropic';
SET genai-nl2sql_provider_url='https://api.anthropic.com/v1/messages';
SET genai-nl2sql_provider_model='claude-3-haiku';
SET genai-nl2sql_provider_key='sk-ant-...';
LOAD GENAI VARIABLES TO RUNTIME;
```
**Using any OpenAI-compatible endpoint:**
This works with **any** OpenAI-compatible API (vLLM, LM Studio, Z.ai, etc.):
```sql
SET genai-nl2sql_provider='openai';
SET genai-nl2sql_provider_url='https://your-endpoint.com/v1/chat/completions';
SET genai-nl2sql_provider_model='your-model-name';
SET genai-nl2sql_provider_key='your-api-key'; -- Empty for local endpoints
LOAD GENAI VARIABLES TO RUNTIME;
```
### 3. Use NL2SQL
```sql
-- Verify NL2SQL is enabled (run this in the Admin interface)
SHOW VARIABLES LIKE 'genai-nl2sql%';
-- Use NL2SQL in your MySQL client (MySQL module, not Admin)
mysql> NL2SQL: Show top 10 customers by revenue;
```
**Important**: NL2SQL queries are executed in the **MySQL module** (your regular SQL client), not in the ProxySQL Admin interface. The Admin interface is only for configuration.
## Configuration
### Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `genai-nl2sql_enabled` | false | Enable/disable NL2SQL |
| `genai-nl2sql_query_prefix` | NL2SQL: | Prefix for NL2SQL queries |
| `genai-nl2sql_provider` | openai | Provider format: `openai` or `anthropic` |
| `genai-nl2sql_provider_url` | http://localhost:11434/v1/chat/completions | Endpoint URL |
| `genai-nl2sql_provider_model` | llama3.2 | Model name |
| `genai-nl2sql_provider_key` | (none) | API key (optional for local endpoints) |
| `genai-nl2sql_cache_similarity_threshold` | 85 | Semantic similarity threshold (0-100) |
| `genai-nl2sql_timeout_ms` | 30000 | LLM request timeout in milliseconds |
### Request Configuration (Advanced)
When using NL2SQL programmatically, you can configure retry behavior:
| Parameter | Default | Description |
|-----------|---------|-------------|
| `max_retries` | 3 | Maximum retry attempts for transient failures |
| `retry_backoff_ms` | 1000 | Initial backoff in milliseconds |
| `retry_multiplier` | 2.0 | Backoff multiplier for exponential backoff |
| `retry_max_backoff_ms` | 30000 | Maximum backoff in milliseconds |
| `allow_cache` | true | Enable semantic cache lookup |
### Error Handling
NL2SQL provides structured error information to help diagnose issues:
| Error Code | Description | HTTP Status |
|-----------|-------------|-------------|
| `ERR_API_KEY_MISSING` | API key not configured | N/A |
| `ERR_API_KEY_INVALID` | API key format is invalid | N/A |
| `ERR_TIMEOUT` | Request timed out | N/A |
| `ERR_CONNECTION_FAILED` | Network connection failed | 0 |
| `ERR_RATE_LIMITED` | Rate limited by provider | 429 |
| `ERR_SERVER_ERROR` | Server error | 500-599 |
| `ERR_EMPTY_RESPONSE` | Empty response from LLM | N/A |
| `ERR_INVALID_RESPONSE` | Malformed response from LLM | N/A |
| `ERR_SQL_INJECTION_DETECTED` | SQL injection pattern detected | N/A |
| `ERR_VALIDATION_FAILED` | Input validation failed | N/A |
| `ERR_UNKNOWN_PROVIDER` | Invalid provider name | N/A |
| `ERR_REQUEST_TOO_LARGE` | Request exceeds size limit | 413 |
**Result Fields:**
- `error_code`: Structured error code (e.g., "ERR_API_KEY_MISSING")
- `error_details`: Detailed error context with query, schema, provider, URL
- `http_status_code`: HTTP status code if applicable
- `provider_used`: Which provider was attempted
### Request Correlation
Each NL2SQL request generates a unique request ID for log correlation:
```
NL2SQL [a1b2c3d4-e5f6-7890-abcd-ef1234567890]: REQUEST url=http://... model=llama3.2
NL2SQL [a1b2c3d4-e5f6-7890-abcd-ef1234567890]: RESPONSE status=200 duration_ms=1234
```
This allows tracing a single request through all log lines for debugging.
### Model Selection
The system automatically selects the best model based on:
1. **Provider format**: Uses `genai-nl2sql_provider` setting (openai or anthropic)
2. **API key availability**: For cloud endpoints, API key is required
3. **Local endpoints**: API key is optional for local endpoints (localhost, 127.0.0.1)
## Examples
### Basic Queries
```
NL2SQL: Show all users
NL2SQL: Find orders with amount > 100
NL2SQL: Count customers by country
```
### Complex Queries
```
NL2SQL: Show top 5 customers by total order amount
NL2SQL: Find customers who placed orders in the last 30 days
NL2SQL: What is the average order value per month?
```
### Schema-Aware Queries
```
-- Switch to your schema first
USE my_database;
NL2SQL: List all products in the Electronics category
NL2SQL: Find orders that contain specific products
```
### Results
NL2SQL returns a resultset with:
| Column | Type | Description |
|--------|------|-------------|
| `sql_query` | TEXT | Generated SQL query |
| `confidence` | FLOAT | Confidence score (0.0-1.0) |
| `explanation` | TEXT | Which model was used |
| `cached` | BOOLEAN | Whether from semantic cache |
| `cache_id` | BIGINT | Cache entry ID |
| `error_code` | TEXT | Structured error code (if error) |
| `error_details` | TEXT | Detailed error context (if error) |
| `http_status_code` | INT | HTTP status code (if applicable) |
| `provider_used` | TEXT | Which provider was attempted (if error) |
**Example successful response:**
```
+----------------------------------+------------+----------------------+------+----------+
| sql_query | confidence | explanation | cached | cache_id |
+----------------------------------+------------+----------------------+------+----------+
| SELECT * FROM customers ORDER BY | 0.850 | Generated by llama3.2 | 0 | 0 |
| revenue DESC LIMIT 10 | | | | |
+----------------------------------+------------+----------------------+------+----------+
```
**Example error response:**
```
+-----------------------------------------------------------------------+
| sql_query |
+-----------------------------------------------------------------------+
| -- NL2SQL conversion failed: API key not configured for provider |
| |
| error_code: ERR_API_KEY_MISSING |
| error_details: NL2SQL conversion failed: |
| Query: Show top 10 customers |
| Schema: (none) |
| Provider: openai |
| URL: https://api.openai.com/v1/chat/completions |
| Error: API key not configured |
| |
| http_status_code: 0 |
| provider_used: openai |
+-----------------------------------------------------------------------+
```
## Troubleshooting
### NL2SQL returns empty result
1. Check AI module is initialized:
```sql
SELECT * FROM runtime_mysql_servers WHERE variable_name LIKE 'ai_%';
```
2. Verify LLM is accessible:
```bash
# For Ollama
curl http://localhost:11434/api/tags
# For cloud APIs, check your API keys
```
3. Check logs with request ID:
```bash
# Find all log lines for a specific request
tail -f proxysql.log | grep "NL2SQL \[a1b2c3d4"
```
4. Check error details:
- Review `error_code` for structured error type
- Review `error_details` for full context including query, schema, provider, URL
- Review `http_status_code` for HTTP-level errors (429 = rate limit, 500+ = server error)
### Retry Behavior
NL2SQL automatically retries on transient failures:
- **Rate limiting (HTTP 429)**: Retries with exponential backoff
- **Server errors (500-504)**: Retries with exponential backoff
- **Network errors**: Retries with exponential backoff
**Default retry behavior:**
- Maximum retries: 3
- Initial backoff: 1000ms
- Multiplier: 2.0x
- Maximum backoff: 30000ms
**Log output during retry:**
```
NL2SQL [request-id]: ERROR phase=llm error=Empty response status=0
NL2SQL [request-id]: Retryable error (status=0), retrying in 1000ms (attempt 1/4)
NL2SQL [request-id]: Request succeeded after 1 retries
```
### Poor quality SQL
1. **Try a different model:**
```sql
SET genai-nl2sql_provider_model='gpt-4o';
LOAD GENAI VARIABLES TO RUNTIME;
```
2. **Increase timeout for complex queries:**
```sql
SET genai-nl2sql_timeout_ms=60000;
LOAD GENAI VARIABLES TO RUNTIME;
```
3. **Check confidence score:**
- High confidence (> 0.7): Generally reliable
- Medium confidence (0.4-0.7): Review before using
- Low confidence (< 0.4): May need manual correction
### Cache Issues
```sql
-- Clear cache (Phase 3 feature)
-- TODO: Add cache clearing command
-- Check cache stats
SHOW STATUS LIKE 'genai-nl2sql%';
```
## Performance
| Operation | Typical Latency |
|-----------|-----------------|
| Local Ollama | ~1-2 seconds |
| Cloud API | ~2-5 seconds |
| Cache hit | < 50ms |
**Tips for better performance:**
- Use local Ollama for faster responses
- Enable caching for repeated queries
- Use `genai-nl2sql_timeout_ms` to limit wait time
- Consider pre-warming cache with common queries
## Security
### Important Notes
- NL2SQL queries are **NOT executed automatically**
- Generated SQL is returned for **review first**
- Always validate generated SQL before execution
- Keep API keys secure (use environment variables)
### Best Practices
1. **Review generated SQL**: Always check the output before running
2. **Use read-only accounts**: Test with limited permissions first
3. **Monitor confidence scores**: Low confidence may indicate errors
4. **Keep API keys secure**: Don't commit them to version control
5. **Use caching wisely**: Balance speed vs. data freshness
## API Reference
For complete API documentation, see [API.md](API.md).
## Architecture
For system architecture details, see [ARCHITECTURE.md](ARCHITECTURE.md).
## Testing
For testing information, see [TESTING.md](TESTING.md).
## Version History
- **0.2.0** (2025-01-16):
- Added structured error messages with error codes
- Added request ID correlation for debugging
- Added exponential backoff retry for transient failures
- Added configurable retry parameters
- Added unit tests for validation functions
- **0.1.0** (2025-01-16): Initial release with Ollama, OpenAI, Anthropic support
## License
This feature is part of ProxySQL and follows the same license.
Loading…
Cancel
Save