MICROSOFT AGENT FRAMEWORK · 0.16.0-rc.1
Prompt profiles
Name and version instructions without assigning them model selection or write permission.
Objectives
- Separate instructions and data
- Task-specific profiles
- Version and compare without a security guarantee
Changed instructions change behavior
Two environments run the same program with different instructions: one asks for detailed hypotheses, the other three sentences. Without a name and version, explaining the difference later becomes difficult. EP014 proposed treating the prompt as an application artifact. Demo390 makes that choice visible with two versioned instruction profiles while keeping connection configuration separate.
Load an identified instruction contract
appsettings.json is an array of Id, Version and Instructions profiles, read with File.ReadAllTextAsync and JsonSerializer from AppContext.BaseDirectory. The program requires at least one profile, nonblank values and ordinally unique IDs. MAF_INSTRUCTION_PROFILE selects support-cautious by default or support-brief explicitly; an unknown name fails. The earlier IConfiguration-loading and constant/file comparison-menu narrative is corrected: this program deserializes the array and runs once.
var profiles = JsonSerializer.Deserialize<InstructionProfile[]>(
await File.ReadAllTextAsync(Path.Combine(AppContext.BaseDirectory, "appsettings.json")),
JsonSerializerOptions.Web) ?? throw new InvalidDataException("Missing instruction profiles.");
if (profiles.Length == 0 || profiles.Any(p => string.IsNullOrWhiteSpace(p.Id)
|| string.IsNullOrWhiteSpace(p.Version) || string.IsNullOrWhiteSpace(p.Instructions))
|| profiles.Select(p => p.Id).Distinct(StringComparer.Ordinal).Count() != profiles.Length)
throw new InvalidDataException("Instruction profiles must have unique IDs, versions, and instructions.");
string selected = global::Maf.DemoConnection.DemoConfiguration.GetSetting("MAF_INSTRUCTION_PROFILE") ?? "support-cautious";
var profile = profiles.SingleOrDefault(p => p.Id == selected)
?? throw new InvalidDataException("Unknown instruction profile.");
Console.WriteLine($"Instructions: {profile.Id}/{profile.Version}. Effective connection provider: {settings.ChatProvider}.");
Console.WriteLine("The instruction profile does not select a model; AI settings select the connection.");
Two independent selections
support-cautious asks for facts and hypotheses to be separated, missing error details requested and destructive actions avoided. support-brief asks for at most three sentences and the next diagnostic step. These instructions change neither ChatProvider nor model name; MemoryDemo.Load and common configuration select the connection. Changing an instruction profile must not be described as changing the model client. No embeddings are required.
- AI configuration → provider, endpoint and model → client
- appsettings.json + MAF_INSTRUCTION_PROFILE → Id/Version/Instructions → agent
- Same support request → response → provider usage when available
- One execution; no persisted session or business write
var agent = chat.AsAIAgent(name: profile.Id, instructions: profile.Instructions);
var response = await agent.RunAsync("Billing is blocked for three customers. No precise error is available. Suggest the next support action.", cancellationToken: stop.Token);
Console.WriteLine(response.Text);
MemoryDemo.PrintUsage(response);
Version for comparison without promising quality
The program prints Id/Version and effective provider. For reproducible comparison also record file revision, model, options and the fixed request. Printed output is not a durable journal and cannot alone recover every past configuration. Changing the file copied beside the executable changes instructions on the next launch; a build may copy the source file again. Work in a distribution copy and version changes instead of rewriting the reference profile.
A version identifies an intention, not a quality result. The program does not validate the three-sentence limit or a semantic “no destruction” rule after generation. No tool is exposed here; tool denial does not follow from instructions alone. For a persistent session or workflow, changing instructions requires a compatibility policy; Demo390 serializes no session and performs no such migration. The previous lot’s durable decision remains a separate protocol.
Change profile, then trigger configuration rejection
$env:MAF_INSTRUCTION_PROFILE = "support-cautious"dotnet run --project demos/Demo390_PromptProfiles/Demo390.App.csproj -c Release --no-build$env:MAF_INSTRUCTION_PROFILE = "support-brief"dotnet run --project demos/Demo390_PromptProfiles/Demo390.App.csproj -c Release --no-buildCompare the same request and record the Instructions header and provider; retain responses as dated observations without promising constant style. Then test unknown-profile: expect Unknown instruction profile before generation. Restore or remove the variable in this PowerShell session with the command below. Unknown-profile refusal can be checked without model output; both valid-profile comparisons require chat.
Remove-Item Env:MAF_INSTRUCTION_PROFILE -ErrorAction SilentlyContinueA profile is not authorization
Catalogue and permissions do not change because a profile says “cautious” or “administrator.” The program has no hot reload, remote prompt registry, migration contract or automatic evaluation of both styles. It prints a profile identity and uses the selected instructions. Provider usage may be unavailable; it must not be invented or treated as monetary cost.
