Spaces:
Running on Zero
Running on Zero
Commit ·
f440fba
1
Parent(s): 36d6af8
Narration: expand per-city gazetteer with famous landmarks (loosen gate)
Browse filesThe 1B name-drops real landmarks (Arc de Triomphe, Sacre-Coeur, Edo
Castle...) for scene-setting; the strict gate rejected them -> template.
Add curated landmark allowlists per pre-baked city so that grounded,
vivid prose passes instead. Eiffel Tower stays OFF the list (the planted
hallucination the gate must keep catching) and invented venues still
fail. Narration prompt realigned: name the 'You may reference' places
freely, never anything outside the lists.
Test: test_geo_gazetteer_allows_landmarks_but_not_eiffel.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
src/discoverroute/narrate/gazetteer.py
CHANGED
|
@@ -34,9 +34,18 @@ CITY_GAZETTEER: dict[str, list[str]] = {
|
|
| 34 |
"Le Marais", "Marais", "Quartier Latin", "Latin Quarter",
|
| 35 |
"Saint-Germain", "Saint-Germain-des-Prés", "Montmartre", "Montparnasse",
|
| 36 |
"Belleville", "Bastille", "Pigalle", "Oberkampf", "Le Sentier",
|
| 37 |
-
# well-known landmarks/areas a guide name-checks in passing
|
|
|
|
|
|
|
| 38 |
"Sorbonne", "Panthéon", "Champs-Élysées", "Tuileries", "Louvre",
|
| 39 |
-
"Notre-Dame", "Île-de-France",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
],
|
| 41 |
"london": [
|
| 42 |
"Thames", "South Bank", "Southbank", "North Bank", "the City",
|
|
@@ -44,12 +53,27 @@ CITY_GAZETTEER: dict[str, list[str]] = {
|
|
| 44 |
"Southwark", "Lambeth", "Vauxhall", "Holborn", "Clerkenwell",
|
| 45 |
"Fitzrovia", "Marylebone", "the West End", "the East End", "Shoreditch",
|
| 46 |
"Bankside", "Embankment", "Strand", "Piccadilly",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
],
|
| 48 |
"barcelona": [
|
| 49 |
"Mediterranean", "Barri Gòtic", "Gothic Quarter", "El Raval", "El Born",
|
| 50 |
"La Ribera", "Eixample", "La Rambla", "Las Ramblas", "Barceloneta",
|
| 51 |
"Gràcia", "Montjuïc", "Poble Sec", "Ciutat Vella", "Port Vell",
|
| 52 |
"Passeig de Gràcia",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
],
|
| 54 |
"newyork": [
|
| 55 |
"Manhattan", "Midtown", "Downtown", "Uptown", "SoHo", "NoHo", "Tribeca",
|
|
@@ -61,33 +85,65 @@ CITY_GAZETTEER: dict[str, list[str]] = {
|
|
| 61 |
"the Garment District", "Hell's Kitchen", "Murray Hill", "Koreatown",
|
| 62 |
"Herald Square", "Madison Square", "the High Line", "Rockefeller Center",
|
| 63 |
"Grand Central", "Penn Station", "Bryant Park",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
],
|
| 65 |
"sanfrancisco": [
|
| 66 |
"San Francisco", "Union Square", "the Financial District", "North Beach",
|
| 67 |
"Chinatown", "Nob Hill", "Russian Hill", "Telegraph Hill", "the Embarcadero",
|
| 68 |
"SoMa", "the Mission", "Hayes Valley", "the Tenderloin", "Fisherman's Wharf",
|
| 69 |
"the Marina", "Market Street", "the Bay", "San Francisco Bay",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
],
|
| 71 |
"tokyo": [
|
| 72 |
"Tokyo", "Ginza", "Marunouchi", "Nihonbashi", "Yurakucho", "Tokyo Station",
|
| 73 |
"the Imperial Palace", "Chiyoda", "Hibiya", "Kanda", "Otemachi",
|
| 74 |
"Shimbashi", "Tsukiji", "the Sumida", "the Sumida River",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
],
|
| 76 |
"mumbai": [
|
| 77 |
"Mumbai", "Colaba", "Fort", "Marine Drive", "Churchgate", "Nariman Point",
|
| 78 |
"Kala Ghoda", "Ballard Estate", "Cuffe Parade", "South Mumbai",
|
| 79 |
"the Gateway of India", "the Arabian Sea",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
],
|
| 81 |
"shanghai": [
|
| 82 |
"Shanghai", "the Bund", "People's Square", "Huangpu", "the Huangpu River",
|
| 83 |
"Nanjing Road", "Yu Garden", "the French Concession", "Jing'an",
|
| 84 |
"Lujiazui", "Xintiandi", "the Old City",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
],
|
| 86 |
"berlin": [
|
| 87 |
"Berlin", "Mitte", "the Spree", "Museum Island", "Unter den Linden",
|
| 88 |
"Alexanderplatz", "the Brandenburg Gate", "Kreuzberg", "Prenzlauer Berg",
|
| 89 |
"Friedrichshain", "Hackescher Markt", "Gendarmenmarkt", "Potsdamer Platz",
|
| 90 |
"the Tiergarten",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
],
|
| 92 |
}
|
| 93 |
|
|
|
|
| 34 |
"Le Marais", "Marais", "Quartier Latin", "Latin Quarter",
|
| 35 |
"Saint-Germain", "Saint-Germain-des-Prés", "Montmartre", "Montparnasse",
|
| 36 |
"Belleville", "Bastille", "Pigalle", "Oberkampf", "Le Sentier",
|
| 37 |
+
# well-known landmarks/areas a guide name-checks in passing.
|
| 38 |
+
# NOTE: the Eiffel Tower is deliberately NOT listed — it's the planted
|
| 39 |
+
# hallucination the zero-hallucination gate must keep catching.
|
| 40 |
"Sorbonne", "Panthéon", "Champs-Élysées", "Tuileries", "Louvre",
|
| 41 |
+
"Notre-Dame", "Île-de-France", "Arc de Triomphe", "Sacré-Cœur",
|
| 42 |
+
"Sacre-Coeur", "Pont Neuf", "Pont des Arts", "Palais Garnier",
|
| 43 |
+
"Opéra Garnier", "Grand Palais", "Petit Palais", "Place de la Concorde",
|
| 44 |
+
"Place Vendôme", "Place des Vosges", "Place de la République",
|
| 45 |
+
"Jardin du Luxembourg", "Luxembourg Gardens", "Jardin des Tuileries",
|
| 46 |
+
"Centre Pompidou", "Musée d'Orsay", "Orsay", "Hôtel de Ville",
|
| 47 |
+
"Trocadéro", "Les Invalides", "Invalides", "La Madeleine",
|
| 48 |
+
"Père Lachaise", "Bois de Boulogne", "Bois de Vincennes", "Mona Lisa",
|
| 49 |
],
|
| 50 |
"london": [
|
| 51 |
"Thames", "South Bank", "Southbank", "North Bank", "the City",
|
|
|
|
| 53 |
"Southwark", "Lambeth", "Vauxhall", "Holborn", "Clerkenwell",
|
| 54 |
"Fitzrovia", "Marylebone", "the West End", "the East End", "Shoreditch",
|
| 55 |
"Bankside", "Embankment", "Strand", "Piccadilly",
|
| 56 |
+
# landmarks
|
| 57 |
+
"Big Ben", "the Tower of London", "Tower Bridge", "London Bridge",
|
| 58 |
+
"St Paul's", "St Paul's Cathedral", "Buckingham Palace",
|
| 59 |
+
"Trafalgar Square", "Leicester Square", "the Shard", "the Gherkin",
|
| 60 |
+
"the London Eye", "Hyde Park", "Regent's Park", "St James's Park",
|
| 61 |
+
"Green Park", "the British Museum", "Tate Modern", "the National Gallery",
|
| 62 |
+
"Borough Market", "Camden", "Camden Town", "Notting Hill", "Kensington",
|
| 63 |
+
"Greenwich", "Canary Wharf", "the Barbican", "Whitehall",
|
| 64 |
+
"Downing Street", "the Houses of Parliament", "Westminster Abbey",
|
| 65 |
],
|
| 66 |
"barcelona": [
|
| 67 |
"Mediterranean", "Barri Gòtic", "Gothic Quarter", "El Raval", "El Born",
|
| 68 |
"La Ribera", "Eixample", "La Rambla", "Las Ramblas", "Barceloneta",
|
| 69 |
"Gràcia", "Montjuïc", "Poble Sec", "Ciutat Vella", "Port Vell",
|
| 70 |
"Passeig de Gràcia",
|
| 71 |
+
# landmarks
|
| 72 |
+
"Sagrada Família", "Sagrada Familia", "Park Güell", "Casa Batlló",
|
| 73 |
+
"Casa Milà", "La Pedrera", "Plaça de Catalunya", "Plaça Reial",
|
| 74 |
+
"the Cathedral", "Catedral", "Camp Nou", "Tibidabo", "Arc de Triomf",
|
| 75 |
+
"La Boqueria", "Mercat de la Boqueria", "Port Olímpic",
|
| 76 |
+
"Barceloneta Beach",
|
| 77 |
],
|
| 78 |
"newyork": [
|
| 79 |
"Manhattan", "Midtown", "Downtown", "Uptown", "SoHo", "NoHo", "Tribeca",
|
|
|
|
| 85 |
"the Garment District", "Hell's Kitchen", "Murray Hill", "Koreatown",
|
| 86 |
"Herald Square", "Madison Square", "the High Line", "Rockefeller Center",
|
| 87 |
"Grand Central", "Penn Station", "Bryant Park",
|
| 88 |
+
# landmarks
|
| 89 |
+
"the Empire State Building", "the Chrysler Building",
|
| 90 |
+
"the Statue of Liberty", "the Brooklyn Bridge", "Wall Street",
|
| 91 |
+
"Washington Square", "Washington Square Park", "Madison Square Garden",
|
| 92 |
+
"the Met", "the Metropolitan Museum", "MoMA", "the Guggenheim",
|
| 93 |
+
"the Flatiron Building", "Battery Park", "Columbus Circle",
|
| 94 |
+
"Lincoln Center", "Little Italy", "Nolita", "the Meatpacking District",
|
| 95 |
],
|
| 96 |
"sanfrancisco": [
|
| 97 |
"San Francisco", "Union Square", "the Financial District", "North Beach",
|
| 98 |
"Chinatown", "Nob Hill", "Russian Hill", "Telegraph Hill", "the Embarcadero",
|
| 99 |
"SoMa", "the Mission", "Hayes Valley", "the Tenderloin", "Fisherman's Wharf",
|
| 100 |
"the Marina", "Market Street", "the Bay", "San Francisco Bay",
|
| 101 |
+
# landmarks
|
| 102 |
+
"the Golden Gate Bridge", "the Golden Gate", "Alcatraz", "Coit Tower",
|
| 103 |
+
"Lombard Street", "the Painted Ladies", "Alamo Square",
|
| 104 |
+
"the Ferry Building", "Pier 39", "the Presidio", "Golden Gate Park",
|
| 105 |
+
"the Castro", "Haight-Ashbury", "the Haight", "Twin Peaks",
|
| 106 |
+
"the Transamerica Pyramid", "Ghirardelli Square", "Dolores Park",
|
| 107 |
],
|
| 108 |
"tokyo": [
|
| 109 |
"Tokyo", "Ginza", "Marunouchi", "Nihonbashi", "Yurakucho", "Tokyo Station",
|
| 110 |
"the Imperial Palace", "Chiyoda", "Hibiya", "Kanda", "Otemachi",
|
| 111 |
"Shimbashi", "Tsukiji", "the Sumida", "the Sumida River",
|
| 112 |
+
# landmarks / districts
|
| 113 |
+
"Tokyo Tower", "Tokyo Skytree", "Sensō-ji", "Senso-ji", "Asakusa",
|
| 114 |
+
"Shibuya", "Shibuya Crossing", "Shinjuku", "Harajuku", "Akihabara",
|
| 115 |
+
"Ueno", "Ueno Park", "Roppongi", "Meiji Shrine", "Edo Castle",
|
| 116 |
+
"Hibiya Park",
|
| 117 |
],
|
| 118 |
"mumbai": [
|
| 119 |
"Mumbai", "Colaba", "Fort", "Marine Drive", "Churchgate", "Nariman Point",
|
| 120 |
"Kala Ghoda", "Ballard Estate", "Cuffe Parade", "South Mumbai",
|
| 121 |
"the Gateway of India", "the Arabian Sea",
|
| 122 |
+
# landmarks
|
| 123 |
+
"Chhatrapati Shivaji Terminus", "the Taj Mahal Palace", "Haji Ali",
|
| 124 |
+
"Girgaum Chowpatty", "Chowpatty", "Flora Fountain", "Crawford Market",
|
| 125 |
+
"the Hanging Gardens", "Banganga", "Bandra", "Worli",
|
| 126 |
],
|
| 127 |
"shanghai": [
|
| 128 |
"Shanghai", "the Bund", "People's Square", "Huangpu", "the Huangpu River",
|
| 129 |
"Nanjing Road", "Yu Garden", "the French Concession", "Jing'an",
|
| 130 |
"Lujiazui", "Xintiandi", "the Old City",
|
| 131 |
+
# landmarks
|
| 132 |
+
"the Oriental Pearl Tower", "the Shanghai Tower", "the Jin Mao Tower",
|
| 133 |
+
"the City God Temple", "the Jade Buddha Temple", "Tianzifang",
|
| 134 |
+
"Jing'an Temple", "People's Park", "the Yuyuan Garden",
|
| 135 |
],
|
| 136 |
"berlin": [
|
| 137 |
"Berlin", "Mitte", "the Spree", "Museum Island", "Unter den Linden",
|
| 138 |
"Alexanderplatz", "the Brandenburg Gate", "Kreuzberg", "Prenzlauer Berg",
|
| 139 |
"Friedrichshain", "Hackescher Markt", "Gendarmenmarkt", "Potsdamer Platz",
|
| 140 |
"the Tiergarten",
|
| 141 |
+
# landmarks
|
| 142 |
+
"the Reichstag", "the TV Tower", "Fernsehturm", "Checkpoint Charlie",
|
| 143 |
+
"the Berlin Wall", "the East Side Gallery", "Berliner Dom",
|
| 144 |
+
"the Berlin Cathedral", "the Holocaust Memorial", "Charlottenburg",
|
| 145 |
+
"the Victory Column", "the Siegessäule", "Nikolaiviertel",
|
| 146 |
+
"Kurfürstendamm", "the Pergamon Museum",
|
| 147 |
],
|
| 148 |
}
|
| 149 |
|
src/discoverroute/narrate/narrate.py
CHANGED
|
@@ -268,13 +268,12 @@ def _llm_narration(plain, discovery, pois, vibe, mode, start_label, end_label,
|
|
| 268 |
"Never write bare type labels like 'park garden', 'place of worship' or "
|
| 269 |
"'monument historic'. Mention the time of day or the light.\n"
|
| 270 |
"ONE HARD RULE — NAMES: the ONLY proper names you may write are the 'Ordered "
|
| 271 |
-
"stops', the start/destination, and the
|
| 272 |
-
"
|
| 273 |
-
"
|
| 274 |
-
"
|
| 275 |
-
"
|
| 276 |
-
"
|
| 277 |
-
"makes the entire itinerary get thrown away."
|
| 278 |
)
|
| 279 |
user = (
|
| 280 |
f"Vibe: {vibe or 'open to anything'}\n"
|
|
|
|
| 268 |
"Never write bare type labels like 'park garden', 'place of worship' or "
|
| 269 |
"'monument historic'. Mention the time of day or the light.\n"
|
| 270 |
"ONE HARD RULE — NAMES: the ONLY proper names you may write are the 'Ordered "
|
| 271 |
+
"stops', the start/destination, and the places under 'You may reference'. Name "
|
| 272 |
+
"those freely for scene-setting. Do NOT name ANY place outside those lists — no "
|
| 273 |
+
"other landmark, museum, monument, street or venue, even a real famous one — "
|
| 274 |
+
"and never invent a venue. If you want more scenery, describe it WITHOUT a "
|
| 275 |
+
"proper name ('a stone bridge', 'a grand old church'). A single name outside "
|
| 276 |
+
"the lists makes the entire itinerary get thrown away."
|
|
|
|
| 277 |
)
|
| 278 |
user = (
|
| 279 |
f"Vibe: {vibe or 'open to anything'}\n"
|
tests/test_narration.py
CHANGED
|
@@ -84,6 +84,23 @@ def test_geo_gazetteer_allows_real_districts():
|
|
| 84 |
assert ok, offenders
|
| 85 |
|
| 86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
def test_geo_gazetteer_still_blocks_invented_venue():
|
| 88 |
"""Loosening for districts must NOT let an invented venue through."""
|
| 89 |
from discoverroute.narrate import gazetteer
|
|
|
|
| 84 |
assert ok, offenders
|
| 85 |
|
| 86 |
|
| 87 |
+
def test_geo_gazetteer_allows_landmarks_but_not_eiffel():
|
| 88 |
+
"""Expanded gazetteer lets a guide name real landmarks (Arc de Triomphe,
|
| 89 |
+
Sacré-Cœur) for scene-setting, while the Eiffel Tower — the planted
|
| 90 |
+
hallucination — must STILL be caught."""
|
| 91 |
+
from discoverroute.narrate import gazetteer
|
| 92 |
+
geo = gazetteer.geo_terms("paris", "Paris")
|
| 93 |
+
ok, off = grounding.verify_grounded(
|
| 94 |
+
"From the Arc de Triomphe, wander toward Sacré-Cœur, passing "
|
| 95 |
+
"Jardin des Plantes.", POIS, start_label="Bastille", extra_allowed=geo)
|
| 96 |
+
assert ok, off
|
| 97 |
+
# the famous-landmark allowlist must not punch a hole for the planted one
|
| 98 |
+
ok2, off2 = grounding.verify_grounded(
|
| 99 |
+
"A lovely detour past the Eiffel Tower, then Jardin des Plantes.",
|
| 100 |
+
POIS, start_label="Bastille", extra_allowed=geo)
|
| 101 |
+
assert not ok2 and any("Eiffel" in o for o in off2)
|
| 102 |
+
|
| 103 |
+
|
| 104 |
def test_geo_gazetteer_still_blocks_invented_venue():
|
| 105 |
"""Loosening for districts must NOT let an invented venue through."""
|
| 106 |
from discoverroute.narrate import gazetteer
|