Message Types and Session History in Go

Message Types and Session History

Welcome back! In the previous lessons, you learned how to send a simple query to DeepSeek's language model and explored various model parameters to customize the AI's responses. Now, we will delve into the concept of message types and the importance of maintaining session history. These elements are crucial for creating dynamic and context-aware interactions with the AI, allowing your personal tutor to engage in more meaningful educational conversations.

Understanding Message Types

Before we dive into building and managing session history, it's important to understand the concept of message types and how a tutoring session history is structured. In a tutor-student interaction, messages are typically categorized by roles: system, user, and assistant. While we'll explore system prompts more thoroughly in a later lesson, remember that these primary roles help define the flow of dialogue and ensure the AI understands who is speaking at any given time.

DeepSeek expects the session history to be formatted as a slice of message structs, where each struct represents a message with two fields: Role and Content. Here's an example of what a simple tutoring session might look like in Go:

// Define a struct for a chat message
type Message struct {
    Role    string
    Content string
}

// Example session history
session := []Message{
    {Role: "user", Content: "Can you explain the theory of relativity?"},
    {Role: "assistant", Content: "Einstein's theory of relativity consists of two parts: special relativity and general relativity..."},
    {Role: "user", Content: "What practical applications does it have?"},
    {Role: "assistant", Content: "The theory of relativity has several practical applications including GPS systems, particle accelerators, and understanding astronomical phenomena."},
}

In this example, the session history consists of alternating messages between the user (the student) and the assistant (the AI tutor). Each message is stored with its respective role, providing context for the AI to generate appropriate educational responses. Understanding this structure is key to effectively managing tutoring sessions and ensuring that the AI can provide coherent and contextually relevant explanations.

Creating a Function to Handle Tutoring Sessions

To manage tutoring sessions effectively, we will create a function called SendQuery. This function will send the session history to the AI and receive explanations, allowing us to handle multiple interactions seamlessly. Here is the updated function and full example in Go:

package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "strings" // Import the strings package for capitalization
    "github.com/openai/openai-go"
    "github.com/openai/openai-go/option"
)

// Message struct for session history
type Message struct {
    Role    string
    Content string
}

// SendQuery sends the session history to DeepSeek and returns the AI's reply.
func SendQuery(client *openai.Client, session []Message) (string, error) {
    var messages []openai.ChatCompletionMessageParamUnion
    for _, m := range session {
        switch m.Role {
        case "user":
            messages = append(messages, openai.UserMessage(m.Content))
        case "assistant":
            messages = append(messages, openai.AssistantMessage(m.Content))
        case "system":
            messages = append(messages, openai.SystemMessage(m.Content))
        }
    }

    chatCompletion, err := client.Chat.Completions.New(
        context.Background(),
        openai.ChatCompletionNewParams{
            Messages: messages,
            Model:    "deepseek-ai/DeepSeek-V3",
        },
    )
    if err != nil {
        return "", err
    }
    if len(chatCompletion.Choices) == 0 {
        return "", nil
    }
    return chatCompletion.Choices[0].Message.Content, nil
}

// Helper function to capitalize the role
func capitalize(s string) string {
    if len(s) == 0 {
        return s
    }
    return strings.ToUpper(string(s[0])) + s[1:]
}

func main() {
    // Read OpenAI credentials from environment variables
    apiKey := os.Getenv("OPENAI_API_KEY")
    baseURL := os.Getenv("OPENAI_BASE_URL")

    if apiKey == "" {
        log.Fatal("Please set the OPENAI_API_KEY environment variable.")
    }


    client := openai.NewClient(
        option.WithAPIKey(apiKey),
        option.WithBaseURL(baseURL),
    )

    // Start a session with an initial query
    session := []Message{
        {Role: "user", Content: "What was the most notable achievement of Albert Einstein?"},
    }

    // Get first response
    // Pass the address of client using &
    reply, err := SendQuery(&client, session)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Answer:", reply)

    // Add the response to session history
    session = append(session, Message{Role: "assistant", Content: reply})

    // Add a follow-up query
    session = append(session, Message{Role: "user", Content: "Can you provide three more examples?"})

    // Get explanation with tutoring context
    // Pass the address of client using &
    followUpReply, err := SendQuery(&client, session)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Follow-up:", followUpReply)

    // Add the follow-up response to session history
    session = append(session, Message{Role: "assistant", Content: followUpReply})

    fmt.Println("\n--- Full Session History ---")
    // Print the entire session history
    for _, message := range session {
        fmt.Printf("%s: %s\n", capitalize(message.Role), message.Content)
    }
}
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal