Files
tm_back/pkg/glm/USAGE.md
T
n.nakhostin a5d3a94c97 Add GLM SDK Implementation
- Introduced a new GLM SDK for interacting with the GLM (Zhipu AI) API, designed for chat completions and text generation tasks.
- Implemented core components including Client, Service, and SDK layers following Clean Architecture principles.
- Added configuration management, error handling, and structured logging for improved usability and maintainability.
- Included comprehensive documentation and usage examples to facilitate integration and understanding of the SDK's functionality.
- Enhanced the API with features such as chat completion, streaming responses, and model management, ensuring robust interaction with the GLM service.
2025-11-04 16:09:44 +03:30

7.3 KiB

GLM SDK Usage Guide

Matching the Provided Curl Request

The SDK can replicate the exact curl request provided:

package main

import (
    "context"
    "fmt"
    "log"
    "tm/pkg/glm"
    "tm/pkg/logger"
)

func main() {
    config := &glm.Config{
        BaseURL: "https://api.z.ai",
        APIKey:  "4e267ac7897f4a789cacb3dbee15f312.coJtK3397qFv16x5",
    }

    logger := logger.NewLogger()
    sdk, err := glm.New(config, logger)
    if err != nil {
        log.Fatal(err)
    }

    req := &glm.ChatCompletionRequest{
        Model: "glm-4.5",
        Messages: []glm.Message{
            {
                Role:    glm.MessageRoleSystem,
                Content: "You are a high-precision translator specializing in professional tender documents. Always respond with only the translated English text — no explanations, notes, or markdown formatting.",
            },
            {
                Role:    glm.MessageRoleUser,
                Content: "Translate the following text from Swedish to English accurately and professionally:\n\"IT-stöd för projekt- och portföljstyrning\"",
            },
        },
        Thinking: &glm.Thinking{
            Type: "false",
        },
        MaxTokens:        4096,
        TopP:             1,
        FrequencyPenalty: 0,
        PresencePenalty:  0,
    }

    ctx := context.Background()
    resp, err := sdk.ChatCompletion(ctx, req)
    if err != nil {
        log.Fatal(err)
    }

    if len(resp.Choices) > 0 {
        fmt.Println(resp.Choices[0].Message.Content)
    }
}

Using the Translate Convenience Method

For the specific translation use case:

translated, err := sdk.Translate(ctx, "IT-stöd för projekt- och portföljstyrning", "Swedish", "English")
if err != nil {
    log.Fatal(err)
}
fmt.Println(translated) // Output: "IT support for project and portfolio management"

Custom Translation Options

For more control over translation parameters:

opts := &glm.TranslateOptions{
    Model:            "glm-4.5",
    MaxTokens:        1024,
    Temperature:      0.1,  // Very low for consistent translations
    FrequencyPenalty: 0.2,
    PresencePenalty:  0.2,
    EnableThinking:   &[]bool{false}[0],
}

translated, err := sdk.TranslateWithOptions(ctx, "IT-stöd för projekt- och portföljstyrning", "Swedish", "English", opts)
if err != nil {
    log.Fatal(err)
}
fmt.Println(translated)

Advanced Configuration

GLM SDK Configuration

config := &glm.Config{
    BaseURL:                "https://api.z.ai",
    APIKey:                 "your-api-key",
    Timeout:                300 * time.Second,
    RetryAttempts:          3,
    RetryDelay:             2 * time.Second,
    EnableLogging:          true,
    DefaultModel:           "glm-4.5",
    DefaultMaxTokens:       4096,
    DefaultTopP:            1.0,
    DefaultTemperature:     0.7,
    DefaultFrequencyPenalty: 0.0,
    DefaultPresencePenalty:  0.0,
    EnableStreaming:        false,
    EnableThinking:         false,

    // Translation-specific configuration
    TranslationMaxTokens:        2048,
    TranslationTemperature:      0.3,
    TranslationFrequencyPenalty: 0.1,
    TranslationPresencePenalty:  0.1,
    TranslationEnableThinking:   false,
}

Bootstrap Configuration (Application Level)

Configure translation parameters via environment variables in your application bootstrap:

// cmd/worker/bootstrap/config.go
type GLMConfig struct {
    // ... basic GLM settings ...

    // Translation options configured via environment variables
    TranslateOptions TranslateOptions
}

type TranslateOptions struct {
    MaxTokens        int     `env:"GLM_TRANSLATE_MAX_TOKENS" default:"2048"`
    Temperature      float64 `env:"GLM_TRANSLATE_TEMPERATURE" default:"0.3"`
    FrequencyPenalty float64 `env:"GLM_TRANSLATE_FREQUENCY_PENALTY" default:"0.1"`
    PresencePenalty  float64 `env:"GLM_TRANSLATE_PRESENCE_PENALTY" default:"0.1"`
    EnableThinking   bool    `env:"GLM_TRANSLATE_ENABLE_THINKING" default:"false"`
}

Set these environment variables to customize translation behavior:

export GLM_TRANSLATE_MAX_TOKENS=1024
export GLM_TRANSLATE_TEMPERATURE=0.2
export GLM_TRANSLATE_FREQUENCY_PENALTY=0.2
export GLM_TRANSLATE_PRESENCE_PENALTY=0.2
export GLM_TRANSLATE_ENABLE_THINKING=false

Error Handling Examples

resp, err := sdk.ChatCompletion(ctx, req)
if err != nil {
    var glmErr *glm.Error
    if errors.As(err, &glmErr) {
        switch glmErr.Code {
        case glm.ErrCodeAuthentication:
            log.Printf("Authentication failed: %s", glmErr.Message)
            // Handle authentication error (e.g., refresh token)
        case glm.ErrCodeRateLimit:
            log.Printf("Rate limit exceeded: %s", glmErr.Message)
            // Implement backoff strategy
        case glm.ErrCodeInvalidRequest:
            log.Printf("Invalid request: %s", glmErr.Message)
            // Fix request parameters
        case glm.ErrCodeServerError:
            log.Printf("Server error: %s", glmErr.Message)
            // Retry or alert administrators
        default:
            log.Printf("Unknown error: %s", glmErr.Error())
        }
    } else {
        log.Printf("Non-GLM error: %v", err)
    }
    return
}

Streaming with Progress Tracking

var fullResponse strings.Builder

err := sdk.StreamChatCompletion(ctx, req, func(chunk *glm.StreamChatCompletionResponse) error {
    if len(chunk.Choices) > 0 {
        content := chunk.Choices[0].Delta.Content
        fmt.Print(content) // Print as it comes
        fullResponse.WriteString(content)
    }

    // Check for completion
    if len(chunk.Choices) > 0 && chunk.Choices[0].FinishReason != nil {
        fmt.Printf("\n\nFinished with reason: %s\n", *chunk.Choices[0].FinishReason)
    }

    return nil
})

if err != nil {
    log.Fatal(err)
}

fmt.Printf("Complete response: %s\n", fullResponse.String())

Integration with Tender Management System

// In your service layer
type TranslationService struct {
    glmSDK *glm.SDK
    logger logger.Logger
}

func NewTranslationService(glmSDK *glm.SDK, logger logger.Logger) *TranslationService {
    return &TranslationService{
        glmSDK: glmSDK,
        logger: logger,
    }
}

func (s *TranslationService) TranslateTenderDocument(ctx context.Context, text, sourceLang, targetLang string) (string, error) {
    s.logger.Info("Translating tender document", map[string]interface{}{
        "text_length": len(text),
        "source_lang": sourceLang,
        "target_lang": targetLang,
    })

    translated, err := s.glmSDK.Translate(ctx, text, sourceLang, targetLang)
    if err != nil {
        s.logger.Error("Translation failed", map[string]interface{}{
            "error": err.Error(),
        })
        return "", err
    }

    s.logger.Info("Translation completed", map[string]interface{}{
        "translated_length": len(translated),
    })

    return translated, nil
}

Health Monitoring

// Check service health
err := sdk.Health(ctx)
if err != nil {
    log.Printf("GLM service is unhealthy: %v", err)
    // Alert monitoring system
} else {
    log.Println("GLM service is healthy")
}

Model Management

// List available models
models, err := sdk.ListModels(ctx)
if err != nil {
    log.Fatal(err)
}

fmt.Println("Available models:")
for _, model := range models.Data {
    fmt.Printf("- %s (owned by %s)\n", model.ID, model.OwnedBy)
}