In the world of LLM development, a static prompt is rarely enough. Real-world applications require dynamic context—data that changes based on user input, database records, or application state. In Semantic Kernel, this is achieved through Kernel Arguments.
Kernel Arguments act as a bridge between your application data and your prompt templates, allowing you to inject variables into your instructions seamlessly.
using System.ComponentModel;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
var apiKey = Environment.GetEnvironmentVariable("OPEN_AI_KEY");
if (string.IsNullOrEmpty(apiKey))
{
Console.WriteLine("Please set the OPEN_AI_KEY environment variable.");
return;
}
var kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
modelId: "gpt-4o",
apiKey: apiKey)
.Build();
var executionSettings = new OpenAIPromptExecutionSettings
{
Temperature = 0.1,
ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};
var chat = kernel.GetRequiredService<IChatCompletionService>();
Console.WriteLine("=== Health & Fitness Assistant ===");
Console.WriteLine("First, let's set up your profile for personalized nutrition advice.\n");
Console.Write("Enter your daily calorie goal (e.g., 2000): ");
var calorieGoal = Console.ReadLine() ?? "2000";
Console.Write("Enter your diet type (e.g., balanced, low-carb, high-protein): ");
var dietType = Console.ReadLine() ?? "balanced";
Console.Write("Enter your fitness goal (e.g., weight loss, muscle gain, maintenance): ");
var fitnessGoal = Console.ReadLine() ?? "maintenance";
// 1. Defining Kernel Arguments
var kernelArguments = new KernelArguments
{
["calorieGoal"] = calorieGoal,
["dietType"] = dietType,
["fitnessGoal"] = fitnessGoal
};
// 2. Defining a Template with {{$variable}} syntax
var systemPromptTemplate = """
You are a professional health and fitness assistant specializing in nutrition analysis.
User Profile:
- Daily Calorie Goal: {{$calorieGoal}} calories
- Diet Type: {{$dietType}}
- Fitness Goal: {{$fitnessGoal}}
When analyzing meals, provide:
1. Estimated calorie count
2. Macronutrients breakdown (protein, carbs, fats)
3. Health rating (1-10) based on user's {{$dietType}} diet
4. Brief recommendations aligned with {{$fitnessGoal}} goal
Keep responses concise and practical.
""";
// 3. Rendering the prompt using the kernel and arguments
var renderedSystemPrompt = await kernel.InvokePromptAsync(systemPromptTemplate, kernelArguments);
List<ChatMessageContent> messages =
[
new(AuthorRole.System, renderedSystemPrompt.ToString()),
new(AuthorRole.User, "I want to track my daily calorie intake. What's my total so far?"),
new(AuthorRole.Assistant,
"Currently, I don't have any meals logged. Please share a photo of your meal or describe what you've eaten today."),
];
var history = new ChatHistory(messages);
Console.WriteLine("\n=== Profile Setup Complete ===");
Console.WriteLine($"Calorie Goal: {calorieGoal} | Diet: {dietType} | Goal: {fitnessGoal}");
Console.WriteLine("\nCommands:");
Console.WriteLine(" - Type 'meal' to analyze a sample meal photo");
Console.WriteLine(" - Ask about nutrition, calories, or fitness tips");
Console.WriteLine(" - Type 'exit' or press Enter to quit.\n");
while (true)
{
Console.Write(" User >>> ");
var prompt = Console.ReadLine();
if (string.IsNullOrEmpty(prompt) || prompt.ToLower() == "exit") break;
if (prompt.ToLower() == "meal")
{
var mealAnalysisPromptTemplate = """
Can you analyze this meal image?
Consider my profile:
- My daily calorie goal is {{$calorieGoal}} calories
- I'm following a {{$dietType}} diet
- My fitness goal is {{$fitnessGoal}}
Please tell me:
1. Estimated calories and if it fits my goal
2. Macronutrients breakdown
3. How well it aligns with my {{$dietType}} diet (1-10)
4. Specific recommendations for my {{$fitnessGoal}} goal
""";
// Re-rendering a specific prompt for meal analysis
var renderedMealPrompt = await kernel.InvokePromptAsync(mealAnalysisPromptTemplate, kernelArguments);
history.AddMessage(AuthorRole.User,
[
new TextContent(renderedMealPrompt.ToString()),
new ImageContent(new Uri("https://images.unsplash.com/photo-1546069901-ba9599a7e63c?w=800"))
]);
Console.WriteLine("\n[Analyzing meal photo with your profile...]");
}
else
{
history.AddUserMessage(prompt);
}
Console.Write(" Bot >>> ");
string fullMessage = string.Empty;
await foreach (var token in chat.GetStreamingChatMessageContentsAsync(history, executionSettings, kernel))
{
Console.Write(token.Content);
fullMessage += token.Content;
}
Console.WriteLine("\n");
history.AddAssistantMessage(fullMessage);
}
Console.WriteLine("\n=== Chat History Summary ===");
foreach (var chatMessage in history)
{
Console.WriteLine($"\n{chatMessage.Role}:");
if (chatMessage.Items.Count > 1)
{
foreach (var item in chatMessage.Items)
{
if (item is TextContent textContent)
{
Console.WriteLine($" [Text] {textContent.Text}");
}
else if (item is ImageContent imageContent)
{
Console.WriteLine($" [Image] {imageContent.Uri}");
}
}
}
else
{
Console.WriteLine($" {chatMessage.Content}");
}
}