Simplify NPC normalization prompt guidance
This commit is contained in:
@@ -157,18 +157,18 @@ messages remain canonical shared assets rather than copied package text.
|
||||
### D&D NPC Normalization Prompt Ordering And Cache Boundaries
|
||||
|
||||
NPC normalization has a distinct prompt and response-schema identity from NPC
|
||||
extraction. Its stable message tiers are the common D&D system and identity
|
||||
assets, followed by package-owned task and normalization instructions. Cache
|
||||
boundaries follow the shared identity tier and the package instructions. The
|
||||
variable tail contains the private candidate-name-and-range input and a
|
||||
windowed transcript input whose cited units provide local context; neither has
|
||||
a cache boundary because it changes with the document.
|
||||
extraction. Its stable message tiers are the common D&D system asset, followed
|
||||
by package-owned task and normalization instructions. Cache boundaries follow
|
||||
the shared system tier and the package instructions. The variable tail contains
|
||||
the private candidate-name-and-range input and a windowed transcript input
|
||||
whose cited units provide local context; neither has a cache boundary because
|
||||
it changes with the document.
|
||||
|
||||
This prompt intentionally omits extraction-evidence and campaign-reference
|
||||
assets: it reconciles existing records rather than extracting events or adding
|
||||
evidence. Its package-owned manifest and schema identity are fingerprinted
|
||||
separately, so a normalization prompt or schema change cannot reuse a prior
|
||||
normalization checkpoint.
|
||||
This prompt intentionally omits shared identity guidance,
|
||||
extraction-evidence, and campaign-reference assets: it reconciles existing
|
||||
records rather than extracting events or adding evidence. Its package-owned
|
||||
manifest and schema identity are fingerprinted separately, so a normalization
|
||||
prompt or schema change cannot reuse a prior normalization checkpoint.
|
||||
|
||||
Shared wording belongs in the canonical assets under
|
||||
`internal/modules/dnd/shared`; extraction packages reference those assets in
|
||||
|
||||
@@ -11,8 +11,6 @@ inputs:
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-identity.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
|
||||
@@ -21,7 +21,6 @@ var promptAssetManifest = shared.PromptAssetManifest{
|
||||
},
|
||||
SharedFiles: []string{
|
||||
"common-dnd-system.md",
|
||||
"common-dnd-identity.md",
|
||||
"common-dnd-transcript.md",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package npcs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -11,6 +12,12 @@ import (
|
||||
)
|
||||
|
||||
func TestRegisterPromptAssetsPreparesNormalizationPrompt(t *testing.T) {
|
||||
if want := []string{"common-dnd-system.md", "common-dnd-transcript.md"}; !reflect.DeepEqual(promptAssetManifest.SharedFiles, want) {
|
||||
t.Fatalf("shared prompt assets = %#v, want %#v", promptAssetManifest.SharedFiles, want)
|
||||
}
|
||||
if promptHash, err := scriptoriumPromptMetadata(); err != nil || promptHash == "" {
|
||||
t.Fatalf("scriptoriumPromptMetadata() = %q, %v; want prompt fingerprint", promptHash, err)
|
||||
}
|
||||
registry := llm.NewAssetRegistry()
|
||||
if err := RegisterPromptAssets(registry); err != nil {
|
||||
t.Fatalf("RegisterPromptAssets() error = %v", err)
|
||||
@@ -39,23 +46,36 @@ func TestRegisterPromptAssetsPreparesNormalizationPrompt(t *testing.T) {
|
||||
if prepared.PromptID != PromptID || prepared.OutputContract.SchemaPath != "dnd_npcs_normalize_llm.v1.json" {
|
||||
t.Fatalf("prepared prompt = %#v, want normalization prompt identity and schema", prepared)
|
||||
}
|
||||
if len(prepared.Messages) != 6 {
|
||||
t.Fatalf("prepared messages = %d, want 6", len(prepared.Messages))
|
||||
if len(prepared.Messages) != 5 {
|
||||
t.Fatalf("prepared messages = %d, want 5", len(prepared.Messages))
|
||||
}
|
||||
for _, index := range []int{1, 3} {
|
||||
for index, role := range []string{"system", "user", "user", "user", "user"} {
|
||||
if prepared.Messages[index].Role != role {
|
||||
t.Errorf("message %d role = %q, want %q", index, prepared.Messages[index].Role, role)
|
||||
}
|
||||
}
|
||||
for _, index := range []int{0, 2} {
|
||||
if cache := prepared.Messages[index].CacheControl; cache == nil || cache.Type != scriptorium.CacheControlEphemeral {
|
||||
t.Errorf("message %d cache control = %#v, want ephemeral", index, cache)
|
||||
}
|
||||
}
|
||||
for _, index := range []int{0, 2, 4, 5} {
|
||||
for _, index := range []int{1, 3, 4} {
|
||||
if cache := prepared.Messages[index].CacheControl; cache != nil {
|
||||
t.Errorf("message %d cache control = %#v, want nil", index, cache)
|
||||
}
|
||||
}
|
||||
if !strings.Contains(prepared.Messages[4].Content, `"Mira"`) || strings.Contains(prepared.Messages[4].Content, `"windows"`) {
|
||||
t.Fatalf("candidate message = %q, want only rendered candidates", prepared.Messages[4].Content)
|
||||
if !strings.Contains(prepared.Messages[3].Content, `"Mira"`) || strings.Contains(prepared.Messages[3].Content, `"windows"`) {
|
||||
t.Fatalf("candidate message = %q, want only rendered candidates", prepared.Messages[3].Content)
|
||||
}
|
||||
if !strings.Contains(prepared.Messages[5].Content, `"windows"`) || strings.Contains(prepared.Messages[5].Content, `"Mira"`) {
|
||||
t.Fatalf("transcript message = %q, want only rendered transcript", prepared.Messages[5].Content)
|
||||
if !strings.Contains(prepared.Messages[4].Content, `"windows"`) || strings.Contains(prepared.Messages[4].Content, `"Mira"`) {
|
||||
t.Fatalf("transcript message = %q, want only rendered transcript", prepared.Messages[4].Content)
|
||||
}
|
||||
for index, message := range prepared.Messages {
|
||||
if index != 3 && strings.Contains(message.Content, `"Mira"`) {
|
||||
t.Errorf("message %d unexpectedly rendered candidate input", index)
|
||||
}
|
||||
if index != 4 && strings.Contains(message.Content, `"windows"`) {
|
||||
t.Errorf("message %d unexpectedly rendered transcript input", index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user