跳转至

Core 模块

pkg/core 模块是整个 GoChat 项目的基石。它的设计目的在于定义一套与具体 LLM 厂商完全解耦的领域模型与核心接口。通过这套标准化抽象,上层业务逻辑能够在不修改代码的情况下无缝切换不同的底层模型引擎(如从 OpenAI 切换到 Anthropic 或本地的 Ollama)。

内部架构与组件关系

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 : 依赖
    Client ..> Option : 依赖
    Client ..> Response : 返回
    Client ..> Stream : 返回
    Message *-- ContentBlock

核心接口与数据结构

Client 接口

所有具体厂商的客户端(如 openai.Clientanthropic.Client)均实现了此接口。

  • Chat: 执行阻塞的对话请求,一次性返回完整响应。
  • ChatStream: 发起流式请求,返回一个 Stream 迭代器对象。

Message 与 ContentBlock

基于多模态设计的消息载体。

  • Message: 定义了角色 (user, assistant, system, tool) 及其内容。
  • ContentBlock: 组成消息的最小单元,通过 ContentType 区分是普通文本 (text)、图片数据 (image) 还是深度思考内容 (thinking)。

选项模式 (Functional Options)

所有的配置调整(如指定 TemperatureMaxTokens、挂载 Tools 等)均通过 core.Option 闭包函数实现。这样保障了 Client 接口的极度精简,同时赋予了接口无限的扩展能力。

详细使用方法

package main

import (
    "context"
    "fmt"
    "github.com/DotNetAge/gochat/pkg/core"
)

// 假设我们有一个已实例化的 client (实现了 core.Client)
func interactWithModel(client core.Client) {
    // 1. 构建多模态/普通消息
    msg := core.NewUserMessage("请分析一下当前的局势。")

    // 2. 利用 Option 传入复杂的执行参数
    opts := []core.Option{
        core.WithTemperature(0.5),
        core.WithMaxTokens(2000),
        core.WithThinking(1024), // 启用 o1/DeepSeek 的深度思考模式
        core.WithSystemPrompt("你是一名客观的分析师"),
    }

    // 3. 调用核心接口
    resp, err := client.Chat(context.Background(), []core.Message{msg}, opts...)
    if err != nil {
        panic(err)
    }

    fmt.Println("回复:", resp.Content)
    fmt.Printf("消耗的 Tokens: %d\n", resp.Usage.TotalTokens)
}

实现基本原理与设计优点

  1. 结构化网络错误与指数退避:在 errors.goretry.go 中,定义了标准的 ErrorType。结合 ExponentialBackoff,实现了内置的韧性容错处理,使得偶发的网络抖动不会直接导致进程崩溃。
  2. 面向未来多模态与 Tool Calling:摒弃了简单的 string 传输,通过结构化的 Message 树实现了工具调用(Function Calling)的无缝集成。
  3. 安全流迭代 (Stream Iterator):封装了 Go 通道,暴露了 Next()Event() 的迭代器模式,防止开发者处理 channel 时可能引发的死锁和 goroutine 泄漏。