# OpenAI vs Anthropic Provider Kinds in DeepSeek-Reasonix: API Differences Explained

> Understand the API differences between OpenAI and Anthropic provider kinds in DeepSeek-Reasonix. Learn how they adapt external protocols to a unified internal interface for seamless integration.

- Repository: [YHH/DeepSeek-Reasonix](https://github.com/esengine/DeepSeek-Reasonix)
- Tags: deep-dive
- Published: 2026-08-06

---

**The `openai` and `anthropic` provider kinds in esengine/DeepSeek-Reasonix implement different external API protocols—OpenAI-compatible chat completions versus Anthropic's Claude API—while exposing a unified internal interface through service-specific request translation, token accounting, and error handling.**

DeepSeek-Reasonix abstracts multiple large language model backends through a pluggable provider system. Understanding the differences between the `openai` and `anthropic` provider kinds is essential for configuring the correct API endpoints, model names, and message formats, as each kind translates internal representations to distinct external schemas.

## Provider Registration and Kind Identification

The fundamental distinction begins at the registration level. In [`internal/provider/openai/openai.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/openai/openai.go), the package self-registers under the kind **"openai"** using the registry pattern:

```go
provider.Register("openai", New)

```

Conversely, the Anthropic provider registers under the kind **"anthropic"** in its corresponding initialization file. The configuration validator in [`internal/diagnose.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/diagnose.go) explicitly recognizes both kinds as valid entries, rejecting any provider configuration that does not specify either `"openai"` or `"anthropic"` as the `Kind` field.

## API Endpoint and Protocol Handling

Each provider kind targets a different base URL and protocol specification. The `openai` provider defaults to `https://api.openai.com/v1` and implements the standard OpenAI chat completions format, detecting the hostname using `strings.EqualFold(u.Hostname(), "api.openai.com")` in the host resolution logic.

The `anthropic` provider targets `https://api.anthropic.com/v1` and implements Anthropic's native message format. While both providers accept a custom `BaseURL` for proxy or gateway scenarios, the internal protocol negotiation differs: the OpenAI provider sets `protocol = "openai"` whereas the Anthropic provider uses `protocol = "anthropic"` to determine message serialization strategy and capability mapping.

## Message Format and Schema Translation

Despite sharing an internal `Message` representation, the providers translate to service-specific schemas. The `openai` provider converts messages to the standard OpenAI JSON format with fields like `role`, `content`, and `tool_calls`, handling OpenAI-style function calling and streaming deltas.

The `anthropic` provider converts the same internal structures to Anthropic's request schema, which uses distinct field naming for tool interactions—specifically `tool_use` and `tool_result` blocks that differ in nesting and structure from OpenAI's format. This translation layer ensures that tool calling and multi-turn conversations work correctly with Claude models while maintaining API consistency internally.

## Token Accounting and Usage Metrics

Token counting conventions differ significantly between the two APIs. The `openai` provider expects and normalizes OpenAI's `prompt_tokens`, `completion_tokens`, and `total_tokens` fields, mapping them to internal accounting structures.

The `anthropic` provider processes Anthropic's `input_tokens` and `output_tokens` fields, performing the same normalization but accounting for the different terminology and granularity that Anthropic's API returns. Both providers ultimately expose unified token counts to the application layer, but the underlying field extraction reflects each service's native terminology.

## Error Handling and Streaming Implementation

Error prefixes help identify the source provider during debugging. The OpenAI provider emits errors prefixed with `openai:`, such as `openai: network: ...`, while the Anthropic provider uses the `anthropic:` prefix.

Both providers support streaming responses, but implementation details vary. The `openai` provider implements Server-Sent Events (SSE) parsing compatible with OpenAI's streaming format, yielding partial `Delta` objects. The `anthropic` provider implements a separate streaming loop that respects Anthropic's chunk format and stream boolean parameters. While the internal consumer receives the same streaming interface, the underlying byte parsing accommodates each service's specific server-sent event structure.

## Configuration Examples

To configure the OpenAI provider for GPT-4 or compatible models:

```go
cfg := provider.Config{
    Name:    "openai",
    Kind:    "openai",
    APIKey:  "sk-your-openai-key",
    BaseURL: "https://api.openai.com/v1",
    Model:   "gpt-4o",
}
client := provider.New(cfg)

```

For Claude models via the Anthropic provider:

```go
cfg := provider.Config{
    Name:    "anthropic",
    Kind:    "anthropic",
    APIKey:  "anth-your-api-key",
    BaseURL: "https://api.anthropic.com/v1",
    Model:   "claude-3-opus-20240229",
}
client := provider.New(cfg)

```

Both configurations use the same constructor pattern but require the correct `Kind` field to instantiate the appropriate protocol handler defined in [`internal/provider/openai/openai.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/openai/openai.go) or [`internal/provider/anthropic/anthropic.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/anthropic/anthropic.go). After initialization, both clients expose identical `Chat` methods, hiding the underlying API differences.

## Summary

- The `openai` provider implements the OpenAI-compatible chat completions protocol, while `anthropic` implements Anthropic's native Claude API.
- Both register distinct provider kinds in the internal registry and validate against supported kinds in [`internal/diagnose.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/diagnose.go).
- Message translation differs: OpenAI uses `tool_calls` format, while Anthropic uses `tool_use` and `tool_result` blocks.
- Token fields vary: OpenAI uses `prompt_tokens`/`completion_tokens`; Anthropic uses `input_tokens`/`output_tokens`.
- Error prefixes distinguish providers: `openai:` versus `anthropic:`.
- Streaming implementations handle service-specific SSE formats but expose a unified interface to the application.
- Configuration requires matching the `Kind` field to the target API, with both supporting custom `BaseURL` values for proxy deployments.

## Frequently Asked Questions

### Can I use an OpenAI-compatible proxy with the anthropic provider?

No. The `anthropic` provider specifically implements Anthropic's message schema and token accounting. While both providers accept custom `BaseURL` values, the `anthropic` provider expects Anthropic-specific response structures including `input_tokens` and `tool_use` blocks. Using an OpenAI-compatible proxy requires the `openai` provider kind, which understands the OpenAI chat completions format and translates requests accordingly.

### How does token counting differ between the two providers?

The OpenAI provider extracts `prompt_tokens` and `completion_tokens` from responses and calculates `total_tokens` accordingly. The Anthropic provider extracts `input_tokens` and `output_tokens` directly from Anthropic's usage fields. Both normalize these values to the internal accounting format, but the source fields and calculation methods reflect each API's native terminology as implemented in [`internal/provider/provider.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/provider.go).

### Which provider kind should I use for Claude models?

Use the `anthropic` provider kind for all Claude models (Claude 2, Claude 3 Opus, Sonnet, etc.). This ensures correct message formatting, proper handling of Anthropic's extended thinking capabilities, and accurate token counting. Attempting to use Claude models with the `openai` provider kind will result in schema mismatches and API errors because the request serialization logic differs between the two implementations.

### Are tool calling capabilities identical across both provider kinds?

While both providers support function calling, the internal representation differs significantly. The `openai` provider handles OpenAI-style `tool_calls` and `function` objects, while the `anthropic` provider manages Anthropic's `tool_use` and `tool_result` message types. DeepSeek-Reasonix abstracts these differences automatically, but the underlying API structures remain distinct as implemented in [`internal/provider/openai/openai.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/openai/openai.go) and [`internal/provider/anthropic/anthropic.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/anthropic/anthropic.go).