代理伺服器
Proxy 是一個本地 HTTP 代理,透明地攔截你的 AI Agent 對 LLM Provider 的請求,自動提取 token 用量、延遲、成本等指標,無需修改任何現有程式碼。
簡化路由(推薦)
使用 Proxy 最簡單的方式是簡化路由。你只需要指定 agent 名稱和 provider 名稱,Proxy 會自動處理所有端點路徑:
POST http://localhost:18900/agents/{agent-name}/{provider}支援的 Provider
| Provider | 端點 |
|---|---|
openai | OpenAI Chat Completions |
anthropic | Anthropic Messages |
google | Google Gemini(OpenAI 相容) |
mistral | Mistral Chat |
deepseek | DeepSeek Chat |
moonshot | Moonshot / Kimi Chat |
zhipu | 智譜 GLM Chat |
minimax | MiniMax Chat |
baichuan | 百川 Chat |
agentgazer | 虛擬 Provider(自動偵測) |
AgentGazer 虛擬 Provider(推薦)
agentgazer 虛擬 provider 透過首次請求自動建立 agent,簡化接入流程:
const openai = new OpenAI({
baseURL: "http://localhost:18900/agents/my-bot/agentgazer",
apiKey: "dummy",
});運作方式
- 首次請求:發送任意請求,model 設為
agentgazer-proxy - 自動建立:Proxy 建立 agent 並回傳成功訊息
- 設定路由:到 Dashboard → Agents → Model Settings 設定目標 provider
- 開始使用:後續請求自動路由到你設定的 provider
首次請求範例
// 這會建立 agent 並確認連線
const response = await openai.chat.completions.create({
model: "agentgazer-proxy", // 用於連線測試的特殊 model
messages: [{ role: "user", content: "test" }],
});
// 回傳: "AgentGazer connected successfully for agent 'my-bot'..."優點
- 不需要知道 provider — 不用決定要用哪個 provider 就能開始
- 集中設定 — 在 Dashboard 改 provider,不用改程式碼
- 跨 provider 路由 — 不同 model 可路由到不同 provider
何時使用
新專案或想用 Dashboard 管理 provider 設定時使用 agentgazer。需要在程式碼中直接控制時使用明確的 provider(openai, anthropic)。
範例:透過簡化路由使用 OpenAI
import OpenAI from "openai";
const openai = new OpenAI({
baseURL: "http://localhost:18900/agents/my-bot/openai",
apiKey: "dummy", // 會被儲存的金鑰取代
});
const response = await openai.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Hello!" }],
});範例:透過簡化路由使用 Anthropic
import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic({
baseURL: "http://localhost:18900/agents/my-bot/anthropic",
apiKey: "dummy", // 會被儲存的金鑰取代
});
const message = await anthropic.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello!" }],
});優點
- 不需要了解路徑格式 — 你不需要知道
/v1/chat/completions、/v1/messages或其他 provider 特定的路徑 - 自動金鑰注入 — Proxy 會自動注入該 provider 儲存的 API 金鑰
- 內建 agent 追蹤 — agent 名稱嵌入在 URL 中
路徑前綴路由
Proxy 支援路徑前綴路由,將請求自動轉發到對應的 Provider:
| 路徑前綴 | 目標 |
|---|---|
/openai/... | https://api.openai.com |
/anthropic/... | https://api.anthropic.com |
/google/... | https://generativelanguage.googleapis.com |
/mistral/... | https://api.mistral.ai |
/deepseek/... | https://api.deepseek.com |
/moonshot/... | https://api.moonshot.cn |
/zhipu/... | https://open.bigmodel.cn |
/minimax/... | https://api.minimax.chat |
/baichuan/... | https://api.baichuan-ai.com |
OpenAI SDK 整合範例
方式 A:使用儲存的 API Key(推薦)
如果你已經用 agentgazer providers set openai <key> 儲存了 API Key,使用路徑前綴讓 Proxy 自動注入:
export OPENAI_BASE_URL=http://localhost:18900/agents/my-agent/agentgazerimport OpenAI from "openai";
const openai = new OpenAI({
baseURL: "http://localhost:18900/agents/my-agent/agentgazer",
apiKey: "dummy", // 任意值,會被 Proxy 覆蓋
});方式 B:自己提供 API Key
如果你想用自己的 API Key(不使用儲存的金鑰):
import OpenAI from "openai";
const openai = new OpenAI({
baseURL: "http://localhost:18900/v1",
apiKey: process.env.OPENAI_API_KEY, // 必須自己提供
});Proxy 會從路徑 /v1/chat/completions 偵測到是 OpenAI 請求並透傳你的 Key。
Anthropic SDK 整合範例
使用路徑前綴 /anthropic,Proxy 會自動注入儲存的 API Key:
import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic({
baseURL: "http://localhost:18900/anthropic",
apiKey: "dummy", // 任意值,會被 Proxy 覆蓋
});
const message = await anthropic.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello!" }],
});若要自己提供 API Key,設定
apiKey並確保不使用路徑前綴(但此情況下無法自動注入)。
Agent 識別
Proxy 支援多種方式識別發出請求的 Agent。
路徑式 Agent ID
在 URL 路徑中加入 agent ID,使用 /agents/{agent-id}/ 格式:
http://localhost:18900/agents/my-bot/openai/v1/chat/completions
└─────────┘└────────────────────────────┘
Agent ID Provider 路徑OpenAI SDK 範例:
const openai = new OpenAI({
baseURL: "http://localhost:18900/agents/coding-assistant/openai/v1",
apiKey: "dummy",
});適用情境:
- SDK 不支援自訂 header
- 希望 agent ID 在 URL 中可見
- 使用 curl 或簡單的 HTTP 用戶端
x-agent-id Header(替代方式)
你也可以使用 x-agent-id header 搭配明確的 provider 路由:
const openai = new OpenAI({
baseURL: "http://localhost:18900/agents/default/openai",
apiKey: "dummy",
defaultHeaders: {
"x-agent-id": "my-agent-name", // 覆蓋 URL 中的 "default"
},
});Agent ID 優先順序
當同時使用多種識別方式時,Proxy 依照以下優先順序:
| 優先順序 | 方式 | 範例 |
|---|---|---|
| 1(最高) | x-agent-id header | x-agent-id: my-agent |
| 2 | 路徑前綴 | /agents/my-agent/openai/... |
| 3(最低) | 預設值 | 啟動時設定或 "default" |
自動建立 Agent
當 Proxy 收到不存在的 agent ID 請求時,會自動建立該 Agent 並套用預設政策設定。
使用 x-target-url Header
若路徑前綴路由無法滿足需求,可使用 x-target-url header 明確指定目標:
curl http://localhost:18900/v1/chat/completions \
-H "x-target-url: https://api.openai.com" \
-H "Authorization: Bearer sk-xxx" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o","messages":[{"role":"user","content":"Hi"}]}'Provider 偵測優先順序
Proxy 使用以下順序偵測目標 Provider:
- 路徑前綴 — 如
/openai/...、/anthropic/... - Host Header — 如
Host: api.openai.com - 路徑模式 — 如
/v1/chat/completions對應 OpenAI - x-target-url Header — 手動指定目標 URL
政策執行
Proxy 在轉發請求前會檢查 Agent 政策。當政策阻擋請求時,Proxy 會回傳假的 LLM 回應,而不是轉發到 Provider。
政策檢查
| 政策 | 行為 |
|---|---|
| Active | 若 active=false,所有請求會被阻擋 |
| Budget Limit | 若當日花費 >= budget_limit,請求會被阻擋 |
| Allowed Hours | 若當前時間在 allowed_hours_start 到 allowed_hours_end 之外,請求會被阻擋 |
阻擋回應格式
被阻擋時,Proxy 會回傳符合 Provider 格式的有效回應:
OpenAI 格式:
{
"id": "blocked-...",
"object": "chat.completion",
"choices": [{
"message": {
"role": "assistant",
"content": "[AgentGazer] Request blocked: budget_exceeded"
},
"finish_reason": "stop"
}]
}Anthropic 格式:
{
"id": "blocked-...",
"type": "message",
"content": [{
"type": "text",
"text": "[AgentGazer] Request blocked: agent_deactivated"
}],
"stop_reason": "end_turn"
}阻擋原因
| 原因 | 說明 |
|---|---|
agent_deactivated | Agent 的 active 設定為 false |
budget_exceeded | 當日花費已達 budget_limit |
outside_allowed_hours | 當前時間在允許區間之外 |
被阻擋的請求會被記錄為 event_type: "blocked" 的事件,阻擋原因會記錄在 tags 中。
頻率限制(Rate Limiting)
Proxy 會執行 Dashboard 中設定的 per-agent per-provider 頻率限制。當超過限制時,Proxy 回傳 429 Too Many Requests 回應。
運作方式
頻率限制使用滑動窗口演算法:
- 記錄每個請求的時間戳
- 新請求抵達時,移除超出窗口時間的舊時間戳
- 若剩餘數量 >= 最大請求數,拒絕該請求
- 回應包含
retry_after_seconds,計算自窗口中最舊請求何時過期
回應格式
被頻率限制時,Proxy 回傳符合 Provider 格式的錯誤回應:
OpenAI 格式(大多數 Provider 通用):
{
"error": {
"message": "Rate limit exceeded for agent \"my-bot\" on openai. Please retry after 45 seconds.",
"type": "rate_limit_error",
"param": null,
"code": "rate_limit_exceeded"
},
"retry_after_seconds": 45
}Anthropic 格式:
{
"type": "error",
"error": {
"type": "rate_limit_error",
"message": "Rate limit exceeded for agent \"my-bot\" on anthropic. Please retry after 45 seconds."
},
"retry_after_seconds": 45
}HTTP Header 也會設定 Retry-After。
設定方式
頻率限制在 Dashboard 的 Agent Detail → Rate Limit Settings 區塊設定。詳見 Dashboard 頻率限制設定。
阻擋原因
被頻率限制的請求會記錄阻擋原因 rate_limited 在事件 tags 中。
模型覆寫(Model Override)
Proxy 可以依據 Dashboard 設定的規則改寫請求中的模型。
運作方式
- 請求抵達,帶有
model: "gpt-4o" - Proxy 檢查此 agent + provider 是否有覆寫規則
- 若有規則(例如覆寫成 "gpt-4o-mini"),Proxy 改寫請求內容
- 請求以
model: "gpt-4o-mini"轉發 - 事件同時記錄
requested_model: "gpt-4o"和model: "gpt-4o-mini"
使用情境
- 成本控制 — 不修改 Agent 程式碼,強制使用較便宜的模型
- 測試 — 比較不同模型的行為
- 快速回滾 — 出問題時快速切換模型
模型覆寫在 Dashboard 的 Agent Detail → Model Settings 區塊設定。
串流支援
Proxy 同時支援串流(SSE, Server-Sent Events)與非串流回應。串流模式下,Proxy 會在串流結束後非同步地解析並擷取指標。
健康檢查
curl http://localhost:18900/health回傳:
{
"status": "ok",
"agent_id": "my-agent",
"uptime_ms": 123456
}隱私保證
Proxy 只提取以下指標資料:
- Token 數量(輸入/輸出/合計)
- 模型名稱(請求的與實際使用的)
- 延遲(毫秒)
- 成本(USD)
- HTTP 狀態碼
Prompt 內容和 API Key 永遠不會傳送到 AgentGazer 伺服器。