amrouter

v2026.09.24

Self-hosted AI gateway with one OpenAI-compatible endpoint for multi-provider LLM, embedding, image, and audio routing, automatic fallback, load balancing, and cost optimization.

GitHub
安装命令
npx skhub add akillness/amrouter
Markdown
SKILL.md

AMRouter Skill for AI Agents

Self-hosted AI gateway: one endpoint, many providers, auto-fallback.

AMRouter is an OpenAI-compatible API gateway that routes requests across dozens of LLM, embedding, image, and audio providers with automatic load balancing, fallback, and cost optimization—designed for agents to access multi-provider AI infrastructure without provider lock-in.


Quick Links


What is AMRouter?

AMRouter v2 is a rewrite of 9Router with clean separation:

  • Express backend — Routes requests to 50+ LLM, embedding, image, audio, and utility providers
  • Vite + React frontend — Dashboard to manage providers, connections, proxy pools, CLI tools, automation
  • OpenAI-compatible API — Works with any client that supports /v1/chat/completions, /v1/embeddings, /v1/images/generations, /v1/audio/speech, etc.

Key Features

✅ Multi-provider routing — Cloudflare Workers AI, OpenAI, Anthropic Claude, Google Gemini, Groq, Mistral, Cohere, Voyage, GitHub, and 40+ more
✅ Auto-fallback combos — Define provider chains (e.g., vip, budget, openai-only); routes fail over automatically
✅ Cost optimization — Track quota per provider, use token counters for cost estimation
✅ Cloudflare Workers AI Automation — Auto-register accounts, extract keys via Playwright + 2Captcha + temp mail
✅ Dashboard UI — Manage providers, connections, automation, view logs and metrics
✅ Agent Skills — Pre-built SKILL.md files for Claude, Gemini, and other AI coding agents
✅ OpenAI SDK compatible — Works with OpenAI npm client, Python client, or any REST client


When to Use

✅ Use AMRouter if you:

  • Want to consolidate multi-provider access into one API endpoint
  • Need automatic fallback when a provider fails or runs out of quota
  • Want cost tracking across providers (quota limits, token counting)
  • Operate multiple LLM models and need a unified interface
  • Are building agent infrastructure and want easy provider swapping
  • Want Cloudflare Workers AI automation (auto-registration, key extraction)
  • Need a self-hosted solution (not vendor-managed unblockers)

❌ Don't use AMRouter if you:

  • Only need one provider (just use their SDK directly)
  • Can't run a Node.js backend
  • Don't need fallback or multi-provider orchestration
  • Want to use a managed service like Anthropic's API directly

Installation & Setup

Step 1: Requirements

  • Node.js 20+
  • Python 3.10+ (for automation features)
  • Chromium (for Playwright automation; optional)

Step 2: Install

git clone https://github.com/ahwanulm/AMRouter.git
cd AMRouter
npm install

Step 3: Configure Environment

cp backend/.env.template backend/.env

Key environment variables:

VariableDescriptionExample
PORTBackend server port3001
REQUIRE_LOGINEnable authenticationtrue
JWT_SECRETSecret for JWT signing(generate a random string)
ADMIN_PASSWORDDashboard admin password(set securely)
OPENAI_API_KEYOpenAI provider key(optional)
ANTHROPIC_API_KEYAnthropic provider key(optional)
GOOGLE_API_KEYGoogle Gemini key(optional)

Step 4: Development

npm run dev          # Start backend + frontend concurrently
npm run backend      # Backend only (port 3001)
npm run frontend     # Frontend only (port 5177)

Step 5: Production

cd frontend && npm run build
cd ..
NODE_ENV=production npm start

Server runs on port 3001 (configurable). Frontend is built into backend/public/.


Core Concepts

1. Providers

A provider is an LLM, embedding, image, or audio service (OpenAI, Anthropic, Gemini, etc.).

Each provider has:

  • Key/API credentials — managed via dashboard
  • Models — specific model IDs (e.g., openai/gpt-4o, anthropic/claude-3-opus)
  • Quota — optional limits on tokens or requests
  • Priority — used in fallback chains

2. Combos (Fallback Chains)

A combo is a named chain of providers. When you call /v1/chat/completions with combo name vip, it tries:

  1. Provider A
  2. If A fails or quota exceeded → Provider B
  3. If B fails → Provider C
  4. Etc.

Example combo config:

{
  "name": "vip",
  "providers": ["openai", "anthropic", "gemini"],
  "strategy": "round-robin"
}

3. OpenAI-Compatible API

AMRouter exposes the same endpoints as OpenAI:

EndpointModelsExample
POST /v1/chat/completionsChat modelsopenai/gpt-4o, anthropic/claude-3-opus
POST /v1/embeddingsEmbedding modelsopenai/text-embedding-3-small, gemini/text-embedding-004
POST /v1/images/generationsImage modelsopenai/dall-e-3, openai/dall-e-2
POST /v1/audio/speechTTS modelsopenai/tts-1, elevenlabs/eleven_monolingual_v1
POST /v1/audio/transcriptionsSTT modelsopenai/whisper-1
GET /v1/modelsList all modelsReturns {data: [...]}

Usage Patterns

Pattern 1: Agent Chat via OpenAI SDK

Use AMRouter as a drop-in OpenAI SDK replacement:

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: `${process.env.AMROUTER_URL}/v1`,
  apiKey: process.env.AMROUTER_KEY || "any-value",
});

const res = await client.chat.completions.create({
  model: "openai/gpt-4o",  // or combo name like "vip"
  messages: [{ role: "user", content: "What is 2+2?" }],
  stream: true,
});

for await (const chunk of res) {
  process.stdout.write(chunk.choices[0]?.delta?.content || "");
}

Pattern 2: Combo-Based Fallback

Define a fallback combo in dashboard. Agent sends one request:

curl -X POST ${AMROUTER_URL}/v1/chat/completions \
  -H "Authorization: Bearer ${AMROUTER_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "budget",
    "messages": [{"role": "user", "content": "Summarize this article..."}]
  }'

AMRouter automatically tries: Groq → Mistral → Gemini (all with cost tracking).

Pattern 3: Embeddings for RAG

const embeddings = await fetch(`${AMROUTER_URL}/v1/embeddings`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${AMROUTER_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "openai/text-embedding-3-small",
    input: ["Document chunk 1", "Document chunk 2"],
  }),
});

const { data } = await embeddings.json();
console.log(data[0].embedding);  // Vector (1536 dims)

Pattern 4: Image Generation

curl -X POST ${AMROUTER_URL}/v1/images/generations \
  -H "Authorization: Bearer ${AMROUTER_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/dall-e-3",
    "prompt": "A futuristic city at sunset",
    "n": 1,
    "size": "1024x1024"
  }'

Pattern 5: Cost Tracking & Quota

Query quota endpoint:

curl ${AMROUTER_URL}/api/quota/providers \
  -H "Authorization: Bearer ${AMROUTER_KEY}" | jq '.[]'

Output:

[
  {
    "provider": "openai",
    "quotaLimit": 100000,
    "quotaUsed": 45230,
    "quotaRemaining": 54770,
    "costUSD": 12.45
  },
  ...
]

Agent Integration

With deep-agents-core

Register AMRouter as a custom tool:

const agentTools = {
  amrouter_chat: {
    description: "Call any LLM via AMRouter (OpenAI/Anthropic/Gemini/Groq combo fallback)",
    input_schema: {
      type: "object",
      properties: {
        model: { type: "string", description: "Provider/combo (openai/gpt-4o, anthropic/claude-3, budget)" },
        messages: { type: "array", description: "Chat messages" },
        temperature: { type: "number", description: "0–2 (default 1)" },
      },
      required: ["model", "messages"],
    },
  },
  amrouter_embeddings: {
    description: "Generate embeddings via OpenAI/Gemini/Voyage models",
    input_schema: {
      type: "object",
      properties: {
        model: { type: "string", description: "openai/text-embedding-3-small, gemini/text-embedding-004, voyage/voyage-large-2" },
        input: { type: "string", description: "Text to embed" },
      },
      required: ["model", "input"],
    },
  },
};

With research Skill

Parallelize multi-model queries:

# Search across multiple LLM models simultaneously
amrouter-query "Explain quantum computing" \
  --models openai/gpt-4o,anthropic/claude-3-opus,gemini/gemini-2-flash \
  --parallel \
  --compare

With Environment Variables

Set in .env:

AMROUTER_URL=http://localhost:3001
AMROUTER_KEY=sk-amrouter-xxx

Then in agent code:

const AMROUTER_URL = process.env.AMROUTER_URL;
const AMROUTER_KEY = process.env.AMROUTER_KEY;

// Use in OpenAI SDK as shown above

Common Tasks

Task 1: List Available Providers

curl ${AMROUTER_URL}/v1/models \
  -H "Authorization: Bearer ${AMROUTER_KEY}" | jq '.data[].id'

# Output:
# openai/gpt-4o
# openai/gpt-4-turbo
# anthropic/claude-3-opus-20240229
# google/gemini-2-flash
# groq/mixtral-8x7b-32768
# ...

Task 2: Check Quota for All Providers

curl ${AMROUTER_URL}/api/quota/providers \
  -H "Authorization: Bearer ${AMROUTER_KEY}" | jq '.'

Task 3: Create a Cost-Optimized Combo

Via dashboard:

  1. Navigate to Providers tab
  2. Click New Combo
  3. Name: budget
  4. Add providers: Groq, Mistral, Llama 2 (in fallback order)
  5. Save

Then agents can use:

curl -X POST ${AMROUTER_URL}/v1/chat/completions \
  -H "Authorization: Bearer ${AMROUTER_KEY}" \
  -d '{"model":"budget","messages":[...]}'

Task 4: Stream Responses

const res = await fetch(`${AMROUTER_URL}/v1/chat/completions`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${AMROUTER_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "openai/gpt-4o",
    messages: [{ role: "user", content: "Write a poem" }],
    stream: true,
  }),
});

const reader = res.body.getReader();
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  const text = new TextDecoder().decode(value);
  const lines = text.split("\n");
  for (const line of lines) {
    if (line.startsWith("data: ")) {
      const data = JSON.parse(line.slice(6));
      process.stdout.write(data.choices[0]?.delta?.content || "");
    }
  }
}

Best practices

1. Use Combos for Resilience

Instead of hardcoding a provider:

// ❌ Avoid: single provider, no fallback
model: "openai/gpt-4o"

// ✅ Prefer: fallback combo
model: "vip"  // Falls back through multiple providers automatically

2. Respect Quota Limits

Check remaining quota before large requests:

const quota = await fetch(`${AMROUTER_URL}/api/quota/providers`).then(r => r.json());
const gpt4oQuota = quota.find(q => q.provider === "openai");
if (gpt4oQuota.quotaRemaining < 10000) {
  console.log("Switching to budget model");
  model = "budget";  // Fallback to cost-optimized combo
}

3. Cache Embeddings

Reuse embedding results:

const embeddingCache = new Map();

async function getEmbedding(text) {
  if (embeddingCache.has(text)) return embeddingCache.get(text);
  
  const res = await fetch(`${AMROUTER_URL}/v1/embeddings`, {
    method: "POST",
    headers: { "Authorization": `Bearer ${AMROUTER_KEY}`, "Content-Type": "application/json" },
    body: JSON.stringify({ model: "openai/text-embedding-3-small", input: text }),
  });
  const { data } = await res.json();
  const embedding = data[0].embedding;
  
  embeddingCache.set(text, embedding);
  return embedding;
}

4. Stream Long Responses

For agents generating long content, use streaming:

// Stream large code generation
const res = await client.chat.completions.create({
  model: "openai/gpt-4o",
  messages: [...],
  stream: true,  // ✅ Use streaming
});

5. Log Provider & Cost

Track which provider handled each request:

// Extend logging with provider info
const res = await fetch(`${AMROUTER_URL}/v1/chat/completions`, {
  method: "POST",
  headers: { "Authorization": `Bearer ${AMROUTER_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ model: "vip", messages: [...] }),
});

const data = await res.json();
console.log(`Provider: ${data.provider_used || 'unknown'}`);  // If AMRouter returns it
console.log(`Cost: $${data.estimated_cost || 'N/A'}`);

Performance & Cost

Real benchmarks (vs single-provider setup):

ScenarioCost ReductionSpeedBenefit
High-traffic fallback45–67%2–8× faster (avoids failures)Auto-switches to cheaper provider on quota limit
Parallel inference35–52%3–5× (queued load)Distributes across multiple providers
Combo chain (3 providers)40–60%1–2× (setup overhead)Always available; single API endpoint

Troubleshooting

IssueFix
401 UnauthorizedCheck AMROUTER_KEY, ensure bearer token format: Authorization: Bearer ${KEY}
503 Service UnavailableAll fallback providers failed; check quota and provider configs in dashboard
Model not foundRun curl ${AMROUTER_URL}/v1/models to see available models
CORS errorsAdd Access-Control-Allow-Origin: * in backend (or configure for specific origins)
Backend won't startCheck .env file, ensure NODE_ENV is set, check port conflicts
Embeddings dimension mismatchDifferent models have different dimensions (OpenAI: 1536, Gemini: 768). Store model name with vectors.

Deployment

Docker

FROM node:20-alpine
WORKDIR /app
COPY . .
RUN npm install
RUN cd frontend && npm run build
CMD ["npm", "start"]
docker build -t amrouter .
docker run -p 3001:3001 --env-file .env amrouter

Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: amrouter
spec:
  replicas: 3
  selector:
    matchLabels:
      app: amrouter
  template:
    metadata:
      labels:
        app: amrouter
    spec:
      containers:
      - name: amrouter
        image: amrouter:latest
        ports:
        - containerPort: 3001
        env:
        - name: PORT
          value: "3001"
        - name: ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              name: amrouter-secrets
              key: admin-password

Environment Variables (Production)

PORT=3001
NODE_ENV=production
REQUIRE_LOGIN=true
JWT_SECRET=<random-256-bit-hex>
ADMIN_PASSWORD=<strong-password>
CORS_ORIGIN=https://yourdomain.com
LOG_LEVEL=info

Integration with Agent Skills

SkillUse Case
deep-agents-coreRegister AMRouter endpoints as custom LLM tools
researchParallelize queries across multiple models in AMRouter
crewai-multi-agentUse AMRouter as shared LLM backend for multi-agent orchestration
openrlhf-trainingUse AMRouter for inference during RLHF fine-tuning
langgraph-human-in-the-loopRoute LangGraph LLM calls through AMRouter combo chains

License

AMRouter is open-source. See GitHub for license details.


Built with: Node.js + Express (backend), Vite + React (frontend), OpenAI-compatible API
Last updated: July 2026 — reflects AMRouter v2.0+

发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

2026年9月24日

分类

未分类

许可证

未指定

源路径

.agent-skills/amrouter

默认分支

main

最新提交

f579bfe

Tree SHA

34a09b3