Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
wengchaoxi committed Mar 9, 2024
1 parent 8a46194 commit ac7f117
Show file tree
Hide file tree
Showing 10 changed files with 656 additions and 0 deletions.
100 changes: 100 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,101 @@
# Go Anthropic

**English** | [简体中文](./README.zh-CN.md)

Anthropic SDK implemented in Go, supporting models such as Claude 2.1, Claude 3 (supports sending images), etc.

## Installation

```
go get github.com/wengchaoxi/go-anthropic
```

## Usage

By default, it will fetch `ANTHROPIC_API_KEY` and `ANTHROPIC_BASE_URL` from the environment variables.

```go
package main

import (
"fmt"

"github.com/wengchaoxi/go-anthropic"
)

func main() {
cli := anthropic.NewClient()
// cli := anthropic.NewClient(anthropic.ClientOptions{
// ApiKey: os.Getenv("ANTHROPIC_API_KEY"),
// BaseUrl: anthropic.DEFAULT_ANTHROPIC_BASE_URL,
// })

resp, err := cli.CreateMessages(anthropic.MessagesRequest{
Model: anthropic.MODEL_CLAUDE_3_SONNET, // or `MODEL_CLAUDE_3_OPUS`、`MODEL_CLAUDE_2_1`
Messages: []anthropic.Message{{
Role: "user",
Content: []anthropic.MessageContent{
&anthropic.MessageContentText{
Type: "text",
Text: "Hello Claude!",
},
}},
},
MaxTokens: 1024,
})
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(resp.Content[0].Text)
}
```

## Streaming Responses

```go
package main

import (
"fmt"

"github.com/wengchaoxi/go-anthropic"
)

func main() {
cli := anthropic.NewClient()
// cli := anthropic.NewClient(anthropic.ClientOptions{
// ApiKey: os.Getenv("ANTHROPIC_API_KEY"),
// BaseUrl: anthropic.DEFAULT_ANTHROPIC_BASE_URL,
// })

stream, _ := cli.CreateMessagesStream(anthropic.MessagesRequest{
Model: anthropic.MODEL_CLAUDE_3_SONNET, // or `MODEL_CLAUDE_3_OPUS`、`MODEL_CLAUDE_2_1`
Messages: []anthropic.Message{{
Role: "user",
Content: []anthropic.MessageContent{
&anthropic.MessageContentText{
Type: "text",
Text: "Hello Claude!",
},
}},
},
MaxTokens: 1024,
Stream: true,
})
defer stream.Close()
for {
resp, err := stream.Recv()
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(resp.Delta.Text)
}
}
```

## References

- https://docs.anthropic.com/claude/reference/messages_post
- https://docs.anthropic.com/claude/reference/messages-streaming
101 changes: 101 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Go Anthropic

**简体中文** | [English](./README.md)

用 Go 实现的 Anthropic SDK,支持:Claude 2.1、Claude 3(支持发送图片)等模型。

## 安装

```
go get github.com/wengchaoxi/go-anthropic
```

## 简单使用

> 默认会从环境变量中获取 `ANTHROPIC_API_KEY``ANTHROPIC_BASE_URL`
```go
package main

import (
"fmt"

"github.com/wengchaoxi/go-anthropic"
)

func main() {
cli := anthropic.NewClient()
// cli := anthropic.NewClient(anthropic.ClientOptions{
// ApiKey: os.Getenv("ANTHROPIC_API_KEY"),
// BaseUrl: anthropic.DEFAULT_ANTHROPIC_BASE_URL,
// })

resp, err := cli.CreateMessages(anthropic.MessagesRequest{
Model: anthropic.MODEL_CLAUDE_3_SONNET, // 或者 `MODEL_CLAUDE_3_OPUS`、`MODEL_CLAUDE_2_1`
Messages: []anthropic.Message{{
Role: "user",
Content: []anthropic.MessageContent{
&anthropic.MessageContentText{
Type: "text",
Text: "Hello Claude!",
},
}},
},
MaxTokens: 1024,
})
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(resp.Content[0].Text)
}
```

## 流式响应

```go
package main

import (
"fmt"

"github.com/wengchaoxi/go-anthropic"
)

func main() {
cli := anthropic.NewClient()
// cli := anthropic.NewClient(anthropic.ClientOptions{
// ApiKey: os.Getenv("ANTHROPIC_API_KEY"),
// BaseUrl: anthropic.DEFAULT_ANTHROPIC_BASE_URL,
// })

stream, _ := cli.CreateMessagesStream(anthropic.MessagesRequest{
Model: anthropic.MODEL_CLAUDE_3_SONNET, // 或者 `MODEL_CLAUDE_3_OPUS`、`MODEL_CLAUDE_2_1`
Messages: []anthropic.Message{{
Role: "user",
Content: []anthropic.MessageContent{
&anthropic.MessageContentText{
Type: "text",
Text: "Hello Claude!",
},
}},
},
MaxTokens: 1024,
Stream: true,
})
defer stream.Close()
for {
resp, err := stream.Recv()
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(resp.Delta.Text)
}
}
```

## 相关文档

- https://docs.anthropic.com/claude/reference/messages_post
- https://docs.anthropic.com/claude/reference/messages-streaming
115 changes: 115 additions & 0 deletions anthropic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package anthropic

// See: https://docs.anthropic.com/claude/reference/messages_post

const (
// See: https://docs.anthropic.com/claude/docs/models-overview#model-recommendations
MODEL_CLAUDE_2_1 = "claude-2.1"
MODEL_CLAUDE_3_SONNET = "claude-3-sonnet-20240229"
MODEL_CLAUDE_3_OPUS = "claude-3-opus-20240229"
// MODEL_CLAUDE_3_HAIKU = "claude-3-haiku-20240229"
)

// MessageContentText | MessageContentFile
type MessageContent interface {
GetType() string
}

type MessageContentText struct {
Type string `json:"type"`
Text string `json:"text"`
}

func (m *MessageContentText) GetType() string {
return m.Type
}

type MessageContentFileSource struct {
Type string `json:"type"`
MediaType string `json:"media_type"`
Data string `json:"data"`
}

type MessageContentFile struct {
Type string `json:"type"`
Source MessageContentFileSource `json:"source,omitempty"`
}

func (m *MessageContentFile) GetType() string {
return m.Type
}

type Message struct {
Role string `json:"role"`
Content []MessageContent `json:"content"`
// Content string `json:"content"`
}

type MessagesRequest struct {
Model string `json:"model"`
Messages []Message `json:"messages"`
System string `json:"system,omitempty"`
MaxTokens int `json:"max_tokens"`
Metadata struct {
UserID string `json:"user_id"`
} `json:"metadata,omitempty"`
StopSequences []string `json:"stop_sequences,omitempty"`
Stream bool `json:"stream,omitempty"`
Temperature float64 `json:"temperature,omitempty"`
TopP float64 `json:"top_p,omitempty"`
TopK int `json:"top_k,omitempty"`
}

type MessagesResponse struct {
ID string `json:"id"`
Type string `json:"type"`
Role string `json:"role"`
Content []MessageContentText `json:"content"`
Model string `json:"model"`
StopReaon string `json:"stop_reason"`
StopSequence string `json:"stop_sequence"`
Usage struct {
InputTokens int `json:"input_tokens"`
OutputTokens int `json:"output_tokens"`
} `json:"usage"`
}

type MessagesStreamResponseContentBlock struct {
Type string `json:"type"`
Text string `json:"text"`
}

type MessagesStreamResponseDelta struct {
Type string `json:"type"`
Text string `json:"text"`
StopReaon string `json:"stop_reason"`
StopSequence string `json:"stop_sequence"`
Usage struct {
InputTokens int `json:"input_tokens"`
OutputTokens int `json:"output_tokens"`
} `json:"usage"`
}

type MessagesStream struct {
*MessagesStreamReader
}

type MessagesStreamResponse struct {
Type string `json:"type"`
Message MessagesResponse `json:"message,omitempty"`
Index int `json:"index,omitempty"`
ContentBlock MessagesStreamResponseContentBlock `json:"content_block,omitempty"`
Delta MessagesStreamResponseDelta `json:"delta,omitempty"`
Error struct {
Type string `json:"type"`
Message string `json:"message"`
} `json:"error,omitempty"`
}

type MessagesResponseError struct {
Type string `json:"type"`
Error struct {
Type string `json:"type"`
Message string `json:"message"`
} `json:"error"`
}
Loading

0 comments on commit ac7f117

Please sign in to comment.