Since T2.3, the Kladde assesses tenders with a structured answer. The text that tells the model what to do still sits somewhere in the C# code as a string. That works as long as the prompt is short and only you change it. In this module it becomes part of the code and gets the same care as the rest: a file of its own, a version, tests, and an order that the providers’ prompt cache rewards. This lesson starts with the most important part, the system prompt.
Where the Kladde stands
After T2, the Kladde has the project Kladde.Ai with a registered IChatClient (local through Foundry Local or in the cloud, depending on
the configuration), the assessment of tenders with a structured answer, and a cost counter for each AI feature. Three types from T2.3
matter for this module. Yours may be named differently; if so, carry the names over:
// src/Kladde.Ai/Tenders/TenderAssessment.cs
using System.Text.Json.Serialization;
namespace Kladde.Ai.Tenders;
/// <summary>What the model sees of a public tender: invented or public facts only.</summary>
public sealed record TenderNotice(string Id, string Title, string Buyer, string Place, DateOnly Deadline, string Description);
/// <summary>How well a tender suits the office.</summary>
public enum Suitability
{
Suitable,
PartlySuitable,
Unsuitable,
NotAssessable,
}
/// <summary>The model's structured answer; a missing field makes the answer unreadable instead of silently 0.</summary>
public sealed record TenderAssessment(
[property: JsonRequired] Suitability Suitability,
[property: JsonRequired] IReadOnlyList<string> Reasons,
[property: JsonRequired] IReadOnlyList<string> Risks,
[property: JsonRequired] int Score);
The value NotAssessable is new. Why it’s added is explained further down, in the section about the way out. Append it at the end of the
enum; that way stored assessments keep their meaning.