polygate

One function.
Any LLM provider.

A tiny, dependency-light client that gives Anthropic, OpenAI, Gemini, and Moonshot one consistent request and response shape.

GitHub
from polygate import chat
 
response = chat(
provider="anthropic", # or "openai", "gemini", "moonshot"
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "Say hi in one word."}],
)
 
print(response.content) # "Hi!"
print(response.usage) # Usage(prompt_tokens=..., ...)

Swap providers by changing one string

Every adapter translates the same message list into whatever shape the provider actually expects. API keys come from the argument or fall back to the environment.

Anthropic

Claude models
"anthropic""claude"

ANTHROPIC_API_KEY

OpenAI

GPT models
"openai""gpt"

OPENAI_API_KEY

Google Gemini

Gemini models
"gemini""google"

GEMINI_API_KEY

Moonshot

Kimi models
"moonshot""kimi"

MOONSHOT_API_KEY

Adding a provider is one adapter file and one registry line. Contribute one

Every call returns the same shape

No more learning four response formats. Anything a provider returns that polygate does not normalize is still there, untouched, under raw.

Extra keyword arguments pass straight through to the provider, so provider-specific options like tools, top_p, or stop sequences keep working without polygate needing to know about them.

content
the assistant's reply text
role
always "assistant"
model
the model that was actually used
provider
which provider served the request
usage
prompt, completion, and total token counts
raw
the untouched original provider response

Small on purpose

polygate is not trying to out-feature LiteLLM, Portkey, or Helicone. It is the smallest layer that normalizes requests and responses across providers, with each adapter readable in under 100 lines. Retries, caching, and routing are yours to build on top, with whatever opinions your project actually needs.

What it does

  • One chat function across all providers
  • One message format, one response shape
  • API keys from arguments or environment
  • Passthrough for provider-specific options

What it leaves to you

  • Retries and backoff
  • Caching and cost tracking
  • Routing and fallback logic
  • Framework integrations