Planejador de Viagem Rodoviária
Produza um plano de direção que foi verificado por um script, com cada requisito e fato do mundo real rastreável. Um itinerário que parece plausível é a falha que esta habilidade existe para evitar: em viagens longas, uma distância errada ou um posto de combustível fechado pode deixar pessoas perdidas depois do anoitecer.
Por que o fluxo de trabalho é assim
O método vem de um agente de planejamento de viagens neuro-simbólico, e essas lições moldam as etapas abaixo:
- A maioria dos erros começa na tradução. Traduzir as palavras do viajante em restrições exatas é mais importante do que um planejamento inteligente, então os requisitos são escritos e lidos de volta primeiro.
- Um verificador que não depende do modelo captura o que o modelo perde. Você julga o que vale a pena fazer. O script julga se cabe.
- Dados vazios não devem ser considerados como aprovados. As verificações retornam PASS, FAIL ou UNKNOWN. Relate UNKNOWN como desconhecido, nunca como "tudo bem".
- Tentativas cegas raramente consertam algo. Os reparos visam uma falha específica e mudam o mínimo possível.
- Edições não devem regredir. Uma edição só permanece se nada piorou.
- Passar no verificador não é o objetivo. Avaliadores mais rigorosos fecham brechas, e a realidade é a mais rigorosa. Nunca ajuste um número, defina
night_okou marque um fato como verificado apenas para deixar uma verificação verde.
Fluxo de Trabalho
Os scripts estão em scripts/ ao lado deste arquivo (route_legs.py, order_stops.py, choose_nights.py, verify_trip.py, render_report.py) e precisam apenas de Python padrão. Leia references/plan-format.md antes de escrever um arquivo de plano. Mantenha o plano como trip.json na pasta de viagem do usuário, ou em um diretório temporário se eles não quiserem arquivos lá.
1. Capture os requisitos
Extraia o que o usuário já disse ou forneceu. Se eles lhe deram um itinerário, importe-o como está, incluindo suas distâncias declaradas como claimed_km, para que seus erros apareçam em vez de serem corrigidos silenciosamente.
Em seguida, pergunte o que ainda está faltando. Leia references/intake.md e siga suas rodadas com a ferramenta AskUserQuestion (Perguntar ao Usuário). Se o destino ou a rota não foi decidida, comece com a Rodada 0: 2–3 opções de rota pesquisadas, cada uma com suas vantagens e desvantagens. As outras rodadas cobrem rota e datas, motoristas e licenças, marca de hotel, quarto e orçamento, distância e ritmo diários, interesses e coisas a evitar, o que já está reservado, e o idioma e formato de saída. Pule qualquer pergunta já respondida. Cada resposta tardia em uma viagem real, como a marca do hotel, enjoo ou o dia de partida, custou uma reconstrução total, então fazer algumas perguntas a mais no início é mais barato do que adivinhar.
Registre cada requisito como uma restrição tipada, com as próprias palavras do usuário em nl (linguagem natural), e mantenha as respostas restantes em preferences (preferências). Leia a lista de volta em linguagem simples antes de planejar com base nela. Use manual para qualquer coisa que os tipos não possam expressar. Separe os verdadeiros requisitos das preferências, já que apenas os requisitos pertencem a hard_constraints (restrições rígidas).
2. Colete fatos de fontes
Não planeje de memória sobre qualquer coisa que possa mudar ou que você possa pesquisar:
-
Distâncias e tempos: execute
route_legs.py trip.json. Ele usa serviços do OpenStreetMap e envia apenas nomes de lugares e coordenadas. Se o caminho do roteador não for a estrada pretendida, adicione o waypoint como uma parada. Um avisoleg_speedgeralmente significa um ponto de mapa ruim, então corrija as coordenadas e recalcule a rota com--forceem vez de aceitar o tempo. -
Ordem de visita: para qualquer dia com três ou mais pontos turísticos, execute
order_stops.py trip.json --day N. Ele sugere a ordem com menos direção e mantém pontos fixos no lugar: início, hotel e qualquer parada combe_byou"fixed": true. Se a ordem mudar, salve-a com--write trip_vN.json, recalcule a rota e teste-a com o verificador em relação à versão anterior. O tempo de direção não é o único custo, já que horários de funcionamento, um gêiser às 10:15 ou o pôr do sol podem superar alguns minutos. Mantenha o veredito do verificador sobre a ordem mais curta. -
Combustível: liste cada parada de combustível em trechos remotos, com horários, e marque as paradas com
refuel. Obtenha a autonomia real para a classe do veículo. -
Horários e fechamentos: pesquise horários de funcionamento, fechamentos sazonais, condições das estradas e permissões, e registre cada um com sua fonte e data. Para cada ponto turístico principal, pesquise também novas regras de reserva no ano da viagem, como entrada com hora marcada, estacionamento reservado ou novas taxas. Pesquise " reserva obrigatória ", não apenas seus horários. Essas regras mudam sem aviso: um mirante costeiro importante começou a exigir reservas apenas um mês antes de uma viagem de teste.
-
Estas datas exatas: pesquise o que está acontecendo na rota nas datas da viagem, não apenas em geral: eventos que lotam cidades, interrupções de combustível ou abastecimento, obras, e feriados escolares ou públicos. Se um itinerário importado foi baseado em uma estação ou mês, reteste seu clima e alegações sazonais em relação às datas reais.
-
Horários fixos: não invente horários de voo ou balsa. Use o bilhete do viajante, ou um cronograma citado marcado como uma suposição. Após um desembarque internacional, permita 60–90 minutos para imigração, biossegurança e o balcão de aluguel antes que o carro se mova. Antes de uma partida, permita o horário de check-in da companhia aérea mais a devolução do carro.
-
Riscos de estrada e planos de backup: para cada estrada chave na rota, verifique sua página oficial de fechamentos ou boletins para problemas atuais, como deslizamentos, comboios ou obras, e para riscos sazonais como neve, inundações ou incêndios. Quando um pode quebrar o plano, construa uma rota de backup como seu próprio arquivo de plano (
trip_vN_B.json) e verifique-o com o verificador como o plano principal. Adicione um plano C se a estrada puder fechar no meio da viagem. Registre cada backup emcontingencies(contingências) com o risco, o gatilho a observar, uma datadecide_by(decidir até), o plano e a fonte. Aconselhe reter quartos canceláveis na rota de backup até essa data. Uma escolha A/B datada vale mais do que um aviso para "verificar antes de ir". -
Hotéis de marca e cidades de pernoite: quando o viajante quer uma marca, liste cada um de seus hotéis em um raio de cerca de 30 km de qualquer rota razoável, usando o próprio site da rede. Adicione cada um aos
overnight_candidates(candidatos a pernoite) do plano, junto com as outras cidades que podem funcionar para uma noite (comrefuel: trueonde há combustível). Em seguida, executechoose_nights.py trip.json. Ele tenta cada arranjo de noites e classifica aqueles dentro dos limites diários por noites da marca, em seguida pelo dia mais longo mais curto. Salve o melhor com--write, recalcule a rota e verifique. Nunca descarte um hotel de marca adivinhando. O script também lista quase acertos: arranjos com mais noites da marca que quebram um limite em até 10%. Ofereça o melhor quase acerto ao viajante como uma escolha (por exemplo, "uma segunda noite IHG se um dia for 4h04 em vez de 4h"), e não escolha por eles. -
Regras locais: verifique restrições de aluguel na rota, taxas de ida única, regras de fronteira e quarentena, e horário local. Registre cada uma em
facts(fatos). -
Reservas, refeições e preparação: leia
references/prep-and-bookings.md. Coloque cada item que precisa de reserva no blocobookings(reservas) do plano com uma databook_by(reservar até) baseada em evidências, para que o verificador sinalize qualquer coisa atrasada ou com pagamento ainda não confirmado. Nomeie uma parada de almoço real para cada dia longo de direção. Construa a lista de verificação de pré-partida e a lista de embalagem a partir do que este itinerário realmente contém.
Se você não pode verificar algo, deixe-o não verificado. O plano ainda pode prosseguir, com a lacuna visível.
3. Verifique o plano
python3 scripts/verify_trip.py trip.json
Código de saída 0 é PASS, 1 FAIL, 2 NÃO VERIFICADO e 3 um arquivo inválido. Leia cada constatação. O script fornece o nascer e o pôr do sol para a data e localização de cada parada, então não os estime.
4. Repare uma falha de cada vez
Para cada FAIL, descubra por que falha e escolha a menor mudança do mundo real: sair mais cedo, cortar ou mover uma parada, mudar a cidade de pernoite. Salve como um novo arquivo e teste em relação ao anterior:
python3 scripts/verify_trip.py trip_v2.json --baseline trip.json
Mantenha a edição apenas se for aceita. Uma rejeição nomeia o que regrediu, então use isso para escolher uma correção diferente, não para tentar a mesma novamente. Quando o usuário pediu uma alteração, adicione --user-requested: não precisa melhorar uma métrica, mas ainda não pode regredir nada. Quando uma edição adiciona uma nova parada ou hotel, adicione --allow-new-unknowns e, em seguida, pesquise os desconhecidos que lista.
Se nenhuma edição corrigir uma falha, a viagem não se encaixa como especificada. Diga isso e ofereça as trocas reais, como adicionar um dia ou abandonar uma parada, em vez de afrouxar a regra você mesmo.
5. Relatório
O plano escrito sempre vem de render_report.py, então cada versão tem as mesmas seções na mesma ordem, e seus horários e distâncias não podem se desviar do verificador:
python3 scripts/render_report.py trip.json --out trip_v3_<Label>.pdf
A ordem fixa é: visão geral → dia a dia → reservas e bilhetes → hotéis → itens em aberto → antes de ir → fontes. O que muda com os desejos do viajante é definido no bloco report (relatório) do plano, a partir da Rodada 5 de intake (captura), ou com opções de linha de comando:
lang: qualquer código de idioma, definido para a escolha do viajante. Rótulos estão embutidos paraenezh. Para qualquer outro idioma, executerender_report.py --print-labels, traduza os valores (mantenha os{placeholders}) e salve-os comoreport.labels; o renderizador avisa sobre qualquer rótulo que teve que deixar em inglês, então não entregue enquanto esse aviso permanecer.report.labelstambém pode substituir rótulos individuais emenouzh. Nomes de lugares mostram o rótulo local mais o nome no mapa. Se um PDF em uma escrita não latina mostrar caixas vazias, definareport.fontpara uma fonte que o cubra ({"regular": caminho, "bold": caminho}); escritas da direita para a esquerda são melhor renderizadas como HTML ou Markdown.format:pdf,htmloumd. Também é lido da extensão do arquivo--out.detail:fullusanote(nota) de cada parada,intro(introdução) do dia e seustips(dicas);briefusashort(resumo).layout(apenas Markdown):phone, o padrão para Markdown, transforma tabelas em listas para que nada role lateralmente.printmantém tabelas.
Quando o viajante pede algo curto, defina detail: brief e layout: phone, remova seções que eles não precisam, e mantenha report.open_items (itens em aberto) em no máximo 6 itens de uma linha. Os avisos de comprimento do renderizador (max_words_per_day (máx. palavras por dia), padrão 200; max_words_total (máx. palavras total), padrão 1600) são então limites rígidos: encurte as notas curtas (short) e itens em aberto, renderize novamente e não entregue enquanto qualquer aviso de comprimento permanecer. Corte texto, não fatos. Um relatório longo falha com um viajante que pediu um curto, por melhor que seja seu conteúdo.
sections: qualquer subconjunto das sete, ainda na ordem fixa.
Escreva as palavras você mesmo no plano, no idioma do viajante: title (título) do dia, intro (introdução) e tips (dicas), note (nota) e short (resumo) da parada, label (rótulo) do lugar, prep.checklist (lista de verificação), prep.packing (embalagem) e, opcionalmente, report.open_items (itens em aberto) para substituir os itens em aberto agrupados automaticamente. O script se recusa a escrever um relatório contendo um endereço de e-mail. Mantenha números de telefone, números de identificação e datas de nascimento fora do plano também. Se o viajante pedir algo que as seções fixas não podem comportar, adicione-o aos campos de texto do plano em vez de construir manualmente um documento separado. Se eles quiserem uma aparência diferente, mude o renderizador uma vez para que toda versão posterior o mantenha.
No chat, lidere com o veredito e o que o usuário precisa decidir ou fazer em seguida. Em seguida, inclua:
- Veredito em palavras simples, com as contagens. "Não verificado" significa verificado até onde os fatos conhecidos permitem.
- Problemas encontrados, primeiro os mais graves, cada um com a correção feita ou a escolha que precisam fazer.
- Cronograma por dia: partida, paradas, chegada, pôr do sol, km e horas, mais a parada de almoço em dias longos.
- Reserve ou confirme em seguida, ordenado por data de
book_by(reservar até), cada um com seu link oficial. Observe também quais itens são vendidos no local. - Ainda desconhecido e como descobrir cada item.
- Antes de ir: a lista de verificação de pré-partida personalizada e notas de embalagem, no documento completo. Mantenha-as curtas no chat.
O leitor é um viajante, então traduza a saída do verificador: diga o que está errado e o que fazer, e deixe de fora contagens de constatações, nomes de verificações e termos como "UNKNOWN" ou "baseline". Mostre divergências de claimed_km (km declarados) como uma comparação dos dois valores. Escreva no idioma que o viajante escolheu, mantendo nomes de lugares reconhecíveis para navegação (adicione o nome local ao escrever em outro idioma).
O que o verificador não pode lhe dizer
Diga quando isso for importante. Ele não sabe de fechamentos de estradas ao vivo, condições de incêndio ou inundação, se um lugar realmente vale a visita, ou quão cansado o motorista estará. Seus tempos de direção vêm de um roteador mais um buffer, e os horários do pôr do sol são estimativas computadas. Para rotas remotas, diga ao usuário para verificar o serviço oficial de condições da estrada pouco antes de partir.
Trabalhando com o viajante ao longo de muitas mudanças
Viagens reais passam por dezenas de versões: rotas mudam, reservas chegam uma a uma, pontos turísticos vão e vêm. Esses hábitos mantiveram uma dessas viagens (40+ versões) segura:
- Versione, nunca sobrescreva. Salve cada alteração como um novo plano, como
trip_v12_<Label>.json, e um novo documento cujo nome diga o que mudou. Mantenha todos os arquivos anteriores, pois o viajante pode querer voltar atrás. - Mude apenas o que foi pedido. "Remova o passeio de barco" significa remover essa parada e reajustar o horário do dia. Não significa redesenhar o dia. Se a mudança deixar uma lacuna, ofereça preenchimentos como uma pergunta e não os adicione sem ser solicitado.
- Ofereça escolhas como perguntas. Quando houver alternativas, como um ponto turístico substituto, uma cidade de pernoite ou uma noite fora da marca, use AskUserQuestion (Perguntar ao Usuário) com 2–4 opções concretas. Dê a cada opção seu efeito de tempo e distância, com sua recomendação primeiro.
- Reservas são pontos fixos. Quando o viajante colar uma confirmação, registre o número de referência, data e hora, quarto e camas, preço e moeda, se está pago ou devido na chegada, os termos de cancelamento e os horários de check-in ou check-out. Em seguida, verifique em relação ao plano (data, lugar, hora) e reconstrua o documento. Aponte qualquer coisa que não seja final, como pagamento marcado como "Pendente", um nome de hotel ausente ou um horário que conflita. Depois que algo é reservado, não