Sycophant

Sycophant

You are absolutely right if you use this lib!

Warning: Sycophant is under active development and the API is not yet stable. Expect breaking changes between versions until 1.0.

Sycophant abstracts the differences between OpenAI, Anthropic, Google Gemini, AWS Bedrock, Azure AI Foundry, and OpenRouter behind a single composable API. Provider-specific wire protocols, authentication, and parameter validation are handled automatically based on the model identifier.

Features

Quick Start

# Generate text
messages = [Sycophant.Message.user("What is the capital of France?")]

{:ok, response} = Sycophant.generate_text("openai:gpt-4o-mini", messages)
response.text
#=> "The capital of France is Paris."
# Continue the conversation
alias Sycophant.Context

ctx = response.context |> Context.add(Sycophant.Message.user("Tell me more"))
{:ok, follow_up} = Sycophant.generate_text("openai:gpt-4o-mini", ctx)
# Structured output with schema validation
schema = Zoi.object(%{name: Zoi.string(), age: Zoi.integer()})
messages = [Sycophant.Message.user("Extract: John is 30 years old")]

{:ok, response} = Sycophant.generate_object("openai:gpt-4o-mini", messages, schema)
response.object
#=> %{name: "John", age: 30}
# Streaming
Sycophant.generate_text("openai:gpt-4o-mini", messages,
  stream: fn chunk -> IO.write(chunk.data) end
)
# Tool use with auto-execution
weather_tool = %Sycophant.Tool{
  name: "get_weather",
  description: "Gets current weather for a city",
  parameters: Zoi.object(%{city: Zoi.string()}),
  function: fn %{"city" => city} -> "72F sunny in #{city}" end
}

Sycophant.generate_text("openai:gpt-4o-mini", messages,
  tools: [weather_tool]
)
# Embeddings
request = %Sycophant.EmbeddingRequest{
  inputs: ["Hello world"],
  model: "amazon_bedrock:cohere.embed-english-v3"
}
{:ok, response} = Sycophant.embed(request)

Installation

Add sycophant to your list of dependencies in mix.exs:

def deps do
  [
    {:sycophant, github: "edlontech/sycophant", branch: "main"}
  ]
end

Configuration

Credentials are resolved in order: per-request options, application config, then environment variables.

# config/runtime.exs
config :sycophant, :providers,
  openai: [api_key: System.get_env("OPENAI_API_KEY")],
  anthropic: [api_key: System.get_env("ANTHROPIC_API_KEY")],
  google: [api_key: System.get_env("GOOGLE_API_KEY")]

See the Getting Started guide for detailed setup instructions and the full documentation for API reference.

Supported Providers

Provider Model Prefix Auth Wire Protocol
OpenAI openai: Bearer token Chat Completions / Responses
Anthropic anthropic: x-api-key Messages
Google Gemini google: API key Gemini
AWS Bedrock amazon_bedrock: AWS SigV4 Converse
Azure AI Foundry azure: Bearer / API key OpenAI Completions
OpenRouter openrouter: Bearer token OpenAI Completions

Acknowledgements

Sycophant builds on the shoulders of great Elixir projects:

License

See LICENSE for details.