Skip to content
latentSource

Technical report · 4 min read

CDMX Transit: from place names to a computed route

The graph objective, transfer rules, geometry, and saved GTFS evidence behind the assistant.

What the stored data can answer

The assistant combines Gemini, MCP tools, PostGIS, and pgRouting. Its route is calculated from a stored graph. The documented feed snapshot is October 2022, with ridership files through March 2026. A calculated path therefore cannot establish today's closures, service frequency, or actual travel time.

The saved sample contains trip B_02300LB000_1 on route B_CMX0200LB: 21 ordered stops from Ciudad Azteca to Buenavista. It includes the source revision and a hash of gtfs/stop_times.txt. This is a real saved stop sequence, not a recorded model conversation or a freshly requested route.

Architecture and interpretation boundaries

GTFS stops, trips, stop times, shapes → PostGIS → ride/transfer graph
Question → Gemini → MCP place and station lookup → pgRouting
    → nodes, edges, geometry, totals → answer and visible trace

A station request needs resolved graph nodes. A landmark request first needs a place, nearby station candidates, and comparisons including walking at both ends. Choosing the nearest station alone can miss a faster total journey. Ambiguous place resolution should remain visible before a precise route is calculated for the wrong destination.

The inspected agent allows eight iterations and a 30-second tool timeout. Those bounds describe execution, not an observed success rate. The trace separates lookup mistakes, routing errors, and an answer that misstates a correct tool result.

What shortest path actually minimizes

The graph exposes source, target, cost, and reverse cost through v_routing_graph. The inspected pgr_dijkstra call uses directed := false. It minimizes modeled edge costs in seconds under an undirected representation; it does not prove bidirectional service at the requested time.

Consider an illustrative direct ride costing 900 seconds and another path costing 300 + 240 + 300 = 840 seconds. The latter wins even if the traveler dislikes the transfer. Fewer stairs, lower fares, or crowding require explicit objectives or constraints. These example costs explain the calculation and are not measured CDMX journey times.

Transfers and geometry need their own tests

Mode filtering retains transfer edges while filtering rides by agency. Removing transfer edges can disconnect permitted services. Transfer counting groups contiguous rides with overlapping route-ID sets, ends a segment when walking occurs, and returns max(0, ride_segments - 1).

A reversed traversal must reverse its stored LineString coordinates before joining geometry. The response uses longitude, latitude order, and distance comes from ST_Length(e.geom::geography). A plausible line on a map is insufficient: verify node order, endpoint continuity, totals, and transfer count independently of the model's explanation.

Ridership granularity matters too. The app restricts its station heatmap to Metro, where station-level records exist. Allocating a line total across stations would create synthetic values, not station measurements.

A reproducible review sequence

Begin with the saved trip and its ordered stops. Then reproduce the full graph in an isolated database with PostGIS and pgRouting using the repository's ingestion instructions. Test same-line rides, reversed traversals, transfers, unknown IDs, disconnected endpoints, and mode restrictions directly against routing.

Add MCP only after those results are understood, and compare its objects with direct routing responses. Finally run natural-language cases involving duplicate names, landmarks, missing origins, and unavailable places. Save requests, resolved IDs, tool outputs, model configuration, and final answers. That sequence locates failures instead of reducing every bad conversation to one accuracy label.

The source manifest identifies the inspected agent, MCP server, and routing engine. The technical article documents their behavior. These materials support an implementation review; they do not provide a live transit guarantee or a measured natural-language benchmark.