LLM connections
Neens reads no global LLM API key. Every LLM-powered feature — judge scoring, insight summaries, the assistant, topic and issue classification, enrichments, remediation generation, cluster labeling — resolves an LLM connection you configure per workspace, org, or agent. Your credentials stay yours: they are encrypted at rest and never echoed back by any API.
At a glance
| Where | Settings → LLM providers |
| Key API routes | GET/POST /llm-connections, PATCH/DELETE /llm-connections/{id}, POST /llm-connections/probe, POST /llm-connections/list-models |
| API formats | Anthropic, OpenAI-compatible, Google Gemini, OpenRouter, LiteLLM, Ollama, Custom, HTTP API |
| Credentials | Write-only; encrypted at rest; never returned by any read |
| Who can manage | Members and admins may create org/agent connections; company-wide connections are admin-only. You can delete a connection you created; admins can delete any |
| Without one | LLM features skip or degrade gracefully — nothing else breaks |
API formats
The API format you choose describes the API protocol the endpoint speaks, not the model vendor. Most hosted and self-hosted model services speak the OpenAI chat-completions API, so for anything that isn’t Anthropic, Google Gemini, or one of the named formats below, pick OpenAI-compatible and point it at the endpoint.
| API format | What it is | Credential |
|---|---|---|
| Anthropic | The Anthropic API (Claude models). | API key |
| OpenAI-compatible | Any endpoint speaking the OpenAI /v1/chat/completions API — OpenAI itself, plus DeepSeek, Together, Fireworks, vLLM, LM Studio, and most hosted or self-hosted gateways. Set the Base URL to the endpoint’s /v1 URL. | API key |
| Google Gemini | Google’s native Generative Language API (generateContent) for Gemini models. Leave the Base URL blank — it defaults to Google’s endpoint (https://generativelanguage.googleapis.com) server-side. | Google API key |
| OpenRouter | OpenRouter — one endpoint fronting hundreds of models from many providers. Base URL is filled in for you (https://openrouter.ai/api/v1). | API key |
| LiteLLM | Your own LiteLLM proxy — one OpenAI-compatible endpoint in front of many providers, with your keys and routing. Requires your proxy’s base URL. | As required by your proxy |
| Ollama | A local/self-hosted Ollama server. Base URL defaults to http://localhost:11434/v1. | None needed |
| Custom | Any other OpenAI-compatible endpoint — an Amazon Bedrock–fronting gateway, an internal proxy. Requires a base URL. | As required by the endpoint |
| HTTP API | Outbound HTTP auth for external-API judges and enrichments — it holds the credential (bearer token, header, query parameter, or basic auth) Neens attaches when a judge or enrichment calls a third-party HTTP endpoint instead of an LLM. Not a model connection. | As required by the endpoint |
To point Neens at your own agent’s HTTP endpoint for pre-prod evaluations — where Neens replays each golden prompt against your agent — use the separate Add agent endpoint button on the same page, not the API-format dropdown. See Testing an agent endpoint below.
Local and self-hosted endpoints (Ollama, localhost-style base URLs) work without a
credential. Remote managed providers require one — a run against a keyless remote connection
fails fast with a clear error instead of making a doomed network call.
Create a connection
Open Settings → LLM providers
Click Add connection and pick the API format. Fill in the model (e.g.
claude-sonnet-4-6), the base URL where applicable, and the credential.
For formats that publish a model catalogue (OpenAI-compatible, OpenRouter, LiteLLM, Ollama, and
Custom endpoints) you can click Load models (POST /llm-connections/list-models)
to pull the available model ids and pick from a searchable list instead of typing one. Listing is
best-effort — if it can’t be fetched, just enter the model id by hand.
Choose its visibility
A connection is visible at one of three levels:
- Company — every org and agent in the workspace can use it (admin-only to create or edit).
- Org — one or more specific orgs.
- Agent — one or more specific agents.
Members can only target orgs/agents they have access to, so a credential is never shared wider than its creator could see.
Each connection records who created it, shown in the list. You can delete (disable) a connection you created; an admin can delete any. The delete control only appears on rows you’re allowed to remove — so an admin-created (or another member’s) connection is protected from deletion by a member.
Test it
Click Test (POST /llm-connections/probe) — Neens makes one real, tiny completion
(“ping”) through the provider and reports reachability. A reasoning model that spends the
probe’s 512-token budget without visible output still counts as reachable. Nothing from the
probe is persisted.
Save, optionally as the default
Marking a connection default makes it the one runs fall back to when nothing more specific is chosen. There is one default at a time — setting it clears the previous one.
Worked examples
DeepSeek (an OpenAI-compatible vendor)
DeepSeek, Together, Fireworks, vLLM, LM Studio, and most hosted or self-hosted gateways speak the OpenAI chat-completions API. You pick OpenAI-compatible — the API format, not a vendor name — and tell Neens which endpoint to call.
Add connection → API format = OpenAI-compatible
That’s the key choice: DeepSeek has no format of its own — it speaks the OpenAI API, so you select OpenAI-compatible rather than looking for a “DeepSeek” entry.
Base URL = the vendor’s /v1 URL
For DeepSeek that’s https://api.deepseek.com/v1. (Use whatever /v1 URL your vendor
publishes.)
Model = the vendor’s model id
For example deepseek-chat or deepseek-reasoner.
Paste the API key, then Test and save
Paste the key the vendor issued you, click Test to confirm it’s reachable, and save.
Google Gemini
Add connection → API format = Google Gemini
This is the native Google format — no base URL needed.
Model = gemini-2.5-flash
Or gemini-2.5-pro for a higher-quality, slower model.
Leave Base URL blank
It defaults to Google’s endpoint (https://generativelanguage.googleapis.com).
Paste your Google AI Studio API key, then Test and save
Create a key in Google AI Studio, paste it into the credential field, click Test, and save.
Testing an agent endpoint
The Test action for an agent_http connection calls your endpoint exactly the way the
pre-prod worker will, with a trivial ping prompt. This probe is SSRF-guarded: a base URL
whose host resolves to a private, loopback, or link-local address is refused unless an
operator has explicitly allowlisted that host. Redirects are never followed. That allowlist is
what lets a deliberately internal endpoint — a Docker service, a VPC host, localhost — be
probed and called on purpose.
Credentials and secrets
- Credentials are write-only: you can set or replace one, but no read endpoint ever returns it. The UI shows only whether a usable credential is present.
- Stored credentials are encrypted at rest using a symmetric key. If the deployment has no encryption key configured, Neens refuses to store the plaintext — the save succeeds but returns a warning that the credential was discarded, so nothing sensitive is ever written unprotected.
- Instead of pasting a key, you can supply a secret reference (
secretRef, e.g.secret://my-key), which Neens resolves at use time from the environment variableNEENS_SECRET_<NAME>on the server — useful when secrets are injected by your infrastructure rather than stored in Neens.
How runs pick a connection
When a judge run, enrichment, insight summary, or clustering pass needs an LLM, Neens resolves the connection in this order, always restricted to connections visible to the run’s agent:
- The explicit connection chosen in the feature’s configuration (e.g. the judge editor).
- The agent-visible connection marked default.
- The first agent-visible connection.
A run can never pick up a connection scoped exclusively to another org or agent — the same visibility rule the Settings page applies on read also governs the workers, so a credential never leaks across an internal boundary (and company-level physical isolation keeps it from ever crossing tenants).
Judges can additionally select multiple connections as a pool: an eval run distributes its scoring calls across the pool round-robin, multiplying throughput across several hosts or API keys. See Judges.
What consumes the connection
| Feature | Uses the connection for |
|---|---|
| Judges & scoring | Every judge call in eval runs, including continuous (on-ingest) evaluation |
| Pre-prod evaluations | Scoring replayed golden datasets; agent_http connections are what Neens calls when it invokes your agent |
| Insights | The AI-written fleet briefing, generated in the background and swapped in when ready |
| Assistant | The in-app chat assistant |
| Topics & Issues | Topic and issue classification |
| Enrichments | LLM-prompt enrichments over traces |
| Remediations | Generating fixes and simulating them (counterfactual replay) |
| Clustering | Labeling failure clusters and drafting root-cause hypotheses |
Without a connection
An agent with no visible connection degrades gracefully, never errors the platform:
- Clustering still runs — clusters simply stay unlabeled until a connection appears.
- Judge runs, enrichments, and remediation generation report a clear configuration error for that run instead of failing silently.
- Anomaly/regression detectors, retention, and ingest make no LLM calls at all, so observability keeps working end to end.
- The Insights fleet briefing reports
unavailableand serves its computed, real-number briefing instead — permanently, with nothing queued and nothing retried. That is a supported end state, not an error.
Reference
Connection fields
| Field | Meaning |
|---|---|
name | Display name (defaults to provider/model). |
provider | The API format. In the UI this field is labelled API format; on the API the field name stays provider. Its value is the API format the endpoint speaks — e.g. anthropic, openai (any OpenAI-compatible endpoint), gemini, openrouter, litellm, ollama, custom, http_api (outbound auth for external-API judges/enrichments). A pre-prod agent endpoint is the separate agent_http value, added via Add agent endpoint. |
model | Model id sent on completions (optional for agent_http). |
baseUrl | Endpoint base URL (required for custom and agent_http; defaults to the local server for ollama). |
credential | API key / bearer token — write-only, encrypted at rest. |
secretRef | Reference resolved from the server environment instead of a stored credential. |
scopeType + scopeIds | Visibility: company, or org/project with explicit targets. |
isDefault | The fallback connection for runs (one per workspace at a time). |
requestsPerMinute | Informational rate figure shown with the connection. |
options | Provider-specific knobs passed through on every completion (e.g. Ollama num_ctx, top_p, a default timeout; request shape and auth mode for agent_http). |
Connection changes are recorded to the audit log
(llm_connection.create, llm_connection.update, llm_connection.delete).
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Save returns a warning that the credential was discarded | The deployment has no encryption key, so encryption at rest is impossible | Ask an operator to configure the encryption key, or use a keyless local endpoint / a secretRef |
Test fails for an internal agent_http URL | The host resolves to a private/loopback address and isn’t allowlisted | Ask an operator to allowlist the host or CIDR |
| Judge run errors with “no usable credential” | Remote provider with no stored key or resolvable secret reference | Add a credential, or switch to a local/Ollama endpoint |
| Clusters have no labels | No connection is visible to the agent | Create one at agent, org, or company scope |
Related
- Judges — the heaviest consumer of connections, including pools.
- Pre-prod evaluations — golden-dataset replays and
agent_httpagent endpoints. - Audit log — who changed which connection, and when.