perf(claude): prefilter JSON payloads before diagnostic walks

- Add ASCII pre-filter to skip expensive gjson traversals for title helper and 1h TTL checks
- Check raw bytes for target keywords before initiating full JSON walks
- Fall back to full inspection when printable ASCII Unicode escapes are detected

Closes: #6291
This commit is contained in:
Luis Pater
2026-10-03 10:48:07 +08:00
parent 2044a01f42
commit 5dbce4f3fb
4 changed files with 343 additions and 1 deletions

View File

@@ -441,6 +441,12 @@ func isClaudeTitleHelperInstruction(body []byte) bool {
}
func isClaudeTitleHelperRequest(body []byte) bool {
// Without an output_config key the request is a helper only if one of the
// system title instructions below appears, so skip the walks when none can.
if !jsonMayContainASCII(body, "output_config", "naming a coding session", "Return a short title",
"Write the title in the predominant language") {
return false
}
props := gjson.GetBytes(body, "output_config.format.schema.properties")
if props.Exists() {
if props.Get("title").Exists() && len(props.Map()) == 1 {
@@ -527,7 +533,9 @@ func IsClaudeSubagentRequest(headers http.Header, body []byte) bool {
// ClaudePayloadHas1hTTL reports whether the request payload contains any cache_control
// block with ttl set to "1h".
func ClaudePayloadHas1hTTL(payload []byte) bool {
if len(payload) == 0 || !gjson.ValidBytes(payload) {
// A ttl of "1h" is the JSON string "1h"; its quotes are structural and never
// escaped, so a payload without that token cannot match.
if len(payload) == 0 || !jsonMayContainASCII(payload, `"1h"`) || !gjson.ValidBytes(payload) {
return false
}
has1h := false

View File

@@ -0,0 +1,50 @@
package helps
import "bytes"
// jsonMayContainASCII reports whether decoding the JSON document body could
// yield a key or string value containing any of needles.
//
// It lets the request classifiers below skip their gjson walks: a Claude Code
// request body carries the whole conversation (often several MB), and each
// walk re-scans it. bytes.Contains is far cheaper than a gjson walk.
//
// Every needle must be printable ASCII without '\\' or '/' (JSON may spell
// '/' as `\/`). A '"' may only stand at
// either end of a needle, where it matches a structural string delimiter
// (`"1h"` matches the whole string value 1h). JSON can only
// spell such a character as itself or as a \u00XX escape, so when body holds
// no \u escape of a printable ASCII character, a needle that is absent from
// the raw bytes is absent from every decoded string too. If such an escape is
// present the function answers true and the caller falls back to its full
// walk, so the result never changes, only the cost.
func jsonMayContainASCII(body []byte, needles ...string) bool {
if hasPrintableASCIIUnicodeEscape(body) {
return true
}
for _, needle := range needles {
if bytes.Contains(body, []byte(needle)) {
return true
}
}
return false
}
// hasPrintableASCIIUnicodeEscape reports whether body contains a \u00XX
// escape whose first hex digit is 2-7, i.e. a printable ASCII character. It
// errs only toward "yes": it also matches DEL (7F), malformed escapes such as
// a 2-7 digit followed by a non-hex character, an escape truncated after that
// digit, and an escaped backslash followed by literal text such as `\\u0041`.
// Each of those only makes the caller fall back to a full walk.
func hasPrintableASCIIUnicodeEscape(body []byte) bool {
for rest := body; ; {
i := bytes.Index(rest, []byte(`\u00`))
if i < 0 || i+4 >= len(rest) {
return false
}
if c := rest[i+4]; c >= '2' && c <= '7' {
return true
}
rest = rest[i+4:]
}
}

View File

@@ -0,0 +1,147 @@
package helps
import (
"strings"
"testing"
"github.com/tidwall/gjson"
)
// referenceIsClaudeTitleHelperRequest is isClaudeTitleHelperRequest without
// the jsonMayContainASCII pre-filter (the v8.0.11 implementation).
func referenceIsClaudeTitleHelperRequest(body []byte) bool {
props := gjson.GetBytes(body, "output_config.format.schema.properties")
if props.Exists() {
if props.Get("title").Exists() && len(props.Map()) == 1 {
return isClaudeTitleHelperInstruction(body)
}
return false
}
matchesSystemTitleInstruction := func(t string) bool {
return strings.Contains(t, "naming a coding session") ||
strings.Contains(t, "Return a short title") ||
strings.Contains(t, "Write the title in the predominant language")
}
system := gjson.GetBytes(body, "system")
if system.IsArray() {
for _, part := range system.Array() {
if matchesSystemTitleInstruction(part.Get("text").String()) {
return true
}
}
} else if matchesSystemTitleInstruction(system.String()) {
return true
}
messages := gjson.GetBytes(body, "messages")
if messages.IsArray() {
for _, msg := range messages.Array() {
if msg.Get("role").String() == "system" {
content := msg.Get("content")
if content.IsArray() {
for _, part := range content.Array() {
if matchesSystemTitleInstruction(part.Get("text").String()) {
return true
}
}
} else if matchesSystemTitleInstruction(content.String()) {
return true
}
}
}
}
return false
}
// referenceClaudePayloadHas1hTTL is ClaudePayloadHas1hTTL without the
// jsonMayContainASCII pre-filter (the v8.0.11 implementation).
func referenceClaudePayloadHas1hTTL(payload []byte) bool {
if len(payload) == 0 || !gjson.ValidBytes(payload) {
return false
}
has1h := false
checkBlock := func(item gjson.Result) bool {
cc := item.Get("cache_control")
if cc.IsObject() && cc.Get("ttl").String() == "1h" {
has1h = true
return false
}
return true
}
for _, key := range []string{"tools", "system"} {
if arr := gjson.GetBytes(payload, key); arr.IsArray() {
arr.ForEach(func(_, item gjson.Result) bool {
return checkBlock(item)
})
if has1h {
return true
}
}
}
if messages := gjson.GetBytes(payload, "messages"); messages.IsArray() {
messages.ForEach(func(_, msg gjson.Result) bool {
content := msg.Get("content")
if content.IsArray() {
content.ForEach(func(_, item gjson.Result) bool {
return checkBlock(item)
})
}
return !has1h
})
}
return has1h
}
// bs is one backslash; the seeds below build JSON escapes from it.
const bs = `\`
var prefilterSeeds = []string{
``,
`{}`,
`not json`,
`{"system":"naming a coding session"}`,
`{"system":"naming a` + bs + `u0020coding session"}`,
`{"system":[{"text":"Return a short ` + bs + `u0074itle"}]}`,
`{"system":"Return a short title`,
`{"messages":[{"role":"system","content":[{"text":"Write the title in the predominant language"}]}]}`,
`{"messages":[{"role":"system","content":"naming a coding session"}`,
`{"output_config":{"format":{"schema":{"properties":{"title":{}}}}},"messages":[{"content":"<session>"}]}`,
`{"output_` + bs + `u0063onfig":{"format":{"schema":{"properties":{"title":{}}}}},"system":"Return a short title"}`,
`{"output_config":{"format":{"schema":{"properties":{"title":{},"x":{}}}}}}`,
`{"system":"` + bs + `ud83d` + bs + `ude00 naming a coding session"}`,
`{"system":"` + bs + `/naming a coding session` + bs + `"}`,
`{"system":"` + bs + bs + `u0041 naming"}`,
`{"system":"` + bs + `u00`,
`{"messages":[{"content":[{"cache_control":{"ttl":"1h"}}]}]}`,
`{"messages":[{"content":[{"cache_control":{"ttl":"` + bs + `u0031h"}}]}]}`,
`{"tools":[{"cache_control":{"ttl":"1` + bs + `u0068"}}]}`,
`{"system":[{"cache_control":{"ttl":"5m"}}],"note":"1h"}`,
`{"tools":[{"cache_control":{"ttl":"1h"}}]}`,
`{"messages":[{"content":[{"cache_control":{"ttl":1}}]}]}`,
}
func checkPrefilterEquivalence(t *testing.T, body []byte) {
t.Helper()
if got, want := isClaudeTitleHelperRequest(body), referenceIsClaudeTitleHelperRequest(body); got != want {
t.Fatalf("isClaudeTitleHelperRequest(%q) = %v, reference %v", body, got, want)
}
if got, want := ClaudePayloadHas1hTTL(body), referenceClaudePayloadHas1hTTL(body); got != want {
t.Fatalf("ClaudePayloadHas1hTTL(%q) = %v, reference %v", body, got, want)
}
}
func TestPrefilterMatchesReferenceOnSeeds(t *testing.T) {
for _, seed := range prefilterSeeds {
checkPrefilterEquivalence(t, []byte(seed))
}
}
// FuzzPrefilterMatchesReference checks the pre-filtered classifiers against
// the full walks on arbitrary bytes: go test -fuzz FuzzPrefilterMatchesReference
func FuzzPrefilterMatchesReference(f *testing.F) {
for _, seed := range prefilterSeeds {
f.Add([]byte(seed))
}
f.Fuzz(func(t *testing.T, body []byte) {
checkPrefilterEquivalence(t, body)
})
}

View File

@@ -0,0 +1,137 @@
package helps
import (
"fmt"
"strings"
"testing"
)
func TestJSONMayContainASCII(t *testing.T) {
tests := []struct {
name string
body string
needles []string
want bool
}{
{"absent", `{"system":"hello"}`, []string{"naming a coding session"}, false},
{"present", `{"system":"naming a coding session"}`, []string{"naming a coding session"}, true},
{"any needle", `{"output_config":{}}`, []string{"naming", "output_config"}, true},
{"escaped space falls back", `{"system":"naming a\u0020coding session"}`, []string{"naming a coding session"}, true},
{"escaped letter falls back", `{"s":"n\u0061ming"}`, []string{"naming"}, true},
{"upper hex falls back", `{"s":"\u004E"}`, []string{"N"}, true},
{"escaped backslash is conservative", `{"s":"\\u0041"}`, []string{"zzz"}, true},
{"control escape keeps shortcut", `{"s":"a\u001bbé"}`, []string{"naming"}, false},
{"truncated escape", `{"s":"\u00`, []string{"naming"}, false},
{"quoted value", `{"ttl":"1h"}`, []string{`"1h"`}, true},
{"quoted value absent", `{"ttl":"5m","note":"11h"}`, []string{`"1h"`}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := jsonMayContainASCII([]byte(tt.body), tt.needles...); got != tt.want {
t.Fatalf("jsonMayContainASCII(%s, %q) = %v, want %v", tt.body, tt.needles, got, tt.want)
}
})
}
}
// The pre-filters must never change an answer, including when the matched
// text is spelled with \u escapes.
func TestPrefilteredClassifiersKeepEscapedMatches(t *testing.T) {
escapedTitle := `{"model":"m","system":[{"type":"text","text":"You are naming a\u0020coding session."}],` +
`"messages":[{"role":"user","content":"hi"}]}`
if !isClaudeTitleHelperRequest([]byte(escapedTitle)) {
t.Fatal("escaped system title instruction must still be detected")
}
plainTitle := `{"model":"m","system":"Return a short title for this.","messages":[{"role":"user","content":"hi"}]}`
if !isClaudeTitleHelperRequest([]byte(plainTitle)) {
t.Fatal("plain system title instruction must be detected")
}
schemaTitle := `{"model":"m","output_config":{"format":{"schema":{"properties":{"title":{"type":"string"}}}}},` +
`"messages":[{"role":"user","content":"<session>x</session>"}]}`
if !isClaudeTitleHelperRequest([]byte(schemaTitle)) {
t.Fatal("title schema request must be detected")
}
ordinary := `{"model":"m","system":"You are Claude Code.","messages":[{"role":"user","content":"Return a short answer"}]}`
if isClaudeTitleHelperRequest([]byte(ordinary)) {
t.Fatal("ordinary request must not be a title helper")
}
escaped1h := `{"messages":[{"role":"user","content":[{"type":"text","text":"x","cache_control":{"type":"ephemeral","ttl":"\u0031h"}}]}]}`
if !ClaudePayloadHas1hTTL([]byte(escaped1h)) {
t.Fatal("escaped 1h ttl must still be detected")
}
fiveMinutes := `{"messages":[{"role":"user","content":[{"type":"text","text":"took 11h","cache_control":{"type":"ephemeral","ttl":"5m"}}]}]}`
if ClaudePayloadHas1hTTL([]byte(fiveMinutes)) {
t.Fatal("5m ttl must not count as 1h")
}
}
// largeClaudeCodeBody builds a Claude Code style request with n tool round
// trips, about 2.2 KB each, ending with the top-level keys Claude Code sends
// after messages.
func largeClaudeCodeBody(n int) []byte {
var b strings.Builder
b.WriteString(`{"model":"claude-opus-5-5","messages":[`)
output := strings.Repeat(`line of tool output with \"quotes\", tabs\t and a \u001b[0m reset `, 30)
for i := 0; i < n; i++ {
if i > 0 {
b.WriteByte(',')
}
fmt.Fprintf(&b, `{"role":"assistant","content":[{"type":"tool_use","id":"toolu_%d","name":"Bash","input":{"command":"ls %d"}}]},`, i, i)
fmt.Fprintf(&b, `{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_%d","content":"%s"}]}`, i, output)
}
b.WriteString(`],"system":[{"type":"text","text":"x-anthropic-billing-header: cc_version=2.1.286;"},`)
b.WriteString(`{"type":"text","text":"You are Claude Code.","cache_control":{"type":"ephemeral","ttl":"5m"}}],`)
b.WriteString(`"tools":[{"name":"Bash","input_schema":{"type":"object"}}],"metadata":{"user_id":"u"},`)
b.WriteString(`"max_tokens":64000,"thinking":{"type":"adaptive"},"stream":true}`)
return []byte(b.String())
}
func BenchmarkIsClaudeProbeOrHelperRequestLarge(b *testing.B) {
body := largeClaudeCodeBody(1500)
b.SetBytes(int64(len(body)))
b.ResetTimer()
for i := 0; i < b.N; i++ {
if IsClaudeProbeOrHelperRequest(body) {
b.Fatal("ordinary request classified as probe or helper")
}
}
}
func BenchmarkClaudePayloadHas1hTTLLarge(b *testing.B) {
body := largeClaudeCodeBody(1500)
b.SetBytes(int64(len(body)))
b.ResetTimer()
for i := 0; i < b.N; i++ {
if ClaudePayloadHas1hTTL(body) {
b.Fatal("5m payload reported as 1h")
}
}
}
// The worst cases: a printable-ASCII escape forces the full walk, so the
// pre-filter's scan is pure overhead.
func BenchmarkClaudePayloadHas1hTTLLargeEscapeFallback(b *testing.B) {
body := largeClaudeCodeBody(1500)
body = append([]byte(`{"note":"\u0041",`), body[1:]...)
b.SetBytes(int64(len(body)))
b.ResetTimer()
for i := 0; i < b.N; i++ {
if ClaudePayloadHas1hTTL(body) {
b.Fatal("5m payload reported as 1h")
}
}
}
func BenchmarkClaudePayloadHas1hTTLLargeEscapeFallbackLate(b *testing.B) {
body := largeClaudeCodeBody(1500)
if len(body) > 1 && body[len(body)-1] == '}' {
body = append(body[:len(body)-1], []byte(`,"late_escape":"\u0041"}`)...)
}
b.SetBytes(int64(len(body)))
b.ResetTimer()
for i := 0; i < b.N; i++ {
if ClaudePayloadHas1hTTL(body) {
b.Fatal("5m payload reported as 1h")
}
}
}