From 0128881d0438820641b0d15d56407f3191b3160e Mon Sep 17 00:00:00 2001 From: tommy0103 Date: Sun, 7 Jun 2026 18:35:08 +0800 Subject: [PATCH] docs: add learned-facet detail pass and session-window pitfall Teach the agent to derive second-pass filters from first-pass evidence instead of pulling large message windows. Add the pattern and a pitfall warning against defaulting to LIMIT 25 transcript browsing. --- SKILL.md | 2 +- references/pitfalls.md | 17 ++++++++++ references/query-patterns.md | 66 ++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/SKILL.md b/SKILL.md index 93bf602..7eeb125 100644 --- a/SKILL.md +++ b/SKILL.md @@ -138,7 +138,7 @@ Keep queries scoped, bounded, and structural. - Treat project scope as three distinct semantics: exact `sessions.project` slug, exact `sessions.project_path`, or fuzzy `LIKE` search. Use `sql()` for exact slug/path membership; helper `project` means fuzzy `LIKE`. - Start with cheap locators: `sessions()`, `summaries()`, `search()`, or a small SQL query. - Expand incrementally with `context()`, `trace()`, neighbor SQL, or `raw()` windows. -- For conclusion, broad history, failure investigation, or file evolution questions, prefer one bounded query script that locates, expands, dedupes, groups, and returns compact evidence rows. Do not spend multiple conversation turns showing intermediate query results. +- For conclusion, broad history, failure investigation, or file evolution questions, prefer one bounded query script that locates, expands, dedupes, groups, and returns compact evidence rows. If a second detail pass is needed, derive its filters or facets from the first pass; do not dump whole session windows by default. - Return compact evidence with stable IDs (`session_id`, `uuid`, `tool_call_id`, `run_id`, `agent_id`) and short snippets. - Avoid `thread()` unless the user explicitly asks for a full transcript or all smaller probes are insufficient. - Keep runtime JSON small, ideally under 10k-12k chars for synthesis tasks. Do not return all sessions, all summaries, all tool calls, complete workflow trees, full raw messages, or whole tool results. diff --git a/references/pitfalls.md b/references/pitfalls.md index 51e43cf..eb897ef 100644 --- a/references/pitfalls.md +++ b/references/pitfalls.md @@ -125,6 +125,23 @@ the script: Do not show every intermediate result to the conversation. Return the final compact evidence view, then use the model for the conclusion. +## Session Windows Are Not Evidence Plans + +After finding a relevant session, avoid defaulting to `LIMIT 25` or `LIMIT 40` +message windows. That is transcript browsing in miniature: it often brings back +thinking, transitions, and repeated context instead of the evidence needed for +the question. + +Preferred detail pass: + +1. extract candidate terms, files, tools, or decisions from the first pass; +2. query by learned facets inside the candidate sessions; +3. return 2-4 rows per facet, 8-12 rows total, with 160-220 char snippets. + +If the vocabulary is still unclear, use a small session window as fallback: +5-8 rows per session, filtered by timestamp, role, or discovered terms when +possible, and explain the fallback in `query_plan`. + ## Compact Vs Raw Default to compact evidence. Raw/full access is a conscious escalation. diff --git a/references/query-patterns.md b/references/query-patterns.md index 206def3..2f45983 100644 --- a/references/query-patterns.md +++ b/references/query-patterns.md @@ -92,6 +92,72 @@ return { }; ``` +## Learned Faceted Detail Pass + +Use this after a broad sweep has identified candidate sessions and vocabulary. +Prefer detail facets learned from the first pass over pulling large session +windows. Fall back to small filtered windows only when the vocabulary is still +unclear, and record that reason in `query_plan`. + +```js +const sessionIds = [ + 'first-pass-session-id-a', + 'first-pass-session-id-b', +]; + +const learnedFacets = [ + { facet: 'architecture comparison', terms: ['ultrawork', 'TaskTree', 'parallel'] }, + { facet: 'key judgment', terms: ['ridiculous', 'serial', 'parallel'] }, + { facet: 'merge direction', terms: ['replan', 'merge', 'workflow'] }, + { facet: 'prompt observation', terms: ['prompt', 'guideline', 'skill'] }, +]; + +const rows = []; +for (const { facet, terms } of learnedFacets) { + const clauses = terms.map(() => 'm.text LIKE ?').join(' OR '); + const params = [ + ...sessionIds, + ...terms.map(t => `%${t}%`), + ]; + rows.push(...sql(` + SELECT + ? AS facet, + m.uuid, + m.session_id, + s.title AS session_title, + m.timestamp, + substr(m.text, 1, 220) AS snippet + FROM messages m + JOIN sessions s ON s.id = m.session_id + WHERE m.session_id IN (${sessionIds.map(() => '?').join(',')}) + AND m.text IS NOT NULL + AND (${clauses}) + ORDER BY m.timestamp + LIMIT 3 + `, facet, ...params)); +} + +const seen = new Set(); +const evidence = []; +for (const row of rows) { + if (seen.has(row.uuid)) continue; + seen.add(row.uuid); + evidence.push(row); + if (evidence.length >= 12) break; +} + +return { + query_plan: { + mode: 'learned_faceted_detail', + source: 'terms discovered in first pass', + session_count: sessionIds.length, + facets: learnedFacets.map(f => f.facet), + per_facet_limit: 3, + }, + evidence, +}; +``` + ## Facet Sweep For Broad History Use this only for broad synthesis questions such as "how did X evolve", "what