1"""Stage 2: collapse freely-worded intentions onto a shared vocabulary.23`extract_facets.py` runs one API call per session, and no call can see what the4others wrote. However firmly the prompt demands a shared vocabulary, 500 sessions5came back with 487 distinct labels — `create an email workflow`, `build a welcome6email workflow` and `set up onboarding workflow` all describing one job. That is7not a prompt-tuning failure, it is structural: independent calls cannot converge.89This is the pass that fixes it, in two steps:10111. One call that sees every distinct label at once and proposes a canonical12 vocabulary. Seeing them together is the whole point — it is the thing the13 per-session calls could not do.142. Assignment by embedding similarity rather than a second LLM pass, which is
39SYSTEM = """You are given every distinct starting-intention label produced by an extraction pass over MCP sessions, with how many sessions produced each.
40
41Propose a canonical vocabulary of about {target} labels that covers them.
42
43Rules:
44- Each canonical label is a short imperative phrase, 3-8 words, in the same style as the input.
45- Merge labels that describe the same job in different words. "create an email workflow", "build a welcome email workflow" and "set up onboarding workflow" are one job.
46- Keep labels distinct when the job genuinely differs. Checking a configuration is not the same as changing it; sending to email is not the same as sending to a chat channel.
47- Cover the common labels first. A label used by many sessions must have a good canonical home; a one-off can fall back to its own wording.
48- NEVER include a customer, company, project, product, person, or app name.
49
50Two failure modes to avoid, both seen in real runs:
51
52- **Do not emit near-duplicates of your own labels.** "create automation workflows", "build automated workflows" and "create email automation workflow" are one label, not three. If you cannot articulate how two of your labels differ, emit one.
53- **Name the starting point, not the action.** The input labels drift toward describing what the agent did, because that is what the telemetry recorded. "create email automation workflow" is an action. "build an onboarding email sequence" is a starting point: it says what the person wanted before any tool was chosen. A label that could be a button in the product is the wrong altitude.
54
55Return only the vocabulary."""
56
57
58class Vocabulary(BaseModel):
59 labels: list[str] = Field(description="Canonical starting-intention labels, 3-8 words each")