Skip to content

Chat Session

Gunpal Jain edited this page Nov 15, 2026 · 4 revisions

A ChatSession keeps the conversation history for you, so each new message is sent with the earlier turns. You send messages with the same GenerateContentAsync and StreamContentAsync methods you use on a model. ChatSession derives from GenerativeModel.

Package: Google_GenerativeAI. Setup: Initialization.

Creating a Chat Session

using GenerativeAI;
using GenerativeAI.Types;

var model = new GoogleAi("YOUR_API_KEY").CreateGenerativeModel(GoogleAIModels.Gemini38Flash);
ChatSession chat = model.StartChat();

StartChat accepts these optional parameters:

Parameter Description
history List<Content> to start from. Empty when omitted.
config GenerationConfig for the session. Defaults to the model's Config.
safetySettings ICollection<SafetySetting>. Defaults to the model's settings.
systemInstruction System prompt for the session. Defaults to the model's SystemInstruction.

The session also copies the model's function tools and its Google Search, code execution and retrieval settings.

With history

var history = new List<Content>
{
    new Content("Hello!", Roles.User),
    new Content("Hi there! How can I help you?", Roles.Model)
};

ChatSession chat = model.StartChat(history: history);

With configuration and a system instruction

ChatSession chat = model.StartChat(
    config: new GenerationConfig { Temperature = 0.8, MaxOutputTokens = 500 },
    systemInstruction: "You are a friendly travel guide.");

Sending Messages

GenerateContentAsync

var chat = model.StartChat();

var response = await chat.GenerateContentAsync("What is the capital of France?");
Console.WriteLine($"Assistant: {response.Text()}");

response = await chat.GenerateContentAsync("And what is its population?");
Console.WriteLine($"Assistant: {response.Text()}");

StreamContentAsync

var chat = model.StartChat();

await foreach (var chunk in chat.StreamContentAsync("Tell me a story."))
{
    Console.Write(chunk.Text());
}

// Or with a request
var request = new GenerateContentRequest();
request.AddText("Now make it shorter.");

await foreach (var chunk in chat.StreamContentAsync(request))
{
    Console.Write(chunk.Text());
}

When a stream finishes, the session joins the streamed text into one model turn and adds it to the history.

Images and files in a chat

Build a request with a file and send it through the session:

var request = new GenerateContentRequest();
request.AddInlineFile("image.png");
request.AddText("Identify the objects in this image.");

var first = await chat.GenerateContentAsync(request);
var followUp = await chat.GenerateContentAsync("Can you estimate the number of blueberries?");

See Multimodal Features for more ways to attach files.

Inspecting and Editing History

List<Content> turns = chat.History;          // alternating user / model turns
Content? lastUser   = chat.LastRequestContent;
Content? lastModel  = chat.LastResponseContent;

chat.History = new List<Content>();          // reset the conversation

Turns that only carry function calls or function results are not added to History. Only the final answer and the prompt that led to it are recorded.

Saving and Restoring a Session

CreateChatSessionBackUpData() captures the history, config, safety settings, system instruction, model, cached content, JSON mode and tool settings. Pass the backup to StartChat to restore the session:

using System.Text.Json;

ChatSessionBackUpData backup = chat.CreateChatSessionBackUpData();
string json = JsonSerializer.Serialize(backup, DefaultSerializerOptions.Options);

// later...
var restoredBackup = JsonSerializer.Deserialize<ChatSessionBackUpData>(json, DefaultSerializerOptions.Options)!;
ChatSession restored = model.StartChat(restoredBackup);   // optional: pass List<IFunctionTool> tools

Function tools are code, so they aren't part of the backup. Pass them again through the tools parameter, or the session uses the model's FunctionTools.

Related Pages

API Reference

Clone this wiki locally