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.

In C#, we can represent each message as an object with two properties: role and content. The session history can be stored as a list of these message objects. Here’s how a simple tutoring session might look in C#:

public class Message
{
    public string role { get; set; }
    public string content { get; set; }

    public Message(string role, string content)
    {
        this.role = role;
        this.content = content;
    }
}

// Example session history
var session = new List<Message>
{
    new Message("user", "Can you explain the theory of relativity?"),
    new Message("assistant", "Einstein's theory of relativity consists of two parts: special relativity and general relativity..."),
    new Message("user", "What practical applications does it have?"),
    new Message("assistant", "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 Method to Handle Tutoring Sessions

To manage tutoring sessions effectively, we will create a method called SendMessage. This method will send queries to the AI and receive explanations, allowing us to handle multiple interactions seamlessly using HttpClient to communicate with the DeepSeek API. Here’s how the method is structured in C#:

private static async Task<string> SendMessage(string endpoint, string apiKey, List<Message> conversation, string userMessage)
{
    // Append the user's message to the conversation history
    conversation.Add(new Message("user", userMessage));

    using var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);

    var payload = new
    {
        model = "deepseek-ai/DeepSeek-V3",
        messages = conversation
    };

    var jsonPayload = JsonSerializer.Serialize(payload);
    using var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
    var response = await client.PostAsync(endpoint, content);
    var body = await response.Content.ReadAsStringAsync();

    if (!response.IsSuccessStatusCode)
    {
        Console.WriteLine($"Error ({response.StatusCode}): {body}");
        return "";
    }

    using var doc = JsonDocument.Parse(body);
    var reply = doc.RootElement
                   .GetProperty("choices")[0]
                   .GetProperty("message")
                   .GetProperty("content")
                   .GetString();

    // Append the AI's response to the conversation history
    conversation.Add(new Message("assistant", reply?.Trim() ?? ""));

    return reply?.Trim() ?? "";
}

In this method, we use HttpClient to send a POST request to the DeepSeek API endpoint. The conversation parameter contains the session history, which provides context for the AI's response. The method appends the user's message, sends the request, parses the AI's reply, appends the assistant's response to the conversation, and returns the AI's explanation.

Building and Managing Session History

Maintaining a session history is crucial for providing context to the AI tutor. This allows the AI to generate explanations that are relevant to the ongoing educational dialogue.

If we don't maintain session history, the AI will lack the context of previous interactions, leading to responses that may not be coherent or relevant to the current conversation. Using a structured object to store session history, as opposed to just storing responses in a list, offers several advantages. The object format allows us to clearly define the role of each message (e.g., "user" or "assistant") and its content, ensuring that the AI can accurately interpret who is speaking and maintain the flow of dialogue. It also makes it easier to manage and update the session history, as each message is self-contained with its role and content, providing a clear and organized way to track the conversation.

Let's see how we can build and manage session history in C#:

public class Program
{
    public static async Task Main(string[] args)
    {
        var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY");
        var baseUri = Environment.GetEnvironmentVariable("OPENAI_BASE_URL");
        if (string.IsNullOrEmpty(apiKey))
        {
            Console.WriteLine("Set your OPENAI_API_KEY.");
            return;
        }
        if (string.IsNullOrEmpty(baseUri))
        {
            Console.WriteLine("Set your OPENAI_BASE_URL (e.g. https://api.openai.com).");
            return;
        }

        var endpoint = baseUri.TrimEnd('/') + "/v1/chat/completions";

        // Start a session with an initial query
        var session = new List<Message>();

        // Get first response
        string reply = await SendMessage(endpoint, apiKey, session, "What was the most notable achievement of Albert Einstein?");
        Console.WriteLine("Answer: " + reply);

        // Add a follow-up query and get explanation with tutoring context
        string followUpReply = await SendMessage(endpoint, apiKey, session, "Can you provide three more examples?");
        Console.WriteLine("Follow-up: " + followUpReply);
    }
}

After sending the initial query, the AI responds with information about Einstein's achievements, showcasing its ability to provide educational content:

Answer: Albert Einstein's most notable achievement is generally considered to be his theory of relativity, particularly the general theory of relativity published in 1915...

With the session history maintained, the AI provides a contextually relevant follow-up explanation, listing additional achievements of Einstein:

Follow-up: Here are three more notable achievements of Albert Einstein:

1. Photoelectric Effect: In 1905, Einstein explained the photoelectric effect, demonstrating that light consists of particles called photons...

2. Einstein's Theory of Brownian Motion: Also in 1905, Einstein provided mathematical evidence for the existence of atoms...

3. Mass-Energy Equivalence: Einstein formulated the equation E=mc²...

By maintaining this history, we provide context for subsequent interactions, allowing the AI to generate more coherent and relevant educational explanations.

Visualizing the Session History

To better understand how the tutoring session has evolved, we can print the entire session history:

// Iterate over the conversation history and print each message
foreach (var message in session)
{
    Console.WriteLine($"{Capitalize(message.role)}: {message.content}");
}

// Helper method to capitalize the first letter
private static string Capitalize(string input)
{
    if (string.IsNullOrEmpty(input)) return input;
    return char.ToUpper(input[0]) + input.Substring(1);
}

This will output the complete dialogue, showing both student queries and tutor explanations:

User: What was the most notable achievement of Albert Einstein?
Assistant: Albert Einstein's most notable achievement is generally considered to be his theory of relativity...
User: Can you provide three more examples?
Assistant: Here are three more notable achievements of Albert Einstein: 1. Photoelectric Effect... 2. Einstein's Theory of Brownian Motion... 3. Mass-Energy Equivalence...

Having access to the session history allows you to track the flow of educational dialogue and ensure that the AI tutor's explanations remain contextually relevant and build upon previous discussions.

Summary and Preparation for Practice

In this lesson, you learned about message types and the importance of maintaining session history in tutoring interactions. We explored how to set up your environment, structure your message objects, and create a method to handle tutoring sessions using HttpClient to communicate with the DeepSeek API. You also saw how to build and manage session history, enabling the AI to generate contextually relevant educational explanations.

As you move on to the practice exercises, I encourage you to experiment with different tutoring scenarios and observe how the AI's explanations change based on the context provided. This hands-on practice will reinforce what you've learned and prepare you for the next unit, where we'll continue to build on these concepts. Keep up the great work, and enjoy the journey of creating your personal tutor with DeepSeek!

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