Skip to main content
LLM Providers

Local Models: Ollama, vLLM and LiteLLM

Run Akmatori investigations on models that you host yourself. The Custom provider talks to any server that implements the OpenAI Chat Completions API, so alerts, logs and tool output stay inside your network.

How the Custom provider works

The agent worker sends POST <Base URL>/chat/completions with streaming and function tools. The investigation agent needs tool calls: it reaches SSH, Kubernetes, Zabbix, metrics and every other connector through one tool, gateway_call. A server or a model without working tool calls can write a summary, but it cannot investigate.

Add the model in Settings → AI models → Add Configuration:

Provider

Custom

API keyRequired

The key of your server. Akmatori enables a model only when the key is not empty, so for a server without authentication (for example Ollama) enter any value, such as ollama.

ModelRequired

Choose Other (enter manually) and type the model name exactly as the server knows it, for example qwen3:30b-a3b for Ollama.

Base URLRequired

In Advanced settings. The URL up to and including /v1, as the akmatori-agent container sees it, for example http://ollama:11434/v1. localhost is the container itself, not your host.

Thinking LevelOptional

Any level other than Off sends reasoning_effort. Set it to Off if your server rejects that field.

Save the model and click Activate. Investigations, chat and the short one-shot calls (titles, summaries, alert extraction) then all use it.

Ollama

The simplest setup runs Ollama as one more container on the network that the agent worker uses for outbound calls. Put this file next to docker-compose.yml:

docker-compose.override.yml
services:
  ollama:
    image: ollama/ollama:latest
    container_name: akmatori-ollama
    restart: unless-stopped
    environment:
      # The default is 4k tokens without a large GPU: far too small.
      - OLLAMA_CONTEXT_LENGTH=65536
    volumes:
      - ollama_models:/root/.ollama
    networks:
      - frontend
    # GPU (NVIDIA Container Toolkit):
    # deploy:
    #   resources:
    #     reservations:
    #       devices:
    #         - driver: nvidia
    #           count: all
    #           capabilities: [gpu]

volumes:
  ollama_models:

Start it and pull a model:

bash
docker compose up -d ollama
docker exec akmatori-ollama ollama pull qwen3:30b-a3b
docker exec akmatori-ollama ollama list

Then add a Custom model with Base URL http://ollama:11434/v1, API key ollama and the model name that ollama list prints.

Set the context length. Without a large GPU, Ollama uses a 4k-token context and cuts longer prompts without an error: in our test a 17,814-token prompt reached the model as 2,050 tokens with HTTP 200. Akmatori assumes a 128k window for Custom models and compacts the history only near that limit, so a small server context silently drops the system prompt, tool output and evidence. OLLAMA_CONTEXT_LENGTH=65536 fixes this (Ollama caps it at the model's own maximum).

Ollama on the host instead

If Ollama already runs on the Docker host, three things must be true:

  1. Ollama listens on an address that containers can reach. By default it listens on 127.0.0.1:11434 only; set OLLAMA_HOST=0.0.0.0:11434 (or the Docker bridge address, for example 172.17.0.1:11434) and restart it. Set OLLAMA_CONTEXT_LENGTH there too (see the warning above).
  2. The worker can resolve the host. On Linux, host.docker.internal does not exist by default; add it to akmatori-agent (the only container that calls the model):
docker-compose.override.yml
services:
  akmatori-agent:
    extra_hosts:
      - "host.docker.internal:host-gateway"
  1. The host firewall accepts the connection. Traffic from a container to the host goes through the host's INPUT chain. With a default-deny policy the request hangs and Akmatori reports Request timed out. Allow the Docker subnets to port 11434, for example iptables -I INPUT -s 172.16.0.0/12 -p tcp --dport 11434 -j ACCEPT.

The Base URL is then http://host.docker.internal:11434/v1.

vLLM and SGLang

vLLM serves the OpenAI API at /v1. It returns tool calls only when you start it with automatic tool choice and the tool-call parser for your model family:

bash
vllm serve Qwen/Qwen3-32B \
  --enable-auto-tool-choice \
  --tool-call-parser hermes \
  --api-key change-me

See the vLLM tool calling guide for the parser of each model family. Set the API key to the value of --api-key, or to any value if you did not set one. Akmatori sends the system prompt with the role system, not developer, to custom endpoints, because some chat templates drop the developer role without an error.

LiteLLM proxy

A LiteLLM proxy gives Akmatori one OpenAI-compatible endpoint in front of many backends (Ollama, vLLM, Azure OpenAI, Bedrock, Vertex AI) with central keys, budgets and logs. Define the models in the proxy config:

litellm-config.yaml
model_list:
  - model_name: sre-agent
    litellm_params:
      model: ollama_chat/qwen3:30b-a3b
      api_base: http://ollama:11434

litellm_settings:
  # Required: drops OpenAI-only fields (store) that ollama_chat rejects.
  drop_params: true

In Akmatori, add a Custom model:

  • Base URL: the proxy address with /v1, for example http://litellm:4000/v1
  • API key: a LiteLLM virtual key, or the master key
  • Model: the model_name from the config, for example sre-agent

Keep drop_params: true. Akmatori sends OpenAI request fields such as store, and without this setting LiteLLM rejects every request to an ollama_chat/ model with 400 UnsupportedParamsError: ollama_chat does not support parameters: ['store']. With it, tool calls and thinking text pass through the proxy (tested with LiteLLM 1.108.0 and Ollama 0.40.15).

The backend model behind the alias must support tool calls, and the Ollama context-length warning above applies behind the proxy too.

Choose a model that can call tools

Akmatori gives the model one generic tool, gateway_call(tool_name, args, instance), instead of one tool per command. The model must put the inner tool name (for example ssh.execute_command) into the tool_name argument. Small models often call ssh.execute_command as if it were a tool of its own.

Ollama drops a tool call whose name is not one of the defined tools, and returns an empty answer without an error. The investigation then ends with no result. If an investigation on Ollama finishes with an empty answer, try a larger model before you look for a network problem.

We sent the worker's own request (the gateway_call schema, a disk-usage alert, streaming) to Ollama 0.40.15 with each Qwen3 size, directly and through LiteLLM:

ModelSizeCorrect gateway_call
qwen3:0.6b0.5 GB0 of 2 requests
qwen3:4b2.5 GB0 of 2 requests
qwen3:8b5.2 GB0 of 2 requests
qwen3:30b-a3b18.6 GB13 of 28 requests (46%)

Every failed request ended with an empty answer. Thinking level, context length and the LiteLLM proxy did not change the rate. So even a 30B model on a single machine is a demo, not a production setup: about half of its investigations would stop at the first tool call. The open-weight models that do the job are much larger; for the ones that found the root cause in 11 of 12 real incidents and the hardware they need, see Self-Hosted AI SRE Agent With Local Models and SRE Bench. Test your model with a few alerts before you rely on it.

Troubleshooting

Connection error.

The worker cannot resolve or connect to the Base URL host. Check the name from inside the container: docker exec akmatori-agent getent hosts ollama.

Request timed out.

The name resolves but no answer arrives: usually a host firewall, or a server that listens on 127.0.0.1 only. A slow first request can also time out while the server loads the model into memory; send one request with curl first to warm it up.

LLM not configured

Akmatori shows "Your active LLM provider has no API key configured" when the API key field is empty. Enter any value for servers without authentication.

HTTP proxy

If you set HTTP_PROXY for Akmatori, add the model host (for example ollama) to NO_PROXY and no_proxy, or the request goes to the proxy.