MCPcopy Index your code
hub / github.com/cohesion-org/deepseek-go

github.com/cohesion-org/deepseek-go @v1.4.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.4.0 ↗ · + Follow
281 symbols 896 edges 60 files 180 documented · 64% 4 cross-repo links
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Deepseek-Go

MIT License Go Report Card

Deepseek-Go is a Go-based API client for the Deepseek platform. It provides a clean and type-safe interface to interact with Deepseek's AI features, including chat completions with streaming, token usage tracking, and more.

Installation

go get github.com/cohesion-org/deepseek-go

deepseek-go currently uses go 1.26.0

Features

  • Chat Completion: Send chat messages and receive responses from DeepSeek's V4 models with streaming support.
  • Anthropic API: Full Anthropic-compatible endpoint support via NewAnthropicClient with content blocks, tool use, and streaming.
  • Thinking Mode: Chain-of-thought reasoning with configurable reasoning_effort ("high" / "max").
  • Tool Calling: Function calling with standard and strict mode (beta, with automatic /beta routing).
  • FIM Completion: Fill-in-the-Middle completions for code generation, with streaming.
  • JSON Output: Structured JSON output with schema extraction via ResponseFormat.
  • External Providers: OpenRouter, Azure, Ollama, and any OpenAI-compatible endpoint.
  • Balance & Models: Check account balance and list available models.
  • Token Estimation: Client-side token counting for Chinese and English text.
  • Modular Design: Reusable components for building, sending, and handling requests and responses.
  • MIT License: Open-source and free for both personal and commercial use.

The recent gain in popularity and cybersecurity issues Deepseek has seen makes for many problems while using the API. Please refer to the status page for the current status.

Getting Started

Here's a quick example of how to use the library:

Prerequisites

Before using the library, ensure you have: - A valid Deepseek API key. - Go installed on your system.

Supported Models

  • deepseek-v4-flash (current)
    Flagship model with 1M context, 384K max output. Supports thinking mode, tool calls, JSON output, FIM, and prefix completion.

Usage: Model: deepseek.DeepSeekV4Flash

  • deepseek-v4-pro (current)
    Premium reasoning model with 1M context, 384K max output. Best for complex reasoning and agent tasks.

Usage: Model: deepseek.DeepSeekV4Pro

  • deepseek-chat (deprecated, sunset 2026/07/24)
    Maps to deepseek-v4-flash non-thinking mode.

Usage: Model: deepseek.DeepSeekV4Flash — emits a deprecation warning to stderr.

  • deepseek-reasoner (deprecated, sunset 2026/07/24)
    Maps to deepseek-v4-flash thinking mode.

Usage: Model: deepseek.DeepSeekReasoner — emits a deprecation warning to stderr.

External Providers

  • Azure DeepSeekR1
    DeepSeek R1 provided by Azure.

    Usage: Model: deepseek.AzureDeepSeekR1

  • OpenRouter

    OpenRouter provides access to DeepSeek R1 and distill models.

    Usage: Model: deepseek.OpenRouterDeepSeekR1 (and other OpenRouterDeepSeek* constants)

  • Ollama Support

    Please read Ollama Support for more info about this!

Chat

Example for chatting with deepseek

Even more examples are avilable here

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    deepseek "github.com/cohesion-org/deepseek-go"

)

func main() {
    // Set up the Deepseek client
    client := deepseek.NewClient("") // Empty API key triggers env lookup for "DEEPSEEK_API_KEY"

    // Create a chat completion request
    request := &deepseek.ChatCompletionRequest{
        Model: deepseek.DeepSeekV4Flash,
        Messages: []deepseek.ChatCompletionMessage{
            {Role: deepseek.ChatMessageRoleSystem, Content: "Answer every question using slang."},
            {Role: deepseek.ChatMessageRoleUser, Content: "Which is the tallest mountain in the world?"},
        },
    }

    // Send the request and handle the response
    ctx := context.Background()
    response, err := client.CreateChatCompletion(ctx, request)
    if err != nil {
        log.Fatalf("error: %v", err)
    }

    // Print the response
    fmt.Println("Response:", response.Choices[0].Message.Content)
}

More Examples:

Using external providers such as Azure or OpenRouter.

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    deepseek "github.com/cohesion-org/deepseek-go"
)

func main() {

    // Azure
    baseURL := "https://models.inference.ai.azure.com/"

    // OpenRouter
    // baseURL := "https://openrouter.ai/api/v1/"

    // Set up the Deepseek client
    client := deepseek.NewClient(os.Getenv("PROVIDER_API_KEY"), baseURL)

    // Create a chat completion request
    request := &deepseek.ChatCompletionRequest{
        Model: deepseek.AzureDeepSeekR1,
        // Model: deepseek.OpenRouterDeepSeekR1,
        Messages: []deepseek.ChatCompletionMessage{
            {Role: deepseek.ChatMessageRoleUser, Content: "Which is the tallest mountain in the world?"},
        },
    }

    // Send the request and handle the response
    ctx := context.Background()
    response, err := client.CreateChatCompletion(ctx, request)
    if err != nil {
        log.Fatalf("error: %v", err)
    }

    // Print the response
    fmt.Println("Response:", response.Choices[0].Message.Content)
}

Note: If you wish to use other providers that are not supported by us, you can simply extend the baseURL(as shown above), and pass the name of your model as a string to Model while creating the ChatCompletionRequest. This will work as long as the provider follows the same API structure as Azure or OpenRouter.

Sending other params like Temp, Stop

<strong> You just need to extend the ChatCompletionMessage with the supported parameters. </strong>
    request := &deepseek.ChatCompletionRequest{
        Model: deepseek.DeepSeekV4Flash,
        Messages: []deepseek.ChatCompletionMessage{
            {Role: deepseek.ChatMessageRoleUser, Content: "What is the meaning of deepseek"},
            {Role: deepseek.ChatMessageRoleSystem, Content: "Answer every question using slang"},
        },
        Temperature: 1.0,
        Stop:        []string{"yo", "hello"},
        ResponseFormat: &deepseek.ResponseFormat{
            Type: "text",
        },
    }

Multi-Conversation with Deepseek.

package deepseek_examples

import (
    "context"
    "log"

    deepseek "github.com/cohesion-org/deepseek-go"
)

func MultiChat() {
    client := deepseek.NewClient("DEEPSEEK_API_KEY")
    ctx := context.Background()

    messages := []deepseek.ChatCompletionMessage{{
        Role:    deepseek.ChatMessageRoleUser,
        Content: "Who is the president of the United States? One word response only.",
    }}

    // Round 1: First API call
    response1, err := client.CreateChatCompletion(ctx, &deepseek.ChatCompletionRequest{
        Model:    deepseek.DeepSeekV4Flash,
        Messages: messages,
    })
    if err != nil {
        log.Fatalf("Round 1 failed: %v", err)
    }

    response1Message, err := deepseek.MapMessageToChatCompletionMessage(response1.Choices[0].Message)
    if err != nil {
        log.Fatalf("Mapping to message failed: %v", err)
    }
    messages = append(messages, response1Message)

    log.Printf("The messages after response 1 are: %v", messages)
    // Round 2: Second API call
    messages = append(messages, deepseek.ChatCompletionMessage{
        Role:    deepseek.ChatMessageRoleUser,
        Content: "Who was the one in the previous term.",
    })

    response2, err := client.CreateChatCompletion(ctx, &deepseek.ChatCompletionRequest{
        Model:    deepseek.DeepSeekV4Flash,
        Messages: messages,
    })
    if err != nil {
        log.Fatalf("Round 2 failed: %v", err)
    }

    response2Message, err := deepseek.MapMessageToChatCompletionMessage(response2.Choices[0].Message)
    if err != nil {
        log.Fatalf("Mapping to message failed: %v", err)
    }
    messages = append(messages, response2Message)
    log.Printf("The messages after response 1 are: %v", messages)

}

Chat with Streaming

package main

import (
    "context"
    "errors"
    "fmt"
    "io"
    "log"
    "os"

    deepseek "github.com/cohesion-org/deepseek-go"
)

func main() {
    client := deepseek.NewClient(os.Getenv("DEEPSEEK_API_KEY"))
    request := &deepseek.StreamChatCompletionRequest{
        Model: deepseek.DeepSeekV4Flash,
        Messages: []deepseek.ChatCompletionMessage{
            {Role: deepseek.ChatMessageRoleUser, Content: "Just testing if the streaming feature is working or not!"},
        },
        Stream: true,
    }
    ctx := context.Background()

    stream, err := client.CreateChatCompletionStream(ctx, request)
    if err != nil {
        log.Fatalf("ChatCompletionStream error: %v", err)
    }
    var fullMessage string
    defer stream.Close()
    for {
        response, err := stream.Recv()
        if errors.Is(err, io.EOF) {
            fmt.Println("\nStream finished")
            break
        }
        if err != nil {
            fmt.Printf("\nStream error: %v\n", err)
            break
        }
        for _, choice := range response.Choices {
            fullMessage += choice.Delta.Content // Accumulate chunk content
            log.Println(choice.Delta.Content)
        }
    }
    log.Println("The full message is: ", fullMessage)
}

Get the balance(s) of the user.

package main

import (
    "context"
    "log"
    "os"

    deepseek "github.com/cohesion-org/deepseek-go"
)

func main() {
    client := deepseek.NewClient(os.Getenv("DEEPSEEK_API_KEY"))
    ctx := context.Background()
    balance, err := deepseek.GetBalance(client, ctx)
    if err != nil {
        log.Fatalf("Error getting balance: %v", err)
    }

    if balance == nil {
        log.Fatalf("Balance is nil")
    }

    if len(balance.BalanceInfos) == 0 {
        log.Fatalf("No balance information returned")
    }
    log.Printf("%+v\n", balance)
}

Get the list of All the models the API supports right now. This is different from what deepseek-go might support.

func ListModels() {
    client := deepseek.NewClient("DEEPSEEK_API_KEY")
    ctx := context.Background()
    models, err := deepseek.ListAllModels(client, ctx)
    if err != nil {
        t.Fatalf("Error listing models: %v", err)
    }
    fmt.Printf("\n%+v\n", models)
}

Get the estimated tokens for the request.

This is adpated from the Deepseek's estimation.

func Estimation() {
    client := deepseek.NewClient("DEEPSEEK_API_KEY"))
    request := &deepseek.ChatCompletionRequest{
        Model: deepseek.DeepSeekV4Flash,
        Messages: []deepseek.ChatCompletionMessage{
            {Role: deepseek.ChatMessageRoleSystem, Content: "Just respond with the time it might take you to complete this request."},
            {Role: deepseek.ChatMessageRoleUser, Content: "The text to evaluate the time is: Who is the greatest singer in the world?"},
        },
    }
    ctx := context.Background()

    tokens := deepseek.EstimateTokensFromMessages(request)
    fmt.Println("Estimated tokens for the request is: ", tokens.EstimatedTokens)
    response, err := client.CreateChatCompletion(ctx, request)

    if err != nil {
        log.Fatalf("error: %v", err)
    }

    fmt.Println("Response:", response.Choices[0].Message.Content, "\nActual Tokens Used:", response.Usage.PromptTokens)
}

JSON mode for JSON extraction

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    deepseek "github.com/cohesion-org/deepseek-go"
)

func JsonMode() {
    // Book represents a book in a library
    type Book struct {
        ISBN            string `json:"isbn"`
        Title           string `json:"title"`
        Author          string `json:"author"`
        Genre           string `json:"genre"`
        PublicationYear int    `json:"publication_year"`
        Available       bool   `json:"available"`
    }

    type Books struct {
        Books []Book `json:"books"`
    }
    // Creating a new client using OpenRouter; you can use your own API key and endpoint.
    client := deepseek.NewClient(
        os.Getenv("OPENROUTER_API_KEY"),
        "https://openrouter.ai/api/v1/",
    )
    ctx := context.Background()

    prompt := `Provide book details in JSON format. Generate 10 JSON objects. 
    Please provide the JSON in the following format: { "books": [...] }
    Example: {"isbn": "978-0321765723", "title": "The Lord of the Rings", "author": "J.R.R. Tolkien", "genre": "Fantasy", "publication_year": 1954, "available": true}`

    resp, err := client.CreateChatCompletion(ctx, &deepseek.ChatCompletionRequest{
        Model: "mistralai/codestral-2501", // Or another suitable model
        Messages: []deepseek.ChatCompletionMessage{
            {Role: deepseek.ChatMessageRoleUser, Content: prompt},
        },
        JSONMode: true,
    })
    if err != nil {
        log.Fatalf("Failed to create chat completion: %v", err)
    }
    if resp == nil || len(resp.Choices) == 0 {
        log.Fatal("No response or choices found")
    }

    log.Printf("Response: %s", resp.Choices[0].Message.Content)

    extractor := deepseek.NewJSONExtractor(nil)
    var books Books
    if err := extractor.ExtractJSON(resp, &books); err != nil {
        log.Fatal(err)
    }

    fmt.Printf("\n\nExtracted Books: %+v\n\n", books)

    // Basic validation to check if we got some books
    if len(books.Books) == 0 {
        log.Print("No books were extracted from the JSON response")
    } else {
        fmt.Println("Successfully extracted", len(books.Books), "books.")
    }

}

You can see more examples inside the examples folder.

Add more settings to your client with NewClientWithOptions

```go package main

import ( "fmt" "log" "time" "github.com/cohesion-org/deepseek-go" )

func main() { client, err := deepseek.NewClientWithOptions("your-api-key", deepseek.WithBaseURL("https://custom-api.com/"), deepseek.WithTimeout(10*time.Second), ) if err != nil { log.Fatalf("Error creating client: %v", err) }

fmt.Printf("Client initialized with BaseURL: %s and Timeout: %v\n", client.BaseURL, client.Timeout)

} ```

Using local model servers without an API key:

By default, `NewClientWit

Extension points exported contracts — how you extend this code

ChatCompletionStream (Interface)
ChatCompletionStream is an interface for receiving streaming chat completion responses. [3 implementers]
chat_stream.go
AnthropicStream (Interface)
--------------------------------------------------------------------------- Streaming types ---------------------------- [3 …
anthropic.go
FIMChatCompletionStream (Interface)
FIMChatCompletionStream is an interface for receiving streaming chat completion responses. [1 implementers]
fim.go
AuthedRequestBuilder (Interface)
AuthedRequestBuilder is an interface for building authenticated requests. [1 implementers]
utils/requestBuilder.go
HTTPDoer (Interface)
HTTPDoer is an interface for the Do method of http.Client
config.go
Option (FuncType)
Option configures a Client instance
config.go

Core symbols most depended-on inside this repo

Close
called by 57
anthropic.go
Error
called by 34
errors.go
CreateChatCompletion
called by 29
client.go
NewRequestBuilder
called by 20
utils/requestBuilder.go
SetBaseURL
called by 16
utils/requestBuilder.go
SetPath
called by 16
utils/requestBuilder.go
Recv
called by 12
anthropic.go
HandleAPIError
called by 12
errors.go

Shape

Function 149
Struct 75
Method 47
Interface 5
TypeAlias 4
FuncType 1

Languages

Go100%

Modules by API surface

anthropic.go25 symbols
internal/testutil/mock_api.go23 symbols
chat_stream.go16 symbols
responseHandler.go15 symbols
utils/requestBuilder.go13 symbols
ollama.go12 symbols
config.go12 symbols
image.go11 symbols
fim.go11 symbols
json.go9 symbols
chat.go9 symbols
json_test.go7 symbols

For agents

$ claude mcp add deepseek-go \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page