Skip to content

Commit af434ec

Browse files
authored
Model selection (#10)
* add model selection This adds an optional model property to the prompt file, allowing the prompt developer to specify which model it should be executed against * Add model configuration to documentation
1 parent 3eefe78 commit af434ec

4 files changed

Lines changed: 43 additions & 2 deletions

File tree

DotPrompt.Tests/PromptFileTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ public void FromFile_BasicPrompt_ProducesValidPromptFile()
2222

2323
Assert.Equal("basic", promptFile.Name);
2424

25+
Assert.NotNull(promptFile.Model);
26+
Assert.Equal("claude-3-5-sonnet-latest", promptFile.Model);
27+
2528
Assert.NotNull(promptFile.Config);
2629
Assert.Equal(OutputFormat.Text, promptFile.Config.OutputFormat);
2730
Assert.Equal(500, promptFile.Config.MaxTokens);
@@ -196,6 +199,19 @@ public void FromStream_WithInvalidName_ThrowsAnException()
196199
Assert.Contains("once cleaned results in an empty string", exception.Message);
197200
}
198201

202+
[Fact]
203+
public void FromStream_WithMissingModelName_IsPersistedAsNullValue()
204+
{
205+
const string content = "name: missing-model\nmodel: \nprompts:\n system: System prompt\n user: User prompt";
206+
using var ms = new MemoryStream(Encoding.UTF8.GetBytes(content));
207+
ms.Seek(0, SeekOrigin.Begin);
208+
209+
var promptFile = PromptFile.FromStream("", ms);
210+
211+
Assert.Equal("missing-model", promptFile.Name);
212+
Assert.Null(promptFile.Model);
213+
}
214+
199215
[Fact]
200216
public void GenerateUserPrompt_UsingDefaults_CorrectlyGeneratesPromptFromTemplate()
201217
{

DotPrompt.Tests/SamplePrompts/basic.prompt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
model: claude-3-5-sonnet-latest
12
config:
23
outputFormat: text
34
temperature: 0.9

DotPrompt/PromptFile.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ public partial class PromptFile
2121
/// Gets, sets the name of the prompt
2222
/// </summary>
2323
public required string Name { get; set; }
24+
25+
/// <summary>
26+
/// Gets, sets the name of the model (or deployment) the prompt should be executed using
27+
/// </summary>
28+
public string? Model { get; set; }
2429

2530
/// <summary>
2631
/// Gets, sets the configuration to use for the prompt

README.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ A complete prompt file would look like this.
1919

2020
```yaml
2121
name: Example
22+
model: gpt-4o
2223
config:
2324
outputFormat: text
2425
temperature: 0.9
@@ -52,6 +53,16 @@ The `name` is optional in the configuration, if it's not provided then the name
5253

5354
If you use this property then when the file is loaded the name is converted to lowercase and spaces are replaced with hyphens. So a name of `My cool Prompt` would become `my-cool-prompt`. This is done to make sure the name is easily accessible from the code.
5455

56+
### Model
57+
58+
This is another optional item in the configuration, but it provides information to the user of the prompt file which model (or deployment for Azure Open AI) it should use. As this can be null if not specified this the consumer should make sure to check before usage. For example:
59+
60+
```csharp
61+
var model = promptFile.Model ?? "my-default";
62+
```
63+
64+
Using this option though allows the prompt engineer to be very explicit about which model they intended to be used to provide the best results.
65+
5566
### Config
5667

5768
The `config` section has some top level items which are provided for the client to use in their LLM calls to set options on each call. The `outputFormat` property takes a value of either `text` or `json` depending on how the LLM is intended to respond to the request. If specifying `json` then some LLMs require either the system or user prompt to state that the expected output is JSON as well. If the library does not detect the term `JSON` in the prompt then it will append a small statement to the system prompt requesting for the response to be in JSON format.
@@ -202,7 +213,6 @@ using Azure.AI.OpenAI;
202213
using DotPrompt;
203214

204215
var openAiClient = new(new Uri("https://endpoint"), new ApiKeyCredential("abc123"));
205-
var client = openAiClient.GetChatClient("model");
206216

207217
var promptManager = new PromptManager();
208218
var promptFile = promptManager.GetPromptFile("example");
@@ -216,6 +226,8 @@ var userPrompt = promptFile.GetUserPrompt(new Dictionary<string, object>
216226
{ "style", "used car salesman" }
217227
});
218228

229+
var client = openAiClient.GetChatClient(promptFile.Model ?? "default-model");
230+
219231
var completion = await client.CompleteChatAsync(
220232
[
221233
new SystemChatMessage(systemPrompt),
@@ -239,7 +251,6 @@ using DotPrompt;
239251
using DotPrompt.Extensions.OpenAi;
240252

241253
var openAiClient = new(new Uri("https://endpoint"), new ApiKeyCredential("abc123"));
242-
var client = openAiClient.GetChatClient("model");
243254

244255
var promptManager = new PromptManager();
245256
var promptFile = promptManager.GetPromptFile("example");
@@ -250,6 +261,8 @@ var promptValues = new Dictionary<string, object>
250261
{ "style", "used car salesman" }
251262
};
252263

264+
var client = openAiClient.GetChatClient(promptFile.Model ?? "default-model");
265+
253266
var completion = await client.CompleteChatAsync(
254267
promptFile.ToOpenAiChatMessages(promptValues),
255268
promptFile.ToOpenAiChatCompletionOptions()
@@ -332,6 +345,11 @@ public class PromptEntity : ITableEntity
332345
/// </summary>
333346
public ETag ETag { get; set; }
334347

348+
/// <summary>
349+
/// Gets, sets the model to use
350+
/// </summary>
351+
public string? Model { get; set; }
352+
335353
/// <summary>
336354
/// Gets, sets the output format
337355
/// </summary>
@@ -395,6 +413,7 @@ public class PromptEntity : ITableEntity
395413
var promptFile = new PromptFile
396414
{
397415
Name = RowKey,
416+
Model = Model,
398417
Config = new PromptConfig
399418
{
400419
OutputFormat = Enum.Parse<OutputFormat>(OutputFormat, true),

0 commit comments

Comments
 (0)