A well-built prompt: task, context, rules, format
Good prompts say what to do, give the data, set limits, and describe the answer shape. XML-style tags keep the parts apart.
Watch it animatedStep through it, with the running line highlighted. Free with an account.The idea
A prompt is the only way you steer the model, so structure matters. Say the task clearly, give the material to work on, set the constraints (length, tone, what to do when unsure), and describe the exact output format. Wrapping each part in its own tag, such as <task> and <document>, lets the model and your own code tell instructions apart from data. Then, because you asked for JSON, your code can parse and validate the answer.
Code
public record TicketSummary(string Summary, string Urgency);
public static class TicketSummarizer
{
private static readonly JsonSerializerOptions Json = new(JsonSerializerDefaults.Web);
public static string BuildPrompt(string ticket, string[] rules)
{
var sb = new StringBuilder();
sb.AppendLine("<task>Summarize this support ticket.</task>");
sb.AppendLine($"<document>{ticket}</document>");
sb.AppendLine("<rules>" + string.Join("; ", rules) + "</rules>");
sb.AppendLine("<output_format>JSON with keys summary and urgency.</output_format>");
return sb.ToString();
}
public static async Task<TicketSummary?> SummarizeAsync(ILlmClient llm, string ticket)
{
string prompt = BuildPrompt(ticket, new[] { "Max 2 sentences.", "If unsure, say unknown." });
string answer = await llm.CompleteAsync(prompt);
return JsonSerializer.Deserialize<TicketSummary>(answer, Json);
}
}Tips
- Be specific. "Summarize in two sentences for a support manager" beats "summarize this".
- Tell the model what to do when it is unsure ("say unknown"). Otherwise it may guess.
- Anything pasted into the prompt from users or the web goes in the data part. Treat it as data, never as instructions (see the prompt injection lesson).
- Prompts are code: keep them in source control, version them and test them (see the evals lesson).
In the .NET library
Expect parsing to fail sometimes. Wrap JsonSerializer.Deserialize in a try/catch for JsonException, and decide whether to retry, repair or report an error. Never trust model output as already valid.