BYO-LLM Architecture¶
This page describes the architecture of the Bring Your Own LLM (BYO-LLM) system in the Dev Health platform.
Component Overview¶
The BYO-LLM system integrates multiple entry points, a provider factory, and dual database storage.
flowchart TD
subgraph Callers [Entry Points]
CLI[CLI: dev-hops sync]
Worker[Celery Worker: work_graph_tasks]
API[API: explain endpoints]
end
subgraph Factory [Provider Factory]
GP[get_provider]
RP[resolve_provider_name]
RM[resolve_model_name]
end
subgraph Providers [LLM Providers]
OpenAI[OpenAIProvider]
Anthropic[AnthropicProvider]
Gemini[GeminiProvider]
Local[LocalProvider / Ollama / LMStudio]
Mock[MockProvider]
NoneP[NoneProvider]
end
subgraph Storage [Storage Layer]
Postgres[(Postgres: Org Settings)]
ClickHouse[(ClickHouse: Categorization Sink)]
end
CLI --> GP
Worker --> GP
API --> GP
GP --> RP
GP --> RM
RP -.-> Postgres
RM -.-> Postgres
GP --> OpenAI
GP --> Anthropic
GP --> Gemini
GP --> Local
GP --> Mock
GP --> NoneP
API -.-> Postgres
Worker -.-> ClickHouse
Core Components¶
1. Entry Points¶
- CLI: Operators run commands like
dev-hops syncto trigger manual synchronization. - Celery Worker: Background tasks run partitioned materialization jobs.
- API: Endpoints like
/api/v1/work-units/{work_unit_id}/explaingenerate explanations on demand.
2. Provider Factory¶
The get_provider function acts as a central factory. It resolves the provider name and model, retrieves credentials, and instantiates the correct provider class.
- resolve_provider_name: Determines which provider to use. It checks the requested name, the LLM_PROVIDER environment variable, and organization settings.
- resolve_model_name: Resolves the model name. It checks the requested model, environment variables, organization settings, and provider defaults.
3. LLM Providers¶
The platform supports multiple provider implementations: - OpenAIProvider: Connects to OpenAI APIs. - AnthropicProvider: Connects to Anthropic APIs. - GeminiProvider: Connects to Google Gemini APIs. - LocalProvider / Ollama / LMStudio: Connects to local or custom OpenAI-compatible endpoints. - MockProvider: Returns deterministic mock responses for testing. - NoneProvider: Represents an unconfigured state and fails closed for materialization.
4. Storage Layer¶
- Postgres: Stores organization-scoped settings. The
SettingsServiceencrypts sensitive values like API keys before saving them. - ClickHouse: Stores computed investment distributions, evidence quotes, and LLM token usage. The materializer writes token usage with the investment
run_idso admins can inspect spend per materialization run.
Admin Spend Endpoint¶
Org admins with BYO-LLM access can read spend through GET /api/v1/admin/llm-settings/spend. The endpoint is gated by the same byo_llm feature flag and TEAM-tier floor as the settings CRUD endpoints, and every ClickHouse read is scoped to the authenticated organization.
Default behavior returns the latest 20 non-empty run_id values from llm_token_usage in the last 30 days, ordered by each run's latest computed_at. limit is capped at 100 and since can narrow or expand the window. Each run entry reports run_id, provider, model, calls, input_tokens, output_tokens, computed_at, and failures_by_class.
Failure counts are categorization-outcome classes derived from persisted work_unit_investments.categorization_status and categorization_errors_json; they are not exact provider exception counts. Legacy token rows that predate run_id are returned separately under legacy with marker: "legacy_empty_run_id" and run_id: "", never as per-run spend.