Cache keys must be built only from inputs that truly change model output, and must be deterministic, complete, and cheap to compute.
Rules
system/developer, plus first user). Keep later turns from changing the head anchor when that’s intended.text; include non-text parts (image/video/document/audio/etc.) using a consistent scheme. When hashing variable-sized units, include length prefixes (or other unambiguous framing) so different payloads that share a prefix don’t collide.Sketch (Go-like pseudocode)
// Cache key inputs: (1) stable message anchor, (2) cheap settings/rules signature.
func cacheKey(messages []Message, rulesSig uint64, sessionID string) string {
anchor := conversationAnchor(messages) // includes text + non-text parts with framing
return fmt.Sprintf("%s|%d|%s", anchor, rulesSig, sessionID)
}
func conversationAnchor(messages []Message) string {
// Hash only: leading system/developer + first user (bounded by anchorMaxBytes)
// For each message: role + delimiter + all content parts.
// For each part:
// - if text: write length prefix + text
// - if non-text: write part kind + length prefix + URL/data bytes
// Ensure deterministic ordering and framing.
}
Outcome
Enter the URL of a public GitHub repository