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
|
### D&D NPC Normalization Prompt Ordering And Cache Boundaries
|
||||||
|
|
||||||
NPC normalization has a distinct prompt and response-schema identity from NPC
|
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
|
extraction. Its stable message tiers are the common D&D system asset, followed
|
||||||
assets, followed by package-owned task and normalization instructions. Cache
|
by package-owned task and normalization instructions. Cache boundaries follow
|
||||||
boundaries follow the shared identity tier and the package instructions. The
|
the shared system tier and the package instructions. The variable tail contains
|
||||||
variable tail contains the private candidate-name-and-range input and a
|
the private candidate-name-and-range input and a windowed transcript input
|
||||||
windowed transcript input whose cited units provide local context; neither has
|
whose cited units provide local context; neither has a cache boundary because
|
||||||
a cache boundary because it changes with the document.
|
it changes with the document.
|
||||||
|
|
||||||
This prompt intentionally omits extraction-evidence and campaign-reference
|
This prompt intentionally omits shared identity guidance,
|
||||||
assets: it reconciles existing records rather than extracting events or adding
|
extraction-evidence, and campaign-reference assets: it reconciles existing
|
||||||
evidence. Its package-owned manifest and schema identity are fingerprinted
|
records rather than extracting events or adding evidence. Its package-owned
|
||||||
separately, so a normalization prompt or schema change cannot reuse a prior
|
manifest and schema identity are fingerprinted separately, so a normalization
|
||||||
normalization checkpoint.
|
prompt or schema change cannot reuse a prior normalization checkpoint.
|
||||||
|
|
||||||
Shared wording belongs in the canonical assets under
|
Shared wording belongs in the canonical assets under
|
||||||
`internal/modules/dnd/shared`; extraction packages reference those assets in
|
`internal/modules/dnd/shared`; extraction packages reference those assets in
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ inputs:
|
|||||||
messages:
|
messages:
|
||||||
- role: system
|
- role: system
|
||||||
content_file: ./sharedassets/common-dnd-system.md
|
content_file: ./sharedassets/common-dnd-system.md
|
||||||
- role: user
|
|
||||||
content_file: ./sharedassets/common-dnd-identity.md
|
|
||||||
cache_control:
|
cache_control:
|
||||||
type: ephemeral
|
type: ephemeral
|
||||||
- role: user
|
- role: user
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ var promptAssetManifest = shared.PromptAssetManifest{
|
|||||||
},
|
},
|
||||||
SharedFiles: []string{
|
SharedFiles: []string{
|
||||||
"common-dnd-system.md",
|
"common-dnd-system.md",
|
||||||
"common-dnd-identity.md",
|
|
||||||
"common-dnd-transcript.md",
|
"common-dnd-transcript.md",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package npcs
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -11,6 +12,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestRegisterPromptAssetsPreparesNormalizationPrompt(t *testing.T) {
|
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()
|
registry := llm.NewAssetRegistry()
|
||||||
if err := RegisterPromptAssets(registry); err != nil {
|
if err := RegisterPromptAssets(registry); err != nil {
|
||||||
t.Fatalf("RegisterPromptAssets() error = %v", err)
|
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" {
|
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)
|
t.Fatalf("prepared prompt = %#v, want normalization prompt identity and schema", prepared)
|
||||||
}
|
}
|
||||||
if len(prepared.Messages) != 6 {
|
if len(prepared.Messages) != 5 {
|
||||||
t.Fatalf("prepared messages = %d, want 6", len(prepared.Messages))
|
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 {
|
if cache := prepared.Messages[index].CacheControl; cache == nil || cache.Type != scriptorium.CacheControlEphemeral {
|
||||||
t.Errorf("message %d cache control = %#v, want ephemeral", index, cache)
|
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 {
|
if cache := prepared.Messages[index].CacheControl; cache != nil {
|
||||||
t.Errorf("message %d cache control = %#v, want nil", index, cache)
|
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"`) {
|
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[4].Content)
|
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"`) {
|
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[5].Content)
|
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