ai-proxy
Proxies requests to an LLM provider with a unified API.
ai-proxyPriority 1040What it does
ai-proxy sends the requests a route takes to a language model at a provider, in place of an upstream. The Provider picks the service and the request format. The Auth holds the key the provider expects, and the Options name the model, for example gpt-4o.
A client posts a chat request to the route without a provider key of its own and gets the model's answer back in the same call. A provider with no address of its own, openai-compatible for example, is called at the address under Endpoint.
When to use it
- An assistant inside the orders API that calls one model, with the provider key held at the gateway instead of in every service that calls it.
- A model served inside your own network behind an OpenAI-style API, reached with
openai-compatibleand the address under Endpoint. - A model on Amazon Bedrock, or a Gemini model on Vertex AI, signed with AWS keys or a Google service account instead of a header.
- One place to cap what a call may produce, with Output token limit replacing whatever the client asked for.
- A token budget per route or per consumer, counted by ai-rate-limiting from the usage the model reports.
Not for spreading requests over several models or providers, with fallback — see ai-proxy-multi (Proxies requests to several LLM providers with balancing and fallback), sending requests to your own backend instances — see Upstream (Upstreams are the backends that routes and services send traffic to) or changing the path or headers of a request to an ordinary backend — see proxy-rewrite (Rewrites the request URI, method, host and headers before proxying).
Guides
Pages that walk through a job with ai-proxy, step by step.
- Put a language model behind the gatewaySend your apps' chat requests to one language model through a route, with the model's key on the gateway, a token budget, a prompt guard and a cache.
Set it up
Send chat requests to a model on Amazon Bedrock
Under Basics set Provider to bedrock, fill Provider settings as in the JSON below, fill Auth as in the JSON below and fill Options as in the JSON below.
{
"provider": "bedrock",
"auth": {
"aws": {
"access_key_id": "$env://AWS_ACCESS_KEY_ID",
"secret_access_key": "<secret>"
}
},
"provider_conf": {
"region": "us-east-1"
},
"options": {
"model": "anthropic.claude-3-5-sonnet-20240620-v1:0"
}
}
More scenarios
Send chat requests to a Gemini model on Vertex AI
Under Basics set Provider to vertex-ai, fill Provider settings as in the JSON below, fill Auth as in the JSON below and fill Options as in the JSON below.
{
"provider": "vertex-ai",
"auth": {
"gcp": {
"service_account_json": "$env://GOOGLE_SERVICE_ACCOUNT_JSON"
}
},
"provider_conf": {
"project_id": "orders-prod",
"region": "europe-west4"
},
"options": {
"model": "gemini-2.0-flash"
}
}
Things to know
- A client posts a body with
messagesto the route and is answered200with the model's answer,Hello from the mock modelin the ai-cache example this row cites. The route carries no upstream, and the client sends no provider key. - Region — With Provider
bedrock, a configuration without a Region is refused when you save. - Project ID — Vertex AI needs the project and the region together, or an endpoint override instead, and one of the two alone is refused.
- Auth — A configuration without Auth is refused when you save.
- Auth — For Bedrock, write the AWS keys under aws; a header or query credential is refused with that provider.
- Endpoint — A scheme and host alone keep the provider's own path. An address with a path is used as written, so
https://llm.internal/v1is called as/v1. - Endpoint — Two providers carry no address of their own, openai-compatible and azure-openai, so a document that names one of them is refused until this override carries an address; the engine alone would store it and answer every request with 500.
- Request body — Objects merge key by key. A list or a single value replaces the client's only with Request body force override on.
- Output token limit — The limit is sent under the name the provider expects, for example
max_completion_tokensfor OpenAI chat. - Summaries — Nothing is written unless a logger plugin runs on the route.
- Timeout — The longest Timeout is
600000milliseconds;600001is refused when you save. - Response size limit — A non-streamed answer over the cap reaches the client as
502withmax_response_bytes exceeded. - ai-rate-limiting on the same route counts the tokens the model reports and names this plugin after its provider,
ai-proxy-openai-compatible. The answer then carriesX-Ai-Ratelimit-Limit-Ai-Proxy-Openai-Compatible. - AdviceWrite a provider key as a
$secret://or$env://reference rather than as plain text in the route.
Settings
The fields as the console shows them, section by section. A field under “When … is …” is there only while that value is set.
Basics
providerstringRequiredThe AI service the request is sent to, which sets the request format and the default address. Endpoint under Override replaces the address.
When Provider is bedrock
provider_confobjectRequiredprovider_conf.regionstringRequiredThe cloud region the model is served from, such as us-east-1 for Bedrock or us-central1 for Vertex AI.
When Provider is vertex-ai· 3 fields
provider_confobjectprovider_conf.project_idstringThe Google Cloud project the Vertex AI model belongs to.
provider_conf.regionstringThe cloud region the model is served from, such as us-east-1 for Bedrock or us-central1 for Vertex AI.
authobjectRequired{"header":{"Authorization":"Bearer YOUR_API_KEY"}}auth.awsobjectOther keys are stored as written.
auth.aws.access_key_idstringRequiredauth.aws.secret_access_keystringRequiredStored on the engine and shown only to roles that manage this object.
auth.aws.session_tokenstringStored on the engine and shown only to roles that manage this object.
auth.gcpobjectOther keys are stored as written.
auth.gcp.expire_early_secsintegerdefault 60auth.gcp.max_ttlintegerauth.gcp.service_account_jsonstringStored on the engine and shown only to roles that manage this object.
auth.headerobjectStored on the engine and shown only to roles that manage this object. An object whose keys are letters, digits, dots, underscores and hyphens, each with a string as its value.
auth.queryobjectStored on the engine and shown only to roles that manage this object. An object whose keys are letters, digits, dots, underscores and hyphens, each with a string as its value.
optionsobjectSettings passed to the model with every request, such as the model name, the temperature or the maximum tokens. Other keys are stored as written.
{"model":"gpt-4o","temperature":0.2}options.modelstringoverrideobjectRequired when Provider is azure-openai or openai-compatibleoverride.endpointstringRequired when Provider is azure-openai or openai-compatibleAn address to send requests to instead of the provider's own, either a scheme and host or a full URL with its path. A scheme and host alone keep the provider's own path. An address with a path is used exactly as written, so https://llm.internal/v1 is called as /v1.
https://llm.internal/v1override.llm_optionsobjectoverride.llm_options.max_tokensintegerThe most output tokens a call may produce, replacing whatever the client asked for. It is sent under the name the provider expects, such as max_completion_tokens for OpenAI chat or max_output_tokens for the Responses API.
override.request_bodyobjectJSON merged into the outgoing request body, under the key of the protocol the request is sent in. Objects merge key by key. Lists and single values replace the client's only with force override on.
override.request_body.anthropic-messagesobjectMerged into the request body when the target protocol is Anthropic messages.
{"metadata":{"user_id":"gateway"}}override.request_body.bedrock-converseobjectMerged into the request body when the target protocol is Bedrock converse.
{"inferenceConfig":{"topP":0.9}}override.request_body.openai-chatobjectMerged into the request body when the target protocol is OpenAI chat.
{"top_p":0.9}override.request_body.openai-embeddingsobjectMerged into the request body when the target protocol is OpenAI embeddings.
{"encoding_format":"float"}override.request_body.openai-responsesobjectMerged into the request body when the target protocol is OpenAI responses.
{"store":false}override.request_body.passthroughobjectMerged into the request body when the request is passed through in its own format.
{"stream":false}override.request_body_force_overridebooleandefault falseOn, the override values replace what the client sent, and off they only fill in what the client left out.
Behavior
loggingobjectlogging.payloadsbooleandefault falseAdds the request and response bodies to the record that a logger plugin on this route writes. Nothing is written unless a logger plugin runs on the route.
logging.summariesbooleandefault falseAdds the model, the duration and the token counts to the record that a logger plugin on this route writes. Nothing is written unless a logger plugin runs on the route.
timeoutintegerdefault 30000How long the gateway waits for the model to answer one call.
ssl_verifybooleandefault truemax_response_bytesintegerThe largest model response in bytes, streamed or not, where empty sets no cap. A non-streamed answer over the cap reaches the client as 502 'max_response_bytes exceeded'.
max_stream_duration_msintegerThe longest a streamed answer may run before it is cut off, and unset means no limit.
streaming_flush_interval_msintegerdefault 10How often buffered streamed output is sent on to the client, where zero sends each chunk as it arrives.
Advanced
max_req_body_sizeintegerdefault 67108864The largest request body in bytes the gateway reads, and a larger one is refused with 413.
keepalivebooleandefault truekeepalive_poolintegerdefault 30keepalive_timeoutintegerdefault 60000How long an idle connection to the provider is kept open for reuse.