AnswerKit ⚡
A lightweight, standalone Python AI SDK for building Q&A applications with Groq, async streaming, model fallback, conversation context, optional Google Serper web search, and prompt enhancement.
🌟 Overview
AnswerKit is an open-source, framework-independent Python SDK designed to make adding state-of-the-art AI-powered Q&A capabilities to your applications effortless.
Whether you are building a FastAPI backend, a Flask app, a CLI utility, a Discord bot, or a full AI SaaS platform, AnswerKit gives you a clean, async-first API that handles:
- Ultra-fast LLM generation powered by Groq
- Token streaming via native Python async generators
- Automatic model fallback cascades for rock-solid uptime and zero-downtime rate-limit resilience
- Multi-turn conversation context without forcing any database dependencies
- Live web search integration via Google Serper for fresh, up-to-date facts
- Prompt engineering & polishing to transform vague user inputs into optimal LLM prompts
- Safe, zero-leak credential configuration and developer-friendly error handling
🚀 Why AnswerKit?
| Challenge | Without AnswerKit | With AnswerKit |
|---|---|---|
| Model Availability | Single model failure crashes user requests | Automatic fallback cascade across models |
| Streaming | Tied to web frameworks like FastAPI StreamingResponse |
Native async generator usable anywhere (FastAPI, CLI, WebSockets, Bot) |
| Fresh Information | Manual search scraping, parsing, prompt formatting | Built-in smart keyword detection and Serper context injection |
| Database Ties | Heavy ORMs and tables required just to talk to LLMs | Pure in-memory context lists; use any database you want |
| Speed | Slow inference bottlenecks | Ultra-fast Groq LPU inference |
📦 Installation
pip install answerkit
For local development and running tests:
git clone https://github.com/Mahadev1729/QnAChatBot.git
cd QnAChatBot/answerkit
pip install -e ".[dev]"
🔑 API Keys & Configuration
| Service | Environment Variable | Status | Purpose |
|---|---|---|---|
| Groq | GROQ_API_KEY |
Required | LLM inference, streaming, and prompt polishing |
| Google Serper | SERPER_API_KEY |
Optional | Live Google search (Required only when enable_web_search=True) |
Configuration Precedence:
- Explicit constructor argument (
AnswerKit(groq_api_key="...", ...)) - Environment variable (
GROQ_API_KEY,SERPER_API_KEY,ANSWERKIT_MODEL,ANSWERKIT_ENABLE_WEB_SEARCH) - Default SDK fallback
Environment File (.env):
GROQ_API_KEY=gsk_your_groq_api_key_here
SERPER_API_KEY=your_serper_api_key_here
ANSWERKIT_MODEL=openai/gpt-oss-20b
ANSWERKIT_ENABLE_WEB_SEARCH=false
⚡ Quick Start
1. Basic Q&A
import asyncio
from answerkit import AnswerKit
async def main():
ai = AnswerKit(groq_api_key="YOUR_GROQ_API_KEY")
answer = await ai.ask("Explain Retrieval Augmented Generation in 2 sentences.")
print(answer)
if __name__ == "__main__":
asyncio.run(main())
2. Async Token Streaming
Stream tokens in real-time as they are generated by the model:
import asyncio
from answerkit import AnswerKit
async def main():
ai = AnswerKit(groq_api_key="YOUR_GROQ_API_KEY")
async for chunk in ai.stream("Explain how JWT authentication works"):
print(chunk, end="", flush=True)
if __name__ == "__main__":
asyncio.run(main())
3. Multi-Turn Conversation Context
Pass previous conversation history without needing a database:
import asyncio
from answerkit import AnswerKit
async def main():
ai = AnswerKit(groq_api_key="YOUR_GROQ_API_KEY")
history = [
{"role": "user", "content": "What is Python?"},
{"role": "assistant", "content": "Python is a high-level programming language."}
]
answer = await ai.ask("What are its primary design philosophies?", conversation_history=history)
print(answer)
if __name__ == "__main__":
asyncio.run(main())
4. Web-Augmented Answers (Google Serper)
Enable live web search to answer queries regarding current news, latest releases, and real-time events:
import asyncio
from answerkit import AnswerKit
async def main():
ai = AnswerKit(
groq_api_key="YOUR_GROQ_API_KEY",
serper_api_key="YOUR_SERPER_API_KEY",
enable_web_search=True
)
# Simple string answer with web search context
answer = await ai.ask("What are the latest developments in quantum computing today?")
print(answer)
# Or get structured metadata including source citations
result = await ai.ask_with_metadata("What is the current stock price of Apple?")
print("Content:", result.content)
print("Search Used:", result.used_search)
print("Sources:", [s.link for s in result.sources])
if __name__ == "__main__":
asyncio.run(main())
5. Automatic Model Fallback
AnswerKit automatically falls back through configured models if the primary model encounters rate limits (429), decommission errors (404), or temporary outages:
ai = AnswerKit(
groq_api_key="YOUR_GROQ_API_KEY",
model="openai/gpt-oss-120b",
fallback_models=[
"openai/gpt-oss-20b",
"llama-3.3-70b-versatile",
"llama-3.1-8b-instant"
]
)
6. Prompt Polishing
Enhance draft or vague user prompts using ultra-fast LLMs:
improved_prompt = await ai.polish_prompt("build me a chatbot")
print(improved_prompt)
# Output: "Design an end-to-end architecture for an intelligent conversational chatbot, specifying the backend framework, state management, LLM orchestration, and API integrations."
🌐 Framework Integrations
FastAPI Integration
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from answerkit import AnswerKit
app = FastAPI(title="AI API powered by AnswerKit")
ai = AnswerKit()
@app.post("/api/ask")
async def ask_endpoint(question: str):
answer = await ai.ask(question)
return {"answer": answer}
@app.get("/api/stream")
async def stream_endpoint(question: str):
async def event_publisher():
async for chunk in ai.stream(question):
yield f"data: {chunk}\n\n"
return StreamingResponse(event_publisher(), media_type="text/event-stream")
Flask Integration
import asyncio
from flask import Flask, request, jsonify
from answerkit import AnswerKit
app = Flask(__name__)
ai = AnswerKit()
@app.route("/ask", methods=["POST"])
def ask():
question = request.json.get("question", "")
answer = asyncio.run(ai.ask(question))
return jsonify({"answer": answer})
CLI Application
import asyncio
from answerkit import AnswerKit
async def cli():
ai = AnswerKit()
print("🤖 AnswerKit CLI (Type 'exit' to quit)\n")
while True:
prompt = input("You > ")
if prompt.lower() in ("exit", "quit"):
break
print("AI > ", end="", flush=True)
async for token in ai.stream(prompt):
print(token, end="", flush=True)
print("\n")
if __name__ == "__main__":
asyncio.run(cli())
🛡️ Error Handling
AnswerKit provides a clean hierarchy of custom exceptions:
from answerkit import (
AnswerKit,
AnswerKitError,
ConfigurationError,
ModelError,
WebSearchError,
)
try:
ai = AnswerKit()
answer = await ai.ask("Hello world")
except ConfigurationError as e:
print(f"Configuration issue: {e}")
except ModelError as e:
print(f"Model generation failure across all fallbacks: {e}")
except WebSearchError as e:
print(f"Web search error: {e}")
except AnswerKitError as e:
print(f"General SDK error: {e}")
🧪 Testing
AnswerKit includes an extensive test suite with 100% mocked external calls (zero live API tokens required):
# Run tests with pytest
pytest -v
🔨 Building & Packaging
To create wheel and source distributions:
python -m build
This generates distribution archives in dist/:
dist/answerkit-0.1.0-py3-none-any.whldist/answerkit-0.1.0.tar.gz
To install the locally built wheel:
pip install dist/answerkit-0.1.0-py3-none-any.whl
🚀 Manual PyPI Publishing
When ready to publish to PyPI:
- Build distributions:
python -m build
- Upload to TestPyPI (optional):
twine upload --repository testpypi dist/*
- Upload to official PyPI:
twine upload dist/*
(AnswerKit package name availability on PyPI verified for initial release).
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
Metadata
Release files for answerkit 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| answerkit-0.1.0.tar.gz | 23.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| answerkit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.9 kB
Release files / answerkit-0.1.0.tar.gz
| Download URL | answerkit-0.1.0.tar.gz |
|---|---|
| Size | 23.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b6a77b49b160f01c6e93277365a3b479614a565c801f6a80ee067b184ad2d2f3
|
|
BLAKE2b-256 checksum How to use checksums |
8725a34b10eb724e098c7fed7dae0a6c337307e42cc1c4927583f89d79795837
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.7
|
Release files / answerkit-0.1.0-py3-none-any.whl
| Download URL | answerkit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 17.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
670aba967bb9b2c26e9394e2f7280982aec5159d6fedd8cf9466161682069b72
|
|
BLAKE2b-256 checksum How to use checksums |
1cddc72ab97248535b2dd19a9c5e0ad36253c18248059228616b6c5ba41c1210
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.7
|