Skip to main content

A comprehensive toolkit for LLM context management with intelligent metadata selection and contextual question resolution

Project description

llm-context-toolkit

Version: 0.1.0
Author: sreeyenan
License: MIT
Python: 3.10+

A comprehensive toolkit for LLM context management with intelligent metadata selection and contextual question resolution.

PyPI version Python 3.10+ License: MIT


๐ŸŽฏ What This Library Does

llm-context-toolkit solves two critical problems when building LLM-powered AI systems:

  1. Context Resolution - Converts short, contextual messages into complete standalone instructions
  2. Metadata Selection - Intelligently selects only relevant metadata from large catalogs

The Problem

When building Text-to-SQL, RAG systems, or dashboard AI assistants, you face these challenges:

  • Contextual questions are hard to understand: "make it monthly", "what else?", "same for payments"
  • Full metadata catalogs are too large: Sending 50+ tables with 500+ columns to an LLM wastes tokens, increases cost, and reduces accuracy
  • Chat history grows unbounded: Passing full conversation history is expensive and often unnecessary

The Solution

from llm_context_toolkit import resolve_and_select

# One line to resolve context + select metadata
resolution, selection = resolve_and_select(
    current_question="make it monthly",
    metadata_catalog=tenant_catalog,
    context_cards=[previous_turn_card],
    database="client_db"
)

# Result: 
# - Resolved question: "Show monthly revenue by region for last 6 months"
# - Selected metadata: 1 table, 3 columns (from 42 tables, 890 columns)
# - Token reduction: 95.5% (47000 โ†’ 2100 tokens)

๐Ÿš€ Key Features

Context Resolution

  • โœ… Converts contextual messages into standalone questions
  • โœ… Detects follow-ups, modifications, fresh questions, and suggestion requests
  • โœ… Maintains state using compact TurnContextCard objects
  • โœ… No full chat history needed (90%+ memory reduction)
  • โœ… Rule-based resolution (no API calls required)
  • โœ… Optional LLM fallback for ambiguous cases

Metadata Selection

  • โœ… Selects only relevant tables and columns from large catalogs
  • โœ… 90-98% token reduction for LLM prompts
  • โœ… Multiple strategies: lexical, TF-IDF, embeddings, hybrid
  • โœ… No API key required for core functionality
  • โœ… Supports business metadata (synonyms, descriptions, roles)
  • โœ… Works with any database schema (SQL, NoSQL, graph, etc.)

Framework-Agnostic

  • โœ… Works with any LLM (OpenAI, Anthropic, Gemini, Groq, local models)
  • โœ… Works with any SQL engine (PostgreSQL, MySQL, ClickHouse, etc.)
  • โœ… Works with any framework (FastAPI, Flask, Django, etc.)
  • โœ… Works with any vector database for RAG
  • โœ… Pure Python with zero required dependencies

๐Ÿ“ฆ Installation

Minimal Installation (Pure Python)

pip install llm-context-toolkit

With Optional Enhanced Features

# TF-IDF strategy for better lexical matching
pip install llm-context-toolkit[tfidf]

# Local embedding support for semantic matching
pip install llm-context-toolkit[embeddings]

# Everything
pip install llm-context-toolkit[all]

๐ŸŽ“ Quick Start

1. Basic Context Resolution

from llm_context_toolkit import ContextResolver, TurnContextCard

# Previous conversation turn
previous_card = TurnContextCard(
    turn_id=1,
    user_question="Show total revenue by region",
    resolved_question="Show total revenue by region",
    query_state={
        "active_tables": ["sales_orders"],
        "metrics": ["revenue"],
        "group_by": ["region"],
    }
)

# Resolve a contextual follow-up
resolver = ContextResolver()
resolution = resolver.resolve(
    current_question="make it monthly",
    context_cards=[previous_card]
)

print(resolution.resolved_question)
# "Show monthly revenue by region"

print(resolution.metadata_search_query)
# "monthly revenue region order_date sales_orders"

2. Basic Metadata Selection

from llm_context_toolkit import MetadataSelector

catalog = {
    "database": "client_db",
    "tables": [
        {
            "table_name": "sales_orders",
            "columns": [
                {"name": "revenue", "role": "metric", "synonyms": ["sales", "income"]},
                {"name": "region", "role": "dimension", "synonyms": ["zone", "area"]},
                {"name": "order_date", "role": "date"},
            ]
        }
    ]
}

selector = MetadataSelector()
result = selector.select(
    question="Show total sales by region for last 6 months",
    catalog=catalog
)

print(result.selected_metadata)
# Only relevant table and columns selected
print(result.metrics.summary())
# "tables 42 โ†’ 1 (97.6% cut), columns 890 โ†’ 3 (99.7% cut), tokens ~47000 โ†’ ~500 (98.9% cut)"

3. Combined Workflow (Recommended)

from llm_context_toolkit import resolve_and_select, TurnContextCard

# One call to handle both resolution and selection
resolution, selection = resolve_and_select(
    current_question="consider monthly?",
    metadata_catalog=tenant_catalog,
    context_cards=[previous_card],
    database="client_abc_db"
)

# Handle clarification requests
if resolution.route == "clarify":
    return {"message": resolution.clarification_question}

# Now pass to your LLM
prompt = f"""
Question: {resolution.resolved_question}

Available Schema:
{selection.selected_metadata}

Generate SQL for this question.
"""

# Send to OpenAI, Anthropic, Gemini, etc.
sql = your_llm.generate(prompt)

๐Ÿ”„ Typical Pipeline

User Message: "make it monthly"
        โ†“
ContextResolver
        โ†“
Resolved: "Show monthly revenue by region for last 6 months"
Search Query: "monthly revenue region order_date"
        โ†“
MetadataSelector
        โ†“
Selected: 1 table (sales_orders), 3 columns (revenue, region, order_date)
Token Reduction: 47000 โ†’ 2100 tokens (95.5% reduction)
        โ†“
LLM Prompt
        โ†“
SQL/Config/Answer Generation
        โ†“
Save new TurnContextCard

๐Ÿ“– Use Cases

Text-to-SQL

# User: "Show revenue by region"
# โ†’ SQL: SELECT region, sum(revenue) FROM sales_orders GROUP BY region

# User: "make it monthly"
# โ†’ SQL: SELECT toStartOfMonth(order_date) AS month, region, sum(revenue) 
#        FROM sales_orders GROUP BY month, region

Text-to-Query-Config

# User: "Show revenue by region as a bar chart"
# โ†’ Config: {"type": "bar", "x": "region", "y": "sum(revenue)"}

RAG / Document Q&A

# Previous: "What are the compliance requirements?"
# User: "what about privacy only?"
# โ†’ Resolved: "What are the privacy-specific compliance requirements?"

Dashboard AI Assistant

# User: "what else can we analyze?"
# โ†’ Suggestions: ["Revenue by product category", "Monthly trend analysis", "Top 10 regions"]

๐Ÿ—๏ธ Architecture

Context Resolution Flow

User Message
    โ†“
Detect explicit references (turn #3, chart 2, etc.)
    โ†“
Rank recent context cards by relevance
    โ†“
Classify: fresh | follow-up | modify | suggest | clarify
    โ†“
Extract intent delta (granularity, filters, etc.)
    โ†“
Compose resolved question + metadata search query
    โ†“
Output: ContextResolution

Metadata Selection Flow

Question + Full Catalog (42 tables, 890 columns)
    โ†“
Parse intent (metrics, dates, grouping, trends)
    โ†“
Score tables (lexical + TF-IDF + embeddings)
    โ†“
Select top K tables (default: 3)
    โ†“
Score columns within selected tables
    โ†“
Select top N columns per table (default: 25)
    โ†“
Include relationships between selected tables
    โ†“
Output: Selected metadata (1-3 tables, 5-30 columns)

๐ŸŽฏ Core Concepts

TurnContextCard

Compact memory object storing structured context from a previous AI turn.

TurnContextCard(
    turn_id=1,
    user_question="Show revenue by region",
    resolved_question="Show total revenue by region for last 6 months",
    task_type="text_to_sql",
    artifact_type="sql",
    topic_keywords=["revenue", "region", "sales"],
    entities=["sales_orders", "revenue", "region"],
    query_state={
        "active_tables": ["sales_orders"],
        "metrics": ["revenue"],
        "dimensions": ["region"],
        "filters": [{"column": "order_date", "operation": "last_6_months"}],
    },
    sql="SELECT region, sum(revenue) FROM sales_orders WHERE order_date >= ...",
)

Why not store full chat history?

  • Full history: 1000+ tokens per turn ร— 10 turns = 10,000+ tokens
  • Context cards: ~200 tokens per turn ร— 10 turns = 2,000 tokens
  • 80% reduction before metadata selection even starts

ContextType

Classification of how the current question relates to previous context:

  • fresh_question - New independent question
  • follow_up_latest - Continues from latest result
  • follow_up_specific_turn - References a specific older turn
  • modify_previous_query - Modifies a previous result
  • suggestion_request - Asks for related suggestions
  • clarification_needed - Too ambiguous to resolve

Selection Strategies

  • lexical - Pure Python keyword matching (no dependencies)
  • tfidf - TF-IDF scoring (requires scikit-learn)
  • embedding - Semantic similarity (requires sentence-transformers)
  • hybrid - Combines all available strategies (recommended)

๐Ÿ”ง Configuration

Resolver Configuration

from llm_context_toolkit import ResolverConfig, ContextResolver

config = ResolverConfig(
    max_recent_cards=10,              # How many recent cards to consider
    min_confidence_threshold=0.75,    # Minimum confidence to resolve
    allow_llm_fallback=False,         # Use LLM for ambiguous cases
    enable_debug=True,                # Include debug information
)

resolver = ContextResolver(config=config)

Selector Configuration

from llm_context_toolkit import SelectorConfig, MetadataSelector

config = SelectorConfig(
    strategy="hybrid",                # lexical | tfidf | embedding | hybrid
    top_k_tables=3,                   # Max tables to select
    max_columns_per_table=25,         # Max columns per table
    max_output_chars=10000,           # Budget limit for output
    use_embeddings_if_available=True, # Use embeddings if installed
    embedding_model_name_or_path="./models/all-MiniLM-L6-v2",  # Local model
    include_debug=True,               # Include scoring details
)

selector = MetadataSelector(config=config)

๐Ÿ“Š Real-World Results

Token Reduction Examples

Scenario Input Tokens Output Tokens Reduction
Small catalog (5 tables, 50 cols) ~3,000 ~400 86.7%
Medium catalog (20 tables, 200 cols) ~12,000 ~800 93.3%
Large catalog (50 tables, 500 cols) ~30,000 ~1,200 96.0%
Very large (100 tables, 1000 cols) ~60,000 ~1,500 97.5%

Cost Impact

Assuming GPT-4 pricing ($10/1M input tokens):

  • Large catalog: 30,000 tokens โ†’ 1,200 tokens = $0.30 โ†’ $0.012 per query (96% cost reduction)
  • 10,000 queries/month: $3,000 โ†’ $120/month savings = $34,560/year

๐Ÿ”ฌ Advanced Usage

Custom LLM Fallback for Ambiguous Cases

from llm_context_toolkit import ContextResolver

def my_llm_fallback(question, card_summaries, preliminary):
    # Call your LLM to resolve ambiguous cases
    prompt = f"Question: {question}\nContext: {card_summaries}\nResolve this."
    response = your_llm_client.generate(prompt)
    return {"resolved_question": response["question"], ...}

resolver = ContextResolver(llm_fallback=my_llm_fallback)

Multi-Tenant Isolation

# Always pass database override from your tenant resolver
client_id = request.headers["X-Client-ID"]
database = tenant_resolver.get_database(client_id)

resolution, selection = resolve_and_select(
    current_question=user_question,
    metadata_catalog=tenant_catalogs[client_id],
    database=database,  # Ensures LLM only sees this tenant's data
)

State Extraction for Next Turn

# After generating SQL/config, extract state for next turn
from llm_context_toolkit import TurnContextCard

next_card = TurnContextCard(
    turn_id=current_turn_id + 1,
    user_question=resolution.current_question,
    resolved_question=resolution.resolved_question,
    query_state={
        "active_tables": [t["table_name"] for t in selection.selected_metadata["tables"]],
        "metrics": extract_metrics_from_sql(generated_sql),
        "dimensions": extract_dimensions_from_sql(generated_sql),
        # ... extract other state
    },
    sql=generated_sql,
)

# Store for next turn
context_store.save(session_id, next_card)

๐Ÿงช Testing

# Run tests
pytest

# Run with coverage
pytest --cov=llm_context_toolkit

# Run specific test
pytest tests/test_context_resolver.py::test_fresh_question

๐Ÿ“š Documentation


๐Ÿค Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


๐Ÿ™ Acknowledgments

This library was built to solve real-world problems in multi-tenant analytics systems with Text-to-SQL, dashboard AI assistants, and natural language query interfaces.


๐Ÿ“ง Support


Made with โค๏ธ by sreeyenan

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

llm_context_toolkit-0.1.1.tar.gz (52.8 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

llm_context_toolkit-0.1.1-cp311-cp311-win_amd64.whl (920.3 kB view details)

Uploaded CPython 3.11Windows x86-64

llm_context_toolkit-0.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (3.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

llm_context_toolkit-0.1.1-cp311-cp311-macosx_11_0_arm64.whl (968.1 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

llm_context_toolkit-0.1.1-cp311-cp311-macosx_10_9_x86_64.whl (1.0 MB view details)

Uploaded CPython 3.11macOS 10.9+ x86-64

File details

Details for the file llm_context_toolkit-0.1.1.tar.gz.

File metadata

  • Download URL: llm_context_toolkit-0.1.1.tar.gz
  • Upload date:
  • Size: 52.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for llm_context_toolkit-0.1.1.tar.gz
Algorithm Hash digest
SHA256 4fec4df75b5e41d7367cb50cc5609de7ecd37a571e066b5d237b5bb1dee63c1b
MD5 babf00b897aedb8c83eb0292e8f2582a
BLAKE2b-256 01b6632dec360ed6ac097a93b023f41bf3744e49d05dd80e408dae405831c523

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_context_toolkit-0.1.1.tar.gz:

Publisher: publish.yml on sreeyenan/llm_context_toolkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llm_context_toolkit-0.1.1-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for llm_context_toolkit-0.1.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 51182cf79b938cdcc513ebc758065b5b9ba871a51ec5b72575ba67585f3c534a
MD5 0ab3216e04696b434b53ec12abd0e39a
BLAKE2b-256 72a98648761c0a76ddcc081b03f7502f0fe57d16e8a8cfa5243343144d2fb3c7

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_context_toolkit-0.1.1-cp311-cp311-win_amd64.whl:

Publisher: publish.yml on sreeyenan/llm_context_toolkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llm_context_toolkit-0.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for llm_context_toolkit-0.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 243927dd5d4a64eb0668ba6472aa979394f209ab419cf47f869393bd1e991f53
MD5 d4b72d5721b1661dd9ddda50eb720e37
BLAKE2b-256 b06aefcb548f22e3c1539acb0fb8a7616b26e985e8bfc04a398633e56b4eb7a5

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_context_toolkit-0.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl:

Publisher: publish.yml on sreeyenan/llm_context_toolkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llm_context_toolkit-0.1.1-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for llm_context_toolkit-0.1.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 53de022d852b54202b522895cb52f42f054f7b43bf12c74a76fb07e92bdf465f
MD5 1fbde05538c594b376e69d13b4812cd6
BLAKE2b-256 24ac6193795f1205db794d6eb7ceea93bab934b3265a85e25eaece457f0e4e5a

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_context_toolkit-0.1.1-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: publish.yml on sreeyenan/llm_context_toolkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llm_context_toolkit-0.1.1-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for llm_context_toolkit-0.1.1-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 cc558550f0e3eea09d33b11944b9dc2615592c234b82742588f8777b1210df08
MD5 228d98c9e24d9238c6e657b6f5e28eee
BLAKE2b-256 95de0f672ef48a4bc6d7be70f09e4d7e65ac2d97d1df0252092c4f0489ca9be0

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_context_toolkit-0.1.1-cp311-cp311-macosx_10_9_x86_64.whl:

Publisher: publish.yml on sreeyenan/llm_context_toolkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page