Core Module¶
The pkg/core module is the cornerstone of the entire GoChat project. Its design purpose is to define a set of domain models and core interfaces completely decoupled from specific LLM vendors. Through this standardized abstraction, upper-layer business logic can seamlessly switch between different underlying model engines (such as from OpenAI to Anthropic or local Ollama) without code modifications.
Architecture¶
classDiagram
direction TB
class Client {
<>
+Chat(ctx, messages, opts) Response
+ChatStream(ctx, messages, opts) Stream
}
class Message {
+Role string
+Content []ContentBlock
+ToolCalls []ToolCall
+TextContent() string
}
class ContentBlock {
+Type ContentType
+Text string
+MediaType string
+Data string
}
class Response {
+ID string
+Model string
+Content string
+ReasoningContent string
+Message Message
+FinishReason string
+Usage Usage
}
class Stream {
+Next() bool
+Event() StreamEvent
+Close() error
+Usage() Usage
+Text() string
}
class Option {
<>
}
class AuthManager {
+Login() error
+GetToken() OAuthToken
}
Client ..> Message : depends on
Client ..> Option : depends on
Client ..> Response : returns
Client ..> Stream : returns
Message *-- ContentBlock
Interfaces¶
Client Interface¶
All vendor-specific clients (such as openai.Client, anthropic.Client) implement this interface.
Chat: Executes a blocking chat request, returning the complete response at once.ChatStream: Initiates a streaming request, returning aStreamiterator object.
Message and ContentBlock¶
Message carriers based on multimodal design.
- Message: Defines the role (
user,assistant,system,tool) and its content. - ContentBlock: The smallest unit composing a message, distinguished by
ContentTypeas plain text (text), image data (image), or deep thinking content (thinking).
Functional Options Pattern¶
All configuration adjustments (such as specifying Temperature, MaxTokens, mounting Tools, etc.) are implemented through core.Option closure functions. This ensures the extreme simplicity of the Client interface while granting it unlimited expansion capability.
Detailed Usage Examples¶
package main
import (
"context"
"fmt"
"github.com/DotNetAge/gochat/pkg/core"
)
// Assume we have an instantiated client (implementing core.Client)
func interactWithModel(client core.Client) {
// 1. Build multimodal/plain messages
msg := core.NewUserMessage("Please analyze the current situation.")
// 2. Use Option to pass complex execution parameters
opts := []core.Option{
core.WithTemperature(0.5),
core.WithMaxTokens(2000),
core.WithThinking(1024), // Enable o1/DeepSeek's deep thinking mode
core.WithSystemPrompt("You are an objective analyst"),
}
// 3. Call core interface
resp, err := client.Chat(context.Background(), []core.Message{msg}, opts...)
if err != nil {
panic(err)
}
fmt.Println("Response:", resp.Content)
fmt.Printf("Tokens consumed: %d\n", resp.Usage.TotalTokens)
}
Implementation Principles and Design Advantages¶
- Structured Network Errors and Exponential Backoff: In
errors.goandretry.go, standardErrorTypeis defined. Combined withExponentialBackoff, built-in resilient fault tolerance is implemented, so that occasional network jitter does not directly cause process crashes. - Future-Proof Multimodal and Tool Calling: Abandoning simple
stringtransmission, structuredMessagetrees enable seamless integration of tool calling (Function Calling). - Safe Stream Iteration (Stream Iterator): Encapsulating Go channels, exposing the
Next()andEvent()iterator pattern, preventing deadlocks and goroutine leaks that developers might encounter when handlingchannel.