Que fait Planificateur de Road Trip ?
Générez un plan de conduite vérifié par un script, où chaque exigence et fait concret est traçable. Un itinéraire qui semble plausible est l'échec que ce skill existe pour empêcher : sur de longs trajets, une distance erronée ou une station-service fermée peut laisser des personnes bloquées après la nuit.
Pourquoi le flux de travail est ainsi
La méthode provient d'un agent neuro-symbolique de planification de voyages, et ces leçons façonnent les étapes ci-dessous :
- La plupart des erreurs commencent par la traduction. Convertir les paroles du voyageur en contraintes exactes est plus important qu'une planification astucieuse ; les exigences sont donc d'abord écrites et relues.
- Un vérificateur qui ne dépend pas du modèle rattrape ce que le modèle manque. Vous jugez ce qui vaut la peine d'être fait. Le script juge si cela tient.
- Les données vides ne doivent pas compter comme une réussite. Les vérifications retournent PASS, FAIL ou UNKNOWN. Signalez UNKNOWN comme inconnu, jamais comme acceptable.
- Les tentatives aveugles corrigent rarement quoi que ce soit. Les réparations ciblent un échec spécifique et modifient le moins possible.
- Les modifications ne doivent pas régresser. Une modification reste uniquement si rien ne s'est aggravé.
- Réussir le vérificateur n'est pas le but. Des évaluateurs plus stricts ferment les failles, et la réalité est la plus stricte. Ne modifiez jamais un chiffre, ne définissez pas
night_okou ne marquez pas un fait comme vérifié juste pour passer un test au vert.
Flux de travail
Les scripts se trouvent dans scripts/ à côté de ce fichier (route_legs.py, order_stops.py, choose_nights.py, verify_trip.py, render_report.py) et nécessitent seulement Python standard. Lisez references/plan-format.md avant d'écrire un fichier de plan. Conservez le plan sous le nom trip.json dans le dossier de voyage de l'utilisateur, ou dans un répertoire temporaire s'il ne veut pas de fichiers à cet endroit.
1. Capturer les exigences
Extrayez ce que l'utilisateur a déjà dit ou fourni. S'il vous a donné un itinéraire, importez-le tel quel, y compris ses distances déclarées comme claimed_km, afin que ses erreurs apparaissent au lieu d'être silencieusement corrigées.
Ensuite, demandez ce qui manque encore. Lisez references/intake.md et suivez ses rounds avec l'outil AskUserQuestion. Si la destination ou l'itinéraire n'est pas décidé, commencez par son Round 0 : 2 à 3 options d'itinéraire recherchées, chacune avec ses compromis. Les autres rounds couvrent l'itinéraire et les dates, les conducteurs et permis, la marque d'hôtel, la chambre et le budget, la distance quotidienne et le rythme, les centres d'intérêt et les choses à éviter, ce qui est déjà réservé, et la langue et le format de sortie. Sautez toute question déjà répondue. Chaque réponse tardive dans un vrai voyage, comme la marque d'hôtel, le mal de mer ou le jour de départ, a coûté une reconstruction complète, donc poser quelques questions supplémentaires au départ coûte moins cher que de deviner.
Enregistrez chaque exigence comme une contrainte typée, avec les propres mots de l'utilisateur dans nl, et conservez les réponses restantes dans preferences. Relisez la liste en langage simple avant de planifier dessus. Utilisez manual pour tout ce que les types ne peuvent pas exprimer. Séparez les vraies exigences des préférences, car seules les exigences appartiennent à hard_constraints.
2. Rassembler les faits à partir de sources
Ne planifiez pas de mémoire sur quoi que ce soit qui peut changer ou que vous pouvez consulter :
-
Distances et temps : exécutez
route_legs.py trip.json. Il utilise les services OpenStreetMap et n'envoie que les noms de lieux et les coordonnées. Si le chemin du routeur n'est pas la route prévue, ajoutez le point de passage comme arrêt. Un avertissementleg_speedsignifie généralement un mauvais point de carte, alors corrigez les coordonnées et recalculez avec--forceplutôt que d'accepter l'heure. -
Ordre des visites : pour tout jour avec trois sites ou plus, exécutez
order_stops.py trip.json --day N. Il suggère l'ordre avec le moins de conduite et maintient les points fixes en place : départ, hôtel et tout arrêt avecbe_byou"fixed": true. Si l'ordre change, sauvegardez-le avec--write trip_vN.json, recalculez l'itinéraire et testez-le avec le vérificateur par rapport à la version précédente. Le temps de conduite n'est pas le seul coût, car les heures d'ouverture, un geyser à 10h15 ou le coucher du soleil peuvent l'emporter sur quelques minutes. Gardez le verdict du vérificateur plutôt que l'ordre le plus court. -
Carburant : listez chaque station-service sur les tronçons éloignés, avec les horaires, et marquez les arrêts avec
refuel. Obtenez l'autonomie réelle pour la classe de véhicule. -
Horaires et fermetures : recherchez les heures d'ouverture, les fermetures saisonnières, les conditions routières et les permis, et enregistrez chaque élément avec sa source et sa date. Pour chaque site vedette, recherchez également les nouvelles règles de réservation pour l'année du voyage, comme l'entrée à heure fixe, le stationnement réservé ou les nouveaux frais. Cherchez " réservation obligatoire <année>", pas seulement ses horaires. Ces règles changent sans préavis : un point de vue côtier majeur a commencé à exiger des réservations seulement un mois avant un voyage test.
-
Ces dates exactes : recherchez ce qui se passe sur l'itinéraire aux dates du voyage, pas seulement en général : événements qui remplissent les villes, perturbations de carburant ou d'approvisionnement, travaux routiers, et jours fériés scolaires ou publics. Si un itinéraire importé était construit autour d'une saison ou d'un mois, retestez son climat et ses affirmations saisonnières par rapport aux dates réelles.
-
Horaires fixes : n'inventez pas les horaires de vol ou de ferry. Utilisez le billet du voyageur, ou un horaire cité marqué comme hypothèse. Après une arrivée internationale, prévoyez 60 à 90 minutes pour l'immigration, la biosécurité et le comptoir de location avant que la voiture ne bouge. Avant un départ, prévoyez le temps d'enregistrement de la compagnie aérienne plus le retour de la voiture.
-
Risques routiers et plans de secours : pour chaque route clé de l'itinéraire, vérifiez sa page de fermeture officielle ou ses bulletins pour les problèmes actuels, comme les glissements de terrain, les convois ou les travaux routiers, et pour les risques saisonniers comme la neige, les inondations ou les incendies. Lorsque l'un d'eux pourrait compromettre le plan, construisez un itinéraire de secours comme son propre fichier de plan (
trip_vN_B.json) et vérifiez-le avec le vérificateur comme le plan principal. Ajoutez un plan C si la route pourrait fermer en cours de voyage. Enregistrez chaque plan de secours danscontingenciesavec le risque, le déclencheur à surveiller, une datedecide_by, le plan et la source. Conseillez de conserver des chambres annulables sur l'itinéraire de secours jusqu'à cette date. Un choix A/B daté vaut mieux qu'un avertissement "vérifiez avant de partir". -
Hôtels de marque et villes d'étape : lorsque le voyageur souhaite une marque, listez chacun de ses hôtels dans un rayon d'environ 30 km de tout itinéraire raisonnable, en utilisant le site de la chaîne. Ajoutez chacun d'eux au
overnight_candidatesdu plan, avec les autres villes qui pourraient convenir pour une nuit (avecrefuel: truelà où il y a du carburant). Ensuite, exécutezchoose_nights.py trip.json. Il essaie chaque disposition des nuits et classe celles dans les limites quotidiennes par nuits de marque, puis par le jour le plus long le plus court. Sauvegardez la meilleure avec--write, recalculez l'itinéraire et vérifiez-la. N'écartez jamais un hôtel de marque en devinant. Le script liste également les presque réussites : dispositions avec plus de nuits de marque qui dépassent une limite de jusqu'à 10 %. Proposez la meilleure presque réussite au voyageur comme un choix (par exemple, "une deuxième nuit IHG si un jour fait 4h04 au lieu de 4h"), et ne choisissez pas à sa place. -
Règles locales : vérifiez les restrictions de location sur l'itinéraire, les frais de trajet simple, les règles frontalières et de quarantaine, et l'heure locale. Enregistrez chaque élément dans
facts. -
Réservations, repas et préparation : lisez
references/prep-and-bookings.md. Mettez chaque élément nécessitant une réservation dans le blocbookingsdu plan avec une datebook_byfondée sur des preuves, afin que le vérificateur signale tout retard ou paiement non encore confirmé. Nommez un vrai arrêt déjeuner pour chaque longue journée de conduite. Construisez la liste de vérification avant départ et la liste de bagages à partir de ce que contient réellement l'itinéraire.
Si vous ne pouvez pas vérifier quelque chose, laissez-le non vérifié. Le plan peut toujours avancer, avec la lacune visible.
3. Vérifier le plan
python3 scripts/verify_trip.py trip.json
Le code de sortie 0 est PASS, 1 FAIL, 2 UNVERIFIED et 3 un fichier invalide. Lisez chaque constatation. Le script fournit le lever et le coucher du soleil pour chaque arrêt à sa date et son emplacement, donc ne les estimez pas.
4. Réparer un échec à la fois
Pour chaque FAIL, déterminez pourquoi il échoue et choisissez le plus petit changement réel : partir plus tôt, supprimer ou déplacer un arrêt, changer la ville d'étape. Sauvegardez-le comme un nouveau fichier et testez-le par rapport au précédent :
python3 scripts/verify_trip.py trip_v2.json --baseline trip.json
Conservez la modification uniquement si elle est acceptée. Un rejet nomme ce qui a régressé, alors utilisez-le pour choisir un correctif différent, pas pour réessayer le même. Lorsque l'utilisateur a demandé un changement, ajoutez --user-requested : il n'est pas nécessaire d'améliorer une métrique, mais il ne peut toujours rien régresser. Lorsqu'une modification ajoute un nouvel arrêt ou hôtel, ajoutez --allow-new-unknowns, puis recherchez les inconnues qu'elle liste.
Si aucune modification ne corrige un échec, le voyage ne correspond pas aux spécifications. Dites-le et offrez les compromis réels, comme ajouter un jour ou supprimer un arrêt, plutôt que d'assouplir la règle vous-même.
5. Rapport
Le plan écrit provient toujours de render_report.py, de sorte que chaque version a les mêmes sections dans le même ordre, et ses temps et distances ne peuvent pas dériver du vérificateur :
python3 scripts/render_report.py trip.json --out trip_v3_<Label>.pdf
L'ordre fixe est : aperçu → jour par jour → réservations et billets → hôtels → éléments ouverts → avant de partir → sources. Ce qui change selon les souhaits du voyageur est défini dans le bloc report du plan, à partir du Round 5 de la collecte, ou avec les options en ligne de commande :
lang: un code de langue quelconque, défini sur le choix du voyageur. Les étiquettes sont intégrées pourenetzh. Pour toute autre langue, exécutezrender_report.py --print-labels, traduisez les valeurs (conservez les{placeholders}) et sauvegardez-les commereport.labels; le rendu avertit de toute étiquette qu'il a dû laisser en anglais, alors ne livrez pas tant que cet avertissement persiste.report.labelspeut également remplacer des étiquettes uniques enenouzh. Les noms de lieux affichent l'étiquette locale plus le nom de la carte. Si un PDF dans un script non latin montre des cases vides, définissezreport.fontsur une police qui le couvre ({"regular": chemin, "bold": chemin}) ; les scripts de droite à gauche s'affichent mieux en HTML ou Markdown.format:pdf,htmloumd. Il est également lu à partir de l'extension du fichier--out.detail:fullutilisenotede chaque arrêt,introdu jour et sestips;briefutiliseshort.layout(Markdown uniquement) :phone, la valeur par défaut pour Markdown, transforme les tableaux en listes pour éviter le défilement horizontal.printconserve les tableaux.
Lorsque le voyageur demande quelque chose de court, définissez detail: brief et layout: phone, supprimez les sections dont il n'a pas besoin, et gardez report.open_items à au maximum 6 éléments d'une ligne. Les avertissements de longueur du rendu (max_words_per_day, par défaut 200 ; max_words_total, par défaut 1600) sont alors des limites strictes : raccourcissez les notes short et les éléments ouverts, refaites le rendu, et ne livrez pas tant qu'un avertissement de longueur persiste. Coupez le texte, pas les faits. Un rapport long échoue un voyageur qui a demandé un rapport court, aussi bon soit son contenu.
sections: tout sous-ensemble des sept, toujours dans l'ordre fixe.
Écrivez les mots vous-même dans le plan, dans la langue du voyageur : title du jour, intro et tips, note et short des arrêts, label des lieux, prep.checklist, prep.packing, et éventuellement report.open_items pour remplacer les éléments ouverts regroupés automatiquement. Le script refuse d'écrire un rapport contenant une adresse e-mail. Gardez également les numéros de téléphone, les numéros d'identification et les dates de naissance hors du plan. Si le voyageur demande quelque chose que les sections fixes ne peuvent pas contenir, ajoutez-le aux champs de texte du plan plutôt que de construire à la main un document séparé. S'il souhaite un aspect différent, modifiez le rendu une fois afin que chaque version ultérieure le conserve.
En chat, commencez par le verdict et ce que l'utilisateur doit décider ou faire ensuite. Incluez ensuite :
- Verdict en mots simples, avec les comptes. "Non vérifié" signifie vérifié dans la mesure où les faits connus le permettent.
- Problèmes trouvés, du plus grave au moins grave, chacun avec la correction apportée ou le choix qu'ils doivent faire.
- Chronologie par jour : départ, arrêts, arrivée, coucher du soleil, km et heures, plus le stop déjeuner pour les longues journées.
- Réserver ou confirmer ensuite, trié par date
book_by, chacun avec son lien officiel. Notez également les articles qui sont vendus sur place. - Toujours inconnu, et comment découvrir chaque élément.
- Avant de partir : la liste de vérification avant départ et les notes de bagages adaptées, dans le document complet. Gardez-les courts en chat.
Le lecteur est un voyageur, alors traduisez la sortie du vérificateur : dites ce qui ne va pas et quoi faire, et laissez de côté les comptes de constatations, les noms de vérifications et les termes comme "UNKNOWN" ou "baseline". Montrez les désaccords claimed_km comme une comparaison des deux chiffres. Écrivez dans la langue choisie par le voyageur, en gardant les noms de lieux reconnaissables pour la navigation (ajoutez le nom local lorsque vous écrivez dans une autre langue).
Ce que le vérificateur ne peut pas vous dire
Dites-le quand cela importe. Il ne connaît pas les fermetures de routes en direct, les conditions de feux de brousse ou d'inondations, si un endroit vaut vraiment la peine d'être visité, ou à quel point le conducteur sera fatigué. Ses temps de trajet proviennent d'un routeur plus une marge, et les heures de coucher du soleil sont des estimations calculées. Pour les itinéraires éloignés, dites à l'utilisateur de vérifier le service officiel des conditions routières peu avant de partir.
Travailler avec le voyageur sur de nombreux changements
Les vrais voyages passent par des dizaines de versions : les itinéraires changent, les réservations arrivent une par une, les sites vont et viennent. Ces habitudes ont gardé un tel voyage (40+ versions) sûr :
- Versionnez, n'écrasez jamais. Sauvegardez chaque changement comme un nouveau plan, par exemple
trip_v12_<Label>.json, et un nouveau document dont le nom indique ce qui a changé. Conservez chaque fichier antérieur, car le voyageur peut vouloir revenir en arrière. - Changez seulement ce qui a été demandé. "Supprimer la excursion en bateau" signifie supprimer cet unique arrêt et re-rythmer la journée. Cela ne signifie pas reconcevoir la journée. Si le changement laisse un vide, proposez des compléments comme une question, et ne les ajoutez pas sans qu'on vous le demande.
- Proposez des choix comme des questions. Lorsqu'il y a des alternatives, comme un site de remplacement, une ville d'étape ou une nuit sans marque, utilisez AskUserQuestion avec 2 à 4 options concrètes. Donnez à chaque option son effet de temps et de distance, avec votre recommandation en premier.
- Les réservations sont des points fixes. Lorsque le voyageur colle une confirmation, enregistrez le numéro de référence, la date et l'heure, la chambre et les lits, le prix et la devise, si c'est payé ou dû à l'arrivée, les conditions d'annulation, et les heures d'enregistrement ou de départ. Ensuite, vérifiez-le par rapport au plan (date, lieu, heure) et reconstruisez le document. Signalez tout ce qui n'est pas final, comme un paiement marqué "En attente", un nom d'hôtel manquant ou un horaire en conflit. Une fois quelque chose de réservé, ne le déplacez pas : une modification qui déplace ou supprime une réservation échouera l'invariant
bookings_moved, et le vérificateur le refusera. Si le voyageur insiste, dites-lui d'annuler et de réserver. Un 'non' clair du vérificateur est plus fiable qu'un contournement.
Au-delà du planificateur de voyage
Ce même modèle—exigences explicites → faits structurés → vérificateur déterministe → réparation ciblée avec régression—fonctionne pour tout problème de décision multi-contrainte : horaires d'équipe, conception d'itinéraires de fret, planification de production. Conservez les scripts et le format de plan et remplacez les règles.