coreprinciple Claude Opus 4.8 commited on
Commit
f1b269b
·
1 Parent(s): 54646ca

Narration: kill label-parroting at the source + reduce gate false positives

Browse files

Traces showed two remaining issues: the model parroted 'park garden'/'place of
worship' from the 'Weights extracted:' prompt line (removed it + dropped the now
dead _weights_summary), and the gate kept rejecting lone sentence-starters
('Stepping'). Add a comprehensive common-word set instead of a blanket single-word
pass (which had let the planted 'Eiffel Tower' through). Guarantee intact: all
multi-word invented venues still caught.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

src/discoverroute/narrate/grounding.py CHANGED
@@ -38,8 +38,20 @@ _COMMON = {
38
  "just", "main", "canvas", "serene", "golden", "thread", "serendipity",
39
  "awaits", "loop", "tucked", "secret", "alcove", "heart", "memory", "story",
40
  "stories", "forgotten", "damp", "concrete", "dusty", "afternoon", "sky",
41
- "subway", "grid", "skyscrapers", "skyscraper", "serenity", "canvas", "echoes",
42
  "whisper", "whispers", "glow", "shimmer", "quietude",
 
 
 
 
 
 
 
 
 
 
 
 
43
  # template/narration sentence-starters and connective words
44
  "why", "spending", "every", "threads", "discoveries", "real", "spot",
45
  "nothing", "invented", "breath", "hush", "shelves", "stalls", "something",
 
38
  "just", "main", "canvas", "serene", "golden", "thread", "serendipity",
39
  "awaits", "loop", "tucked", "secret", "alcove", "heart", "memory", "story",
40
  "stories", "forgotten", "damp", "concrete", "dusty", "afternoon", "sky",
41
+ "subway", "grid", "skyscrapers", "skyscraper", "serenity", "echoes",
42
  "whisper", "whispers", "glow", "shimmer", "quietude",
43
+ # common sentence-starting verbs/adverbs the model opens clauses with — never
44
+ # venues, but capitalized at a sentence boundary the extractor would flag them.
45
+ "stepping", "step", "begin", "beginning", "enter", "entering", "exit",
46
+ "leave", "leaving", "approach", "approaching", "imagine", "imagining",
47
+ "picture", "notice", "noticing", "feel", "feeling", "soon", "duck", "ducking",
48
+ "glance", "linger", "lingering", "explore", "exploring", "discover",
49
+ "discovering", "meander", "meandering", "amble", "ambling", "saunter",
50
+ "sauntering", "carry", "carrying", "move", "moving", "emerge", "emerging",
51
+ "drift", "drifting", "ahead", "beyond", "below", "above", "around", "alongside",
52
+ "tucked", "nestled", "perched", "wrapped", "framed", "lit", "bathed",
53
+ "morning", "midday", "twilight", "moment", "moments", "pause", "rest",
54
+ "finally", "eventually", "meanwhile", "soon", "shortly", "nearby", "opposite",
55
  # template/narration sentence-starters and connective words
56
  "why", "spending", "every", "threads", "discoveries", "real", "spot",
57
  "nothing", "invented", "breath", "hush", "shelves", "stalls", "something",
src/discoverroute/narrate/narrate.py CHANGED
@@ -230,15 +230,6 @@ def narrate(plain, discovery, pois, vibe="", mode="walk", start_label="",
230
  return template, False # fail-closed: ship the grounded template
231
 
232
 
233
- def _weights_summary(weights) -> str:
234
- """Compact 'cafe 0.9, park 0.7' line from the extracted weights, if any."""
235
- aff = getattr(weights, "category_affinity", None)
236
- if not aff:
237
- return ""
238
- top = sorted(aff, key=aff.get, reverse=True)[:5]
239
- return ", ".join(f"{c.replace('_', ' ')} {aff[c]:.2f}" for c in top)
240
-
241
-
242
  def _llm_narration(plain, discovery, pois, vibe, mode, start_label, end_label,
243
  weights=None, geo_allowed=None, city_label="") -> str:
244
  """Generate narration with MiniCPM5-1B, constrained to the allowed names.
@@ -257,7 +248,6 @@ def _llm_narration(plain, discovery, pois, vibe, mode, start_label, end_label,
257
  bullet = "\n".join(f"- {n}" for n in names)
258
  extra = round(discovery.time_min - plain.time_min)
259
  total_min = round(discovery.time_min + getattr(discovery, "dwell_s", 0.0) / 60.0)
260
- weights_line = _weights_summary(weights)
261
  guide = f"{city_label} " if city_label else ""
262
  context_terms = ", ".join(geo_allowed) if geo_allowed else ""
263
 
@@ -284,7 +274,6 @@ def _llm_narration(plain, discovery, pois, vibe, mode, start_label, end_label,
284
  )
285
  user = (
286
  f"Vibe: {vibe or 'open to anything'}\n"
287
- + (f"Weights extracted: {weights_line}\n" if weights_line else "")
288
  + f"Mode: {mode} from {start_label or 'the start'} to "
289
  f"{end_label or 'the destination'}\n"
290
  + (f"You may reference (scene-setting, name freely): {context_terms}\n"
 
230
  return template, False # fail-closed: ship the grounded template
231
 
232
 
 
 
 
 
 
 
 
 
 
233
  def _llm_narration(plain, discovery, pois, vibe, mode, start_label, end_label,
234
  weights=None, geo_allowed=None, city_label="") -> str:
235
  """Generate narration with MiniCPM5-1B, constrained to the allowed names.
 
248
  bullet = "\n".join(f"- {n}" for n in names)
249
  extra = round(discovery.time_min - plain.time_min)
250
  total_min = round(discovery.time_min + getattr(discovery, "dwell_s", 0.0) / 60.0)
 
251
  guide = f"{city_label} " if city_label else ""
252
  context_terms = ", ".join(geo_allowed) if geo_allowed else ""
253
 
 
274
  )
275
  user = (
276
  f"Vibe: {vibe or 'open to anything'}\n"
 
277
  + f"Mode: {mode} from {start_label or 'the start'} to "
278
  f"{end_label or 'the destination'}\n"
279
  + (f"You may reference (scene-setting, name freely): {context_terms}\n"