Skip to content

AIForge SDK — Architecture & Technology Reference

High-Level Architecture

graph TB
    subgraph Entry["Entry Points"]
        SDK["Python SDK<br/><i>from aiforge import ...</i>"]
        CLI["CLI<br/><i>Typer + Rich</i>"]
        API["REST API<br/><i>FastAPI + Uvicorn</i>"]
        PG["Playground<br/><i>Streamlit</i>"]
    end

    subgraph Middleware["Server Middleware"]
        AUTH["Auth Middleware<br/><i>Bearer Token</i>"]
        CORS["CORS Middleware"]
        RLOG["Request Logging<br/><i>X-Request-Id</i>"]
    end

    subgraph Core["Core Layer"]
        REG["Module Registry"]
        subgraph Modules["10 AI Modules"]
            SUM["Summarizer"]
            DQA["DocQA<br/><i>RAG + LangGraph</i>"]
            EXT["Extractor"]
            CLS["Classifier<br/>+ Sentiment"]
            SEM["SemanticSearch"]
            GEN["Generator<br/>+ Rewrite"]
            CHA["ChatAgent<br/><i>LangGraph</i>"]
            MOD["Moderator"]
            TRN["Translator"]
            VIS["Vision"]
        end
        PIPE["Pipeline Engine<br/><i>Sequential + Router</i>"]
        GUARD["Guardrails<br/><i>Input / output checks, PII</i>"]
        EVAL["Evals<br/><i>Datasets, scorers, reports</i>"]
        RET["Retrieval<br/><i>BM25 + vector, RRF, rerank</i>"]
    end

    subgraph Infra["Infrastructure"]
        CFG["Config<br/><i>Pydantic Settings v2</i>"]
        RL["Rate Limiter<br/><i>RPM / TPM</i>"]
        CACHE["Request Cache<br/><i>Memory LRU / Redis</i>"]
        COST["Cost Tracker<br/><i>Per-call pricing</i>"]
        RETRY["Retry Logic<br/><i>Tenacity</i>"]
        LOG["Logging<br/><i>structlog JSON</i>"]
        TRACE["Tracing<br/><i>LangSmith / OTEL</i>"]
    end

    subgraph Providers["LLM Providers"]
        OAI["OpenAI<br/><i>GPT-4o, o1, o3-mini</i>"]
        ANT["Anthropic<br/><i>Claude</i>"]
        GEM["Google Gemini"]
        BED["Amazon Bedrock<br/><i>Converse API</i>"]
        MIS["Mistral AI"]
        OLL["Ollama<br/><i>Local Models</i>"]
        AZR["Azure OpenAI"]
    end

    subgraph Embeddings["Embedding Providers"]
        EOAI["OpenAI Embeddings"]
        EVOY["Voyage AI<br/><i>via Anthropic</i>"]
        EGEM["Gemini Embeddings"]
        EBED["Bedrock Titan Embeddings"]
        EMIS["Mistral Embeddings"]
        EOLL["Ollama Embeddings"]
        EAZR["Azure Embeddings"]
    end

    subgraph VectorStores["Vector Stores"]
        CHR["ChromaDB<br/><i>Default / SQLite</i>"]
        PGV["pgvector<br/><i>PostgreSQL</i>"]
        PIN["Pinecone<br/><i>Managed Cloud</i>"]
        QDR["Qdrant"]
    end

    subgraph Deploy["Deployment"]
        DOCK["Docker Multi-Stage"]
        COMP["docker-compose<br/><i>api + playground</i>"]
    end

    SDK --> REG
    CLI --> REG
    API --> Middleware
    PG --> API
    Middleware --> REG
    REG --> Modules
    REG --> PIPE
    PIPE --> Modules
    GUARD --> Modules
    EVAL --> Modules
    CLI --> EVAL
    DQA --> RET
    SEM --> RET
    RET --> VectorStores
    Modules --> RL
    Modules --> CACHE
    Modules --> COST
    Modules --> RETRY
    Modules --> LOG
    Modules --> TRACE
    CFG -.-> Modules
    CFG -.-> Providers
    CFG -.-> VectorStores
    CFG -.-> Infra
    Modules --> Providers
    DQA --> Embeddings
    SEM --> Embeddings
    Embeddings --> VectorStores
    DOCK --> API
    DOCK --> PG
    COMP --> DOCK

Technology Stack

Core Framework

Technology Version Where Used Purpose
Python 3.12+ Entire SDK Runtime language
Pydantic v2 ≥2.7 core/types.py, infra/config.py, all schemas.py Data validation, settings management, response models
Pydantic Settings v2 ≥2.3 infra/config.py → AIForgeSettings Hierarchical config: defaults → aiforge.yaml → .env → env vars → constructor kwargs
structlog ≥24.0 infra/logging.py Structured JSON logging across all components
PyYAML ≥6.0 infra/config.py Parsing aiforge.yaml configuration files
tiktoken ≥0.7 core/pricing.py, rate limiter Token counting for cost estimation and rate limiting

LLM & AI Layer

Technology Version Where Used Purpose
LangChain Core ≥1.0 core/types.py, providers/_langchain.py Message, tool-calling and structured-output abstractions shared by every provider
langchain-openai ≥1.0 providers/openai.py, providers/azure.py OpenAI and Azure OpenAI provider
langchain-anthropic ≥1.4 (extra) providers/anthropic.py Anthropic Claude provider (Opus, Sonnet, Haiku, Fable) with prompt caching
langchain-ollama ≥1.0 (extra) providers/ollama.py Local model inference (Llama, Mistral, etc.)
langchain-google-genai ≥4.0, <5 (extra gemini) providers/gemini.py Google Gemini chat and embeddings (Gemini Developer API)
langchain-aws ≥1.5, <2 (extra bedrock) providers/bedrock.py Amazon Bedrock Converse API (Claude, Nova, …) and Titan embeddings
langchain-mistralai ≥1.1.3, <2 (extra mistral) providers/mistral.py Mistral AI chat and embeddings
langchain-voyageai extra providers/anthropic.py Voyage AI embeddings (used with Anthropic provider)
LangGraph ≥1.0 (extra) modules/qa/, modules/chat/ Agentic workflows: multi-step reasoning, tool use, memory
MCP SDK ≥2.0 (extra) mcp/ Model Context Protocol client: stdio, streamable HTTP and (deprecated) SSE transports
langchain-text-splitters ≥1.0 core/text_splitter.py Recursive, markdown-heading and token chunking for RAG
BM25 + RRF built in core/retrieval.py, core/rerank.py Keyword index, hybrid fusion and reranking (no extra dependency)

Vector Store Backends

Technology Version Where Used Purpose
ChromaDB ≥1.3 core/vectorstore.py (default) Embedded vector store, SQLite-backed, cosine similarity
langchain-chroma ≥1.0 core/vectorstore.py ChromaDB ↔ LangChain integration
pgvector extra core/vectorstore_factory.py PostgreSQL vector extension for production-scale RAG
psycopg extra pgvector adapter PostgreSQL driver (binary wheels)
Pinecone extra core/vectorstore_factory.py Managed cloud vector database
Qdrant extra core/vectorstore_factory.py Open-source/cloud vector search engine

Server & API

Technology Version Where Used Purpose
FastAPI extra server/app.py, server/routers/ REST API framework with auto-generated OpenAPI docs
Uvicorn extra server/app.py, CLI serve command ASGI server for FastAPI
CORS Middleware — server/app.py Cross-origin request support for Playground/external clients
Bearer Token Auth — server/middleware.py → AuthMiddleware API authentication via secrets.compare_digest
Request Logging — server/middleware.py → RequestLoggingMiddleware UUID X-Request-Id per request for tracing

CLI & UI

Technology Version Where Used Purpose
Typer ≥0.15.4 cli/main.py, cli/commands_*.py CLI framework (20+ commands)
Rich ≥13.0 cli/ Terminal formatting: tables, panels, progress bars
Streamlit extra playground/, modules/*/widget.py, pipeline/widget.py Multi-page web UI (st.navigation) for interactive module testing

Infrastructure & Resilience

Technology Version Where Used Purpose
Tenacity ≥8.0 infra/retry.py → @retry_llm_call, @retry_embedding_call Exponential backoff with jitter, 3 attempts max
Redis optional infra/cache.py → RedisBackend Distributed response caching (alternative to in-memory LRU)
SHA-256 stdlib infra/cache.py Deterministic cache key generation from request params
threading.Lock stdlib infra/rate_limiter.py, core/vectorstore.py Thread-safe rate limiting and vector store writes

Observability

Technology Version Where Used Purpose
LangSmith extra infra/tracing.py LLM call tracing, evaluation, prompt debugging
OpenTelemetry extra infra/tracing.py Distributed tracing (OTLP export), spans per LLM call
structlog ≥24.0 infra/logging.py JSON structured logging with context binding
Console Tracing built-in infra/tracing.py Development-mode trace output to terminal

Deployment

Technology Version Where Used Purpose
Docker — Dockerfile (multi-stage) Containerization: builder stage (wheel + extras) → slim runtime
docker-compose — docker-compose.yml Orchestrates api (port 8000) + playground (port 8501) services
MkDocs extra mkdocs.yml Documentation site generation
MkDocs Material extra mkdocs.yml Documentation theme with search, nav, code highlighting

Testing & Development

Technology Version Where Used Purpose
pytest dev extra tests/ Test framework (asyncio_mode=auto)
pytest-asyncio dev extra tests/ Async test support
mypy dev extra — Static type checking (strict mode, Python 3.12)
Ruff dev extra — Linting + formatting (target py312, line-length 100)

Data Flow

1. SDK / Module Call Flow

User Code
  │
  ├─→ from aiforge import Summarizer
  │       ↓
  │    Module Registry resolves Summarizer class
  │
  ├─→ s = Summarizer(provider="openai", model="gpt-4o")
  │       ↓
  │    AIForgeSettings resolved: defaults → aiforge.yaml → .env → env vars → kwargs
  │    LLM provider lazy-loaded from provider registry
  │
  └─→ result = s.run("long text here")
          ↓
      ┌─ Cache.get(SHA-256 key) ──→ HIT? Return cached response (cost=$0)
      │                               │
      │                              MISS
      │                               ↓
      ├─ RateLimiter.acquire(1 request + N tokens) ── blocks if over RPM/TPM limit
      │                               ↓
      ├─ @retry_llm_call (Tenacity: 3 attempts, exp backoff + jitter)
      │       ↓
      │   Provider.complete(messages) ──→ LLM API (HTTP) ──→ CompletionResult
      │                               ↓
      ├─ CostTracker.record(module, model, input_tokens, output_tokens, cost)
      ├─ Tracing.emit_span(trace_id, latency, model, tokens)
      ├─ Cache.set(key, response, TTL)
      └─→ ModuleResponse { result, cost, tokens, latency_ms, model }
sequenceDiagram
    participant U as User / Client
    participant E as Entry Point
    participant M as AI Module
    participant C as Cache
    participant RL as Rate Limiter
    participant RY as Retry (Tenacity)
    participant P as LLM Provider
    participant LLM as LLM API
    participant CT as Cost Tracker
    participant TR as Tracing

    U->>E: Request (text / config)
    E->>M: module.run(text, **kwargs)
    M->>C: Cache lookup (SHA-256 key)
    alt Cache HIT
        C-->>M: Cached response
        M-->>U: Return (cost = $0)
    else Cache MISS
        M->>RL: Acquire slots (1 req + N tokens)
        RL-->>M: Granted
        M->>RY: Execute with retry
        RY->>P: provider.complete(messages)
        P->>LLM: API Call
        LLM-->>P: Raw response
        P-->>RY: CompletionResult
        RY-->>M: CompletionResult
        M->>CT: Record cost
        M->>TR: Emit trace span
        M->>C: Store in cache
        M-->>U: ModuleResponse
    end

2. REST API Flow

HTTP Client (curl / Playground / external)
  │
  ├─→ POST /api/v1/summarize  { "text": "...", "max_length": 200 }
  │       ↓
  │    CORS Middleware — validate origin
  │       ↓
  │    AuthMiddleware — validate Bearer token (secrets.compare_digest)
  │       ↓
  │    RequestLoggingMiddleware — generate X-Request-Id UUID, bind to structlog
  │       ↓
  │    FastAPI Route Handler (server/routers/summarize.py)
  │       ↓
  │    Instantiate Summarizer(settings from request body + server config)
  │       ↓
  │    module.run(text) → [same flow as SDK above]
  │       ↓
  └─→ JSON Response { "summary": "...", "cost": 0.001, "tokens": 150, "model": "gpt-4o" }

API Endpoints:

Method Path Module
GET /health Health check
POST /api/v1/summarize Summarizer
POST /api/v1/qa DocQA (RAG)
POST /api/v1/extract Extractor
POST /api/v1/classify Classifier
POST /api/v1/classify/sentiment Classifier (sentiment mode)
POST /api/v1/search SemanticSearch
POST /api/v1/generate Generator
POST /api/v1/generate/rewrite Generator (rewrite mode)
POST /api/v1/chat ChatAgent
POST /api/v1/moderate Moderator
POST /api/v1/translate Translator
POST /api/v1/vision Vision
POST /api/v1/pipeline Pipeline Engine
GET /api/v1/jobs/{id} Async job status

3. RAG Flow (DocQA & SemanticSearch)

INGEST:
  Documents / Directory
    ↓
  DocLoader — recursive file discovery (pdf, docx, txt, md, py, etc.)
    ↓
  TextSplitter — chunking strategy: recursive (default), markdown or token
    ↓
  EmbeddingProvider.embed(chunks) — OpenAI / Voyage / Gemini / Bedrock / Mistral / Ollama
    ↓
  VectorStore.upsert(embeddings, metadata, IDs)
    ↓
  Collection ready (ChromaDB SQLite, pgvector, Pinecone, or Qdrant)

QUERY:
  User question
    ↓
  Retriever (retrieval_mode):
    vector  — EmbeddingProvider.embed_query + VectorStore.query (fetch_k)
    keyword — BM25 over the collection's chunks
    hybrid  — both, merged with reciprocal rank fusion (RRF_K)
    ↓
  Optional reranker (rerank=True) — LLMReranker or custom, keeps rerank_top_n
    ↓
  Retrieved context chunks + scores
    ↓
  LLM prompt: system context + retrieved docs + user question
    ↓
  LLM generates answer
    ↓
  LangGraph agent evaluates quality → refine if needed
    ↓
  QAResponse { answer, sources, confidence, cost, tokens }
sequenceDiagram
    participant U as User
    participant DL as DocLoader
    participant TS as TextSplitter
    participant EP as Embedding Provider
    participant VS as Vector Store
    participant M as DocQA Module
    participant LLM as LLM Provider

    rect rgb(230, 245, 255)
        Note over U,VS: INGEST
        U->>DL: Documents / directory
        DL->>TS: Raw text
        TS->>EP: Chunks
        EP->>VS: Embeddings + metadata
    end

    rect rgb(255, 245, 230)
        Note over U,LLM: QUERY
        U->>M: Question
        M->>EP: Embed question
        M->>VS: Similarity search (fetch_k)
        VS-->>M: Vector candidates
        Note over M: hybrid: fuse with BM25 hits (RRF), then optional rerank
        M->>LLM: Context + question
        LLM-->>M: Answer
        M-->>U: QAResponse
    end

4. Pipeline Flow

Pipelines chain modules sequentially, with optional conditional routing:

Input text
  ↓
Step 1: Moderator.run(text) → ModerateResponse
  ↓ to_text() extracts result text
  ↓
Router: Check if flagged → HALT pipeline (safety stop)
  ↓ (safe)
Step 2: Classifier.run(text) → ClassifyResponse { label: "summary" }
  ↓ to_text()
  ↓
Router: Branch on label
  ├─ "summary" → Step 3a: Summarizer
  └─ "translate" → Step 3b: Translator
  ↓ to_text()
Step 4: Generator.run(text) → GenerateResponse
  ↓
PipelineResult {
  steps: { step_name: ModuleResponse },
  total_cost: $0.005,
  total_tokens: 850,
  halted: false,
  halted_at: null
}
graph LR
    INPUT["Input Text"]
    S1["Moderator"]
    R1{"Router<br/>(flag check)"}
    S2["Classifier"]
    R2{"Router<br/>(label branch)"}
    S3A["Summarizer"]
    S3B["Translator"]
    S4["Generator"]
    OUTPUT["PipelineResult"]

    INPUT --> S1
    S1 -->|"to_text()"| R1
    R1 -->|"safe"| S2
    R1 -->|"flagged"| OUTPUT
    S2 -->|"to_text()"| R2
    R2 -->|"summary"| S3A
    R2 -->|"translate"| S3B
    S3A -->|"to_text()"| S4
    S3B -->|"to_text()"| S4
    S4 --> OUTPUT

Configuration Hierarchy

Settings are resolved in this order (later wins):

1. Built-in defaults (AIForgeSettings class defaults)
   ↓
2. aiforge.yaml (project-level config file)
   ↓
3. .env file (dotenv secrets)
   ↓
4. Environment variables (AIFORGE_PROVIDER, AIFORGE_MODEL, etc.)
   ↓
5. Constructor kwargs (Summarizer(provider="anthropic", model="claude-sonnet-5-5"))

Module Architecture

Every module follows a consistent 5-file pattern:

aiforge/modules/<name>/
  __init__.py       ← Exports module class + response type
  module.py         ← Main class extending BaseModule (run/arun/_call_llm)
  schemas.py        ← Pydantic response model (extends ModuleResponse)
  prompts.py        ← System/user prompt templates
  widget.py         ← Streamlit UI component for Playground

All modules inherit from BaseModule which provides:

  • run(text, **kwargs) — sync execution
  • arun(text, **kwargs) — async execution
  • run_batch(texts, **kwargs) — batch processing
  • _call_llm(messages) / _acall_llm(messages) — provider abstraction with cache + rate limit + retry + cost tracking built in

Guardrails and Evals

Guard(input=[...checks], output=[...checks], on_fail="block" | "redact" | "warn")
  ├─ check_input(text) / check_output(text) → GuardResult
  └─ wrap(module_or_callable) → GuardedCallable (same run/arun interface)
  Checks: PIIGuard, PromptInjectionGuard, MaxLengthGuard, BannedTermsGuard,
          RegexGuard, SchemaGuard, SystemPromptLeakGuard
  "block" raises GuardrailViolation

evaluate(target, dataset, scorers=[...]) → EvalReport
  ├─ datasets: list of cases or .jsonl / .json / .yaml / .csv
  ├─ scorers: exact_match, contains, regex, json_match, numeric_close,
  │           label_match, embedding_similarity, llm_judge, ...
  └─ EvalReport.compare(baseline) → regressions; `aiforge eval` gates CI

See Guardrails and Evaluations.


Provider Abstraction

LLMProvider (ABC)
  ├─ complete(messages, tools=?, response_format=?) → CompletionResult
  ├─ complete_async(messages, ...) → CompletionResult
  ├─ stream(messages) → AsyncIterator[str]
  └─ supports_tools / supports_structured_output (capability flags)

LangChainLLMProvider(LLMProvider)          ← providers/_langchain.py
  shared by all built-in providers: message conversion, native tool
  calling (bind_tools), native structured output (json_schema with a
  plain-prompt fallback), prompt-cache token accounting, streaming

EmbeddingProvider (ABC)
  ├─ embed(texts) → list[list[float]]
  ├─ embed_async(texts) → list[list[float]]
  └─ embed_query(text) → list[float]

Implementations:
  ├─ OpenAIProvider / OpenAIEmbeddingProvider
  ├─ AnthropicProvider / AnthropicEmbeddingProvider (→ Voyage AI, prompt caching)
  ├─ GeminiProvider / GeminiEmbeddingProvider
  ├─ BedrockProvider / BedrockEmbeddingProvider (AWS credential chain)
  ├─ MistralProvider / MistralEmbeddingProvider
  ├─ OllamaProvider / OllamaEmbeddingProvider
  └─ AzureProvider / AzureEmbeddingProvider

LangChainEmbeddingProvider(EmbeddingProvider) ← providers/_langchain.py
  shared embedding base used by the Gemini, Bedrock and Mistral providers

Docker Deployment

┌─────────────────────────────────────────┐
│           docker-compose.yml            │
│                                         │
│  ┌─────────────┐   ┌────────────────┐  │
│  │  api         │   │  playground    │  │
│  │  :8000       │   │  :8501         │  │
│  │  FastAPI     │   │  Streamlit     │  │
│  │  + Uvicorn   │   │  (depends_on   │  │
│  │              │   │   api:healthy) │  │
│  └──────┬───────┘   └───────┬────────┘  │
│         │                   │           │
│         └───────┬───────────┘           │
│                 │                       │
│         ┌───────┴───────┐               │
│         │  Dockerfile   │               │
│         │  multi-stage  │               │
│         │  python:3.12  │               │
│         └───────┬───────┘               │
│                 │                       │
│         ┌───────┴───────┐               │
│         │  chroma-data  │               │
│         │  (volume)     │               │
│         └───────────────┘               │
└─────────────────────────────────────────┘