AIProxy now supports YAML configuration files for managing channels, model configurations, and system options.
The configuration system follows this priority order (highest to lowest):
- Environment Variables (highest priority)
- YAML Configuration File (medium priority)
- Database (lowest priority)
This means:
- Values set via environment variables will always take precedence
- YAML configuration will override database values
- Database values are used as defaults when no other configuration is provided
By default, AIProxy looks for config.yaml in the current working directory.
You can specify a custom location using the CONFIG_FILE_PATH environment variable:
export CONFIG_FILE_PATH=/path/to/your/config.yamlThe YAML configuration file has three main sections. The channel and modelconfig structures directly correspond to the database model types, making it easy to understand and maintain.
Define your API provider channels:
channels:
- name: "openai-primary"
type_name: "openai" # Human-readable type name (recommended)
# OR use numeric type:
# type: 1 # OpenAI channel type
key: "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
base_url: "https://api.openai.com"
models:
- "gpt-4"
- "gpt-3.5-turbo"
model_mapping:
"gpt-4": "gpt-4-0613"
status: 1 # 1=Enabled, 2=Disabled
priority: 0
balance: 100.0
balance_threshold: 10.0
enabled_auto_balance_check: true
sets:
- "default"You can use either type_name (human-readable string) or type (numeric code). Using type_name is recommended for better readability:
Supported Type Names:
openai: OpenAI APIazure/azure2: Azure OpenAIanthropic/claude: Anthropic Claudegemini/google gemini: Google Geminigemini-openai/google gemini (openai): Google Gemini via OpenAI APIzhipu: Zhipu AIali/aliyun: Alibaba Cloudbaidu: Baidu Wenxinbaiduv2/baidu v2: Baidu Wenxin v2xunfei: iFlytek Sparktencent: Tencent Hunyuanmoonshot: Moonshot AIdeepseek: DeepSeekaws: AWS Bedrockvertexai/vertex: Google Vertex AIxai: xAI Grokgroq: Groqmistral: Mistral AIcohere: Coherefake: Local fake adaptor for protocol simulation and integration testingopenrouter: OpenRouter- And many more... (see
core/model/yaml_integration.gofor the complete list)
Numeric Channel Types:
1: OpenAI3: Azure14: Anthropic/Claude24: Google Gemini53: Fake adaptor- See
core/model/chtype.gofor complete list
The fake channel type is intended for local protocol verification, end-to-end integration tests, demos, and front-end development without calling any upstream provider. It synthesizes responses for:
- OpenAI
chat/completions - OpenAI
completions - OpenAI
responsesand related sub-APIs - Anthropic native
/messages - Gemini native
/models/*:generateContent embeddingsimages/generationsrerank
Example YAML:
channels:
- name: "fake-debug"
type_name: "fake"
key: "fake-key"
models:
- "fake-chat"
- "fake-response"
- "fake-gemini"
- "fake-anthropic"
- "fake-embedding"
- "fake-image"
- "fake-rerank"
configs:
static_text: "Fake adaptor says hello."
response_prefix: "[debug] "
response_suffix: " <eom>"
reasoning_text: "Synthesized locally."
stream_chunks: 4
usage:
input_tokens: 32
output_tokens: 16
cached_tokens: 4
reasoning_tokens: 3
embedding:
dimensions: 12
image:
url: "https://fake.local/assets/fake-image.png"
b64_json: "ZmFrZS1pbWFnZQ=="
rerank:
base_score: 0.98
step: 0.07
response:
store: true
status: "completed"
anthropic:
stop_reason: "end_turn"
gemini:
finish_reason: "STOP"
metadata:
environment: "local"
openapi:
spec_version: "3.1.0"
info:
title: "Fake Adaptor Template"
version: "1.0.0"static_text: Main synthesized output text for chat/completion/responses/anthropic/gemini.response_prefix/response_suffix: Wrap synthesized text.reasoning_text: Summary inserted into Responses API reasoning output.delay_ms: Artificial latency in milliseconds.stream_chunks/stream_chunk_size: Control streaming segmentation.usage.*: Override input, output, cached, reasoning, and image token counts.embedding.dimensions: Output vector dimensions.image.url/image.b64_json: Fake image payload.rerank.base_score/rerank.step: Fake rerank score template.response.store: Whether fake Responses API objects should be pinned into the internal store for subsequentGET /responses/{id}style calls.metadata: Arbitrary metadata copied into fake Responses API objects.openapi.*: OpenAPI-style templating section for documenting or versioning fake channel config payloads.
Define model-specific settings:
modelconfigs:
- model: "gpt-4"
owner: "openai"
type_name: "chat" # Human-readable type name (recommended)
# OR use numeric type:
# type: 1 # ChatCompletions
rpm: 3500 # Requests per minute
tpm: 80000 # Tokens per minute
retry_times: 3
timeout_config:
request_timeout: 300
stream_request_timeout: 600
warn_error_rate: 0.5
max_error_rate: 0.8
price:
input: 0.03 # Price per 1000 input tokens
output: 0.06 # Price per 1000 output tokens
config:
max_context_tokens: 8192
max_output_tokens: 4096
vision: false
tool_choice: true
- model: "text-embedding-3-small"
owner: "openai"
type_name: "embedding" # Embedding model
rpm: 3000
tpm: 1000000
price:
input: 0.00002
output: 0You can use either type_name (human-readable string) or type (numeric code). Using type_name is recommended for better readability:
Supported Type Names:
chat/chatcompletions: Chat completion modelscompletion/completions: Text completion modelsembedding/embeddings: Embedding modelsmoderation/moderations: Moderation modelsimage/imagegenerations: Image generation modelsimageedit/imageedits: Image editing modelsaudio/speech/audiospeech: Text-to-speech modelstranscription/audiotranscription: Audio transcription modelstranslation/audiotranslation: Audio translation modelsrerank: Reranking modelspdf/parsepdf: PDF parsing modelsanthropic: Anthropic-specific models- And more... (see
core/model/yaml_integration.gofor the complete list)
Numeric Model Types:
1: ChatCompletions2: Completions3: Embeddings4: Moderations5: ImagesGenerations- See
core/relay/mode/define.gofor complete list
Common configuration keys:
max_context_tokens: Maximum context window sizemax_output_tokens: Maximum output tokensvision: Whether the model supports vision/image inputstool_choice: Whether the model supports function calling
Configure system-wide options:
options:
# Log retention (in hours)
LogStorageHours: "168" # 7 days
RetryLogStorageHours: "72" # 3 days
LogDetailStorageHours: "24" # 1 day
# Log settings
SaveAllLogDetail: "false"
LogDetailRequestBodyMaxSize: "10000"
LogDetailResponseBodyMaxSize: "10000"
# Rate limiting
IPGroupsThreshold: "100" # Requests per minute
IPGroupsBanThreshold: "200"
# Retry settings
RetryTimes: "3"
RetryBudget: "0" # Seconds, maximum 180; 0 disables the time limit
# Error rate alerts
DefaultWarnNotifyErrorRate: "0.5"
# Usage alerts
UsageAlertThreshold: "100"LogStorageHours: How long to keep logs (hours)RetryLogStorageHours: How long to keep retry logs (hours)LogDetailStorageHours: How long to keep detailed logs (hours)CleanLogBatchSize: Batch size for log cleanup operationsIPGroupsThreshold: Request rate limit per IPIPGroupsBanThreshold: Ban threshold for IPSaveAllLogDetail: Whether to save all request/response detailsLogDetailRequestBodyMaxSize: Max size of request body to logLogDetailResponseBodyMaxSize: Max size of response body to logDisableServe: Disable API serving (for maintenance)RetryTimes: Number of retry attemptsRetryBudget: Time budget in seconds, from 0 to 180; 0 disables the time limit. TheRETRY_BUDGETenvironment variable overrides this global default and is capped at 180 seconds.DefaultChannelModels: Default models for new channels (JSON array)GroupMaxTokenNum: Max tokens per groupDefaultWarnNotifyErrorRate: Default error rate warning thresholdUsageAlertThreshold: Usage alert thresholdFuzzyTokenThreshold: Fuzzy token matching threshold
The budget starts with the first upstream attempt and includes upstream calls and retry backoff. After it expires, no further retry starts. An in-flight call keeps its existing request or stream timeout.
Models can set retry_budget to override the global budget, set it to 0 to disable the budget, or omit it to inherit. Group model configs use override_retry_budget and retry_budget to override the model value, including zero. Retry counts continue to use retry_times and override_retry_times.
| Effective configuration | Behavior |
|---|---|
| Count only | Stop after the configured number of retries |
| Budget only | Retry until the budget expires, with no count limit |
| Count and budget | Stop when either limit is reached |
| Neither | No retries |
A model that explicitly sets a positive budget and has no positive retry count uses only that budget, without inheriting the global count. With no local budget, global count and budget defaults apply together. A group can clear an inherited model count with override_retry_times: true and retry_times: 0; when a budget is active, this enables retries for the remaining budget. Without a budget, a zero model count retains the existing global count fallback. Permission failures exclude the channel but do not increase the retry limit. A retry count excludes the initial attempt.
See config.example.yaml for a complete example configuration file.
-
Create a
config.yamlfile in your project root or specify a custom location viaCONFIG_FILE_PATH -
Start AIProxy as usual:
./aiproxy
-
The configuration will be loaded in this order:
- Database values (if any)
- YAML configuration (overrides database)
- Environment variables (overrides everything)
Changes to the YAML configuration file require restarting the application to take effect.
However, you can still use the web UI or API to modify configurations at runtime, which will be stored in the database.
You can extract your current database configuration and convert it to YAML format:
- Export your channels via the web UI
- Export your model configs via the web UI
- Convert to YAML format following the structure in
config.example.yaml
- All values in the
optionssection must be strings (they will be parsed according to their type) - Channel and model config IDs are optional in YAML - if omitted, the system will auto-generate them
- When both YAML and database contain the same configuration, YAML takes precedence
- New configurations from YAML that don't exist in the database will be automatically added
- Check the log output on startup - it will show how many channels/models were loaded from YAML
- Verify the YAML syntax is correct (use a YAML validator)
- Ensure the file path is correct (check
CONFIG_FILE_PATHenvironment variable)
Environment variables override YAML values through the config.SetXxx() functions which check for environment variables on every call. Make sure you're using the correct environment variable names (see core/common/config/env.go for the list).
If you modify configuration through the web UI or API, those changes will be written to the database. On next restart, YAML will override those database values again. Use YAML for persistent configuration and the web UI for temporary changes.