¿Qué hace Planificador de Viajes por Carretera?
Genera un plan de conducción que ha sido verificado por un script, con cada requisito y hecho del mundo real trazable. Un itinerario que suena plausible es el fracaso que este skill existe para evitar: en viajes largos, una distancia incorrecta o una parada de combustible cerrada puede dejar a las personas varadas después del anochecer.
Por qué el flujo de trabajo se ve así
El método proviene de un agente neuro-simbólico de planificación de viajes, y estas lecciones dan forma a los pasos a continuación:
- La mayoría de los errores comienzan en la traducción. Capturar las palabras del viajero en restricciones exactas es más importante que una planificación inteligente, así que los requisitos se escriben y se leen primero en voz alta.
- Un verificador que no depende del modelo detecta lo que el modelo pasa por alto. Tú juzgas qué vale la pena hacer. El script juzga si encaja.
- Los datos vacíos no deben contar como aprobados. Las comprobaciones devuelven PASS, FAIL o UNKNOWN. Reporta UNKNOWN como desconocido, nunca como "está bien".
- Los reintentos ciegos rara vez arreglan algo. Las reparaciones apuntan a un fallo específico y cambian lo mínimo posible.
- Las ediciones no deben retroceder. Una edición se mantiene solo si nada empeoró.
- Pasar el verificador no es el objetivo. Evaluadores más estrictos cierran brechas, y la realidad es la más estricta. Nunca modifiques un número, establezcas
night_oko marques un hecho como verificado solo para que una comprobación se vuelva verde.
Flujo de trabajo
Los scripts están en scripts/ junto a este archivo (route_legs.py, order_stops.py, choose_nights.py, verify_trip.py, render_report.py), y solo necesitan Python estándar. Lee references/plan-format.md antes de escribir un archivo de plan. Mantén el plan como trip.json en la carpeta del viaje del usuario, o en un directorio temporal si no quieren archivos allí.
1. Capturar los requisitos
Extrae lo que el usuario ya ha dicho o proporcionado. Si te dieron un itinerario, impórtalo tal como está escrito, incluyendo sus distancias declaradas como claimed_km, para que sus errores salgan a la luz en lugar de corregirse silenciosamente.
Luego pregunta por lo que aún falta. Lee references/intake.md y sigue sus rondas con la herramienta AskUserQuestion. Si el destino o la ruta no están decididos, comienza con su Ronda 0: 2–3 opciones de ruta investigadas, cada una con sus pros y contras. Las otras rondas cubren ruta y fechas, conductores y licencias, marca de hotel, habitación y presupuesto, distancia diaria y ritmo, intereses y cosas a evitar, lo que ya está reservado, y el idioma y formato de salida. Omite cualquier pregunta ya respondida. Cada respuesta tardía en un viaje real, como la marca de hotel, los mareos o el día de salida, costó una reconstrucción completa, así que hacer algunas preguntas adicionales al principio es más barato que adivinar.
Registra cada requisito como una restricción tipada, con las propias palabras del usuario en nl, y mantén las respuestas restantes en preferences. Lee la lista de nuevo en lenguaje sencillo antes de planificar basándote en ella. Usa manual para cualquier cosa que los tipos no puedan expresar. Separa los verdaderos requisitos de las preferencias, ya que solo los requisitos pertenecen a hard_constraints.
2. Recopilar datos de fuentes
No planifiques de memoria nada que pueda cambiar o que puedas buscar:
-
Distancias y tiempos: ejecuta
route_legs.py trip.json. Utiliza servicios de OpenStreetMap y envía solo nombres de lugares y coordenadas. Si la ruta del enrutador no es la carretera prevista, añade el punto de paso como una parada. Una advertencia deleg_speedgeneralmente significa un mal punto en el mapa, así que corrige las coordenadas y vuelve a enrutar con--forceen lugar de aceptar el tiempo. -
Orden de visitas: para cualquier día con tres o más lugares de interés, ejecuta
order_stops.py trip.json --day N. Sugiere el orden con menos conducción y mantiene los puntos fijos en su lugar: inicio, hotel, y cualquier parada conbe_byo"fixed": true. Si el orden cambia, guárdalo con--write trip_vN.json, vuelve a enrutar, y pruébalo con el verificador contra la versión anterior. El tiempo de conducción no es el único costo, ya que los horarios de apertura, un géiser a las 10:15 o la puesta de sol pueden superar a unos minutos. Mantén el veredicto del verificador sobre el orden más corto. -
Combustible: enumera cada parada de combustible en tramos remotos, con horarios, y marca las paradas con
refuel. Obtén la autonomía real para la clase de vehículo. -
Horarios y cierres: busca horarios de apertura, cierres estacionales, condiciones de carretera y permisos, y registra cada uno con su fuente y fecha. Para cada lugar emblemático, busca también nuevas reglas de reserva en el año del viaje, como entrada con hora asignada, estacionamiento reservado o nuevas tarifas. Busca " reserva necesaria <año>", no solo sus horarios. Tales reglas cambian sin previo aviso: un mirador costero importante comenzó a requerir reservas solo un mes antes de un viaje de prueba.
-
Estas fechas exactas: busca lo que está sucediendo en la ruta en las fechas del viaje, no solo en general: eventos que llenan pueblos, interrupciones de combustible o suministros, obras viales, y días festivos escolares o públicos. Si un itinerario importado se enmarcó en torno a una temporada o mes, vuelve a probar su clima y afirmaciones estacionales con las fechas reales.
-
Horarios fijos: no inventes horarios de vuelos o ferris. Utiliza el billete del viajero, o un horario citado marcado como suposición. Después de un aterrizaje internacional, permite 60–90 minutos para inmigración, bioseguridad y el mostrador de alquiler antes de que el coche se mueva. Antes de una salida, permite el tiempo de facturación de la aerolínea más la devolución del coche.
-
Riesgos de carretera y planes de respaldo: para cada carretera clave en la ruta, verifica su página oficial de cierres o boletines para problemas actuales, como deslizamientos, convoyes u obras viales, y para riesgos estacionales como nieve, inundaciones o incendios. Cuando uno pueda romper el plan, construye una ruta de respaldo como su propio archivo de plan (
trip_vN_B.json) y verifícalo con el verificador como el plan principal. Añade un plan C si la carretera podría cerrarse durante el viaje. Registra cada respaldo encontingenciescon el riesgo, el desencadenante a observar, una fechadecide_by, el plan y la fuente. Aconseja mantener habitaciones cancelables en la ruta de respaldo hasta esa fecha. Una elección A/B con fecha vale más que una advertencia de "verificar antes de ir". -
Hoteles de marca y ciudades para pasar la noche: cuando el viajero quiere una marca, enumera cada uno de sus hoteles dentro de aproximadamente 30 km de cualquier ruta razonable, utilizando el propio sitio de la cadena. Añade cada uno a
overnight_candidatesdel plan, junto con las otras ciudades que podrían funcionar para una noche (conrefuel: truedonde haya combustible). Luego ejecutachoose_nights.py trip.json. Prueba cada disposición de noches y clasifica aquellas dentro de los límites diarios por noches de marca, luego por el día más largo más corto. Guarda la mejor con--write, vuelve a enrutarla, y verifícala. Nunca descartes un hotel de marca adivinando. El script también enumera casi aciertos: disposiciones con más noches de marca que rompen un límite hasta en un 10%. Ofrece el mejor casi acierto al viajero como una opción (por ejemplo, "una segunda noche IHG si un día es 4 h 04 en lugar de 4 h"), y no elijas por ellos. -
Reglas locales: verifica restricciones de alquiler en la ruta, tarifas de ida, reglas fronterizas y de cuarentena, y la hora local del lugar. Registra cada una en
facts. -
Reservas, comidas y preparación: lee
references/prep-and-bookings.md. Coloca cada elemento que necesite reserva en el bloquebookingsdel plan con una fechabook_bybasada en evidencia, para que el verificador marque cualquier cosa vencida o con pago aún no confirmado. Nombra una parada de almuerzo real para cada día largo de conducción. Construye la lista de verificación previa a la salida y la lista de equipaje a partir de lo que realmente contiene este itinerario.
Si no puedes verificar algo, déjalo sin verificar. El plan aún puede seguir adelante, con la brecha visible.
3. Verificar el plan
python3 scripts/verify_trip.py trip.json
El código de salida 0 es PASS, 1 FAIL, 2 UNVERIFIED y 3 un archivo inválido. Lee cada hallazgo. El script proporciona el amanecer y el atardecer para la fecha y ubicación de cada parada, así que no los estimes.
4. Reparar un fallo a la vez
Para cada FAIL, averigua por qué falla y elige el cambio del mundo real más pequeño: salir más temprano, cortar o mover una parada, cambiar la ciudad para pasar la noche. Guárdalo como un archivo nuevo y pruébalo contra el anterior:
python3 scripts/verify_trip.py trip_v2.json --baseline trip.json
Mantén la edición solo si es aceptada. Un rechazo nombra lo que retrocedió, así que usa eso para elegir una corrección diferente, no para volver a intentar la misma. Cuando el usuario solicitó un cambio, añade --user-requested: no necesita mejorar una métrica, pero aún no puede hacer retroceder nada. Cuando una edición añade una nueva parada u hotel, añade --allow-new-unknowns, luego investiga los desconocidos que enumera.
Si ninguna edición corrige un fallo, el viaje no encaja como se especificó. Dilo y ofrece las compensaciones reales, como añadir un día o eliminar una parada, en lugar de aflojar la regla tú mismo.
5. Informe
El plan escrito siempre proviene de render_report.py, así que cada versión tiene las mismas secciones en el mismo orden, y sus horas y distancias no pueden desviarse del verificador:
python3 scripts/render_report.py trip.json --out trip_v3_<Etiqueta>.pdf
El orden fijo es: resumen → día a día → reservas y billetes → hoteles → elementos pendientes → antes de ir → fuentes. Lo que cambia con los deseos del viajero se establece en el bloque report del plan, desde la Ronda 5 de la entrevista, o con opciones de línea de comandos:
lang: cualquier código de idioma, establecido a la elección del viajero. Las etiquetas están integradas paraenyzh. Para cualquier otro idioma, ejecutarender_report.py --print-labels, traduce los valores (mantén los{placeholders}), y guárdalos comoreport.labels; el renderizador advierte sobre cualquier etiqueta que haya tenido que dejar en inglés, así que no entregues mientras esa advertencia permanezca.report.labelstambién puede anular etiquetas individuales enenozh. Los nombres de lugares muestran la etiqueta local más el nombre del mapa. Si un PDF en una escritura no latina muestra cuadros vacíos, establecereport.fonta una fuente que lo cubra ({"regular": ruta, "bold": ruta}); las escrituras de derecha a izquierda se renderizan mejor como HTML o Markdown.format:pdf,htmlomd. También se lee de la extensión del archivo--out.detail:fullusa lanotede cada parada, laintrodel día y sustips;briefusashort.layout(solo Markdown):phone, el predeterminado para Markdown, convierte las tablas en listas para que nada se desplace lateralmente.printmantiene las tablas.
Cuando el viajero pida algo corto, establece detail: brief y layout: phone, elimina las secciones que no necesiten, y mantén report.open_items en un máximo de 6 elementos de una línea. Las advertencias de longitud del renderizador (max_words_per_day, por defecto 200; max_words_total, por defecto 1600) son entonces límites estrictos: acorta las notas short y los elementos abiertos, vuelve a renderizar, y no entregues mientras quede alguna advertencia de longitud. Corta texto, no datos. Un informe largo falla a un viajero que pidió uno corto, por muy bueno que sea su contenido.
sections: cualquier subconjunto de las siete, aún en el orden fijo.
Escribe las palabras tú mismo en el plan, en el idioma del viajero: title, intro y tips del día, note y short de la parada, label del lugar, prep.checklist, prep.packing, y opcionalmente report.open_items para reemplazar los elementos abiertos agrupados automáticamente. El script se niega a escribir un informe que contenga una dirección de correo electrónico. Mantén también los números de teléfono, números de identificación y fechas de nacimiento fuera del plan. Si el viajero pide algo que las secciones fijas no pueden contener, añádelo a los campos de texto del plan en lugar de construir un documento separado manualmente. Si quieren un aspecto diferente, cambia el renderizador una vez para que cada versión posterior lo mantenga.
En el chat, comienza con el veredicto y lo que el usuario necesita decidir o hacer a continuación. Luego incluye:
- Veredicto en palabras sencillas, con los recuentos. "No verificado" significa verificado hasta donde los hechos conocidos lo permiten.
- Problemas encontrados, primero los más graves, cada uno con la corrección realizada o la elección que deben tomar.
- Cronograma por día: salida, paradas, llegada, puesta de sol, km y horas, más la parada de almuerzo en días largos.
- Reservar o confirmar a continuación, ordenado por fecha
book_by, cada uno con su enlace oficial. También nota qué artículos se venden en el lugar. - Aún desconocido, y cómo averiguar cada elemento.
- Antes de ir: la lista de verificación previa a la salida y las notas de equipaje personalizadas, en el documento completo. Mantenlas cortas en el chat.
El lector es un viajero, así que traduce la salida del verificador: di qué está mal y qué hacer, y omite los recuentos de hallazgos, nombres de comprobaciones y términos como "UNKNOWN" o "baseline". Muestra los desacuerdos de claimed_km como una comparación de las dos cifras. Escribe en el idioma que el viajero eligió, manteniendo los nombres de lugares reconocibles para la navegación (añade el nombre local cuando escribas en otro idioma).
Lo que el verificador no puede decirte
Dilo cuando sea importante. No conoce los cierres de carreteras en vivo, las condiciones de incendios forestales o inundaciones, si un lugar vale realmente la pena visitar, o lo cansado que estará el conductor. Sus tiempos de conducción provienen de un enrutador más un margen, y los tiempos de puesta de sol son estimaciones calculadas. Para rutas remotas, dile al usuario que verifique el servicio oficial de condiciones de la carretera poco antes de partir.
Trabajar con el viajero a través de muchos cambios
Los viajes reales pasan por docenas de versiones: las rutas cambian, las reservas llegan una a una, los lugares van y vienen. Estos hábitos mantuvieron seguro uno de esos viajes (más de 40 versiones):
- Versiona, nunca sobrescribas. Guarda cada cambio como un nuevo plan, por ejemplo
trip_v12_<Etiqueta>.json, y un nuevo documento cuyo nombre diga qué cambió. Mantén todos los archivos anteriores, ya que el viajero puede querer volver atrás. - Cambia solo lo que se pidió. "Eliminar el paseo en barco" significa eliminar esa parada y reajustar el tiempo del día. No significa rediseñar el día. Si el cambio deja un vacío, ofrece opciones como una pregunta, y no las añadas sin que te lo pidan.
- Ofrece opciones como preguntas. Cuando haya alternativas, como un lugar de reemplazo, una ciudad para pasar la noche o una noche sin marca, usa AskUserQuestion con 2–4 opciones concretas. Da a cada opción su efecto en tiempo y distancia, con tu recomendación primero.
- Las reservas son puntos fijos. Cuando el viajero pegue una confirmación, registra el número de referencia, fecha y hora, habitación y camas, precio y moneda, si está pagado o pagadero a la llegada, los términos de cancelación, y los horarios de check-in o check-out. Luego verifícalo contra el plan (fecha, lugar, hora) y reconstruye el documento. Señala cualquier cosa que no sea definitiva, como un pago marcado como "Pendiente", un nombre de hotel faltante o una hora que choca. Una vez que algo está reservado, no