Construindo um agente vertical de mercado
Um agente de chat que supera um modelo geral em um setor e uma metrópole, porque carrega um resumo pré-calculado de dados reais e pode buscar registros ao vivo enquanto conversa. Pronto = ao vivo em uma URL, respondendo com números que remetem ao substrato, recusando-se a inventar os que não possui e verificado em produção com sondas reais (não um teste local).
Passo 0: duas perguntas que o proprietário responde
- Qual metrópole, e por que essa? Escolha onde você já tem trabalho de campo ou dados que são literalmente verdadeiros lá. Mine uma metrópole, depois anuncie lá.
- Será anunciado, e é vinculado? Quatro decisões de engenharia dependem disso (pixel, TTL de cache, URLs personalizadas, atribuição). Veja o Passo 7.
Passo 1: encontre o fosso antes de escrever código
Dois tipos: um corpus que você minerou e possui (ex.: dezenas de milhares de avaliações), ou uma junção (um feed ao vivo de ofertas de venda contra registros de parcelas, avaliação e impostos do condado: duas fontes gratuitas que ninguém se dá ao trabalho de combinar). A enumeração em massa paga frequentemente falha (créditos esgotados, pesquisa de proprietário ausente).
Quando a enumeração em massa é murada, o ponto de entrada é a restrição, não os dados. Um aplicativo do condado que responde para qualquer endereço, mas não lista nenhum, é suficiente assim que você enumera endereços em outro lugar (Passo 3).
Estados sem divulgação são uma oportunidade: ninguém tem comparáveis de venda, incluindo concorrentes, então a própria aritmética do condado, bem organizada, torna-se a melhor âncora.
Passo 2: construa o substrato
Um resumo JSON congelado injetado no lado do servidor no prompt do sistema em cada mensagem.
- Verifique o tamanho do painel primeiro em um agente de corpus de avaliações. "Onde você se classifica entre lugares como o seu" precisa de ~50+ empresas com 50+ avaliações cada. Abaixo disso, não publique uma classificação.
- Um perfil de setor escrito por modelo não é substrato. Carregar prosa que um modelo escreveu diz ao modelo o que ele já sabe e cria zero fosso. Substrato é medido.
- Dados ausentes são um backlog, não um bloqueador: se você possui os meios para minerar um painel, mine-o.
- Verifique a licença antes de minerar. Os dados de algumas fontes não podem ser redistribuídos, o que decide se um painel minerado pode jamais ser um download.
- Cada bloco carrega um
_interpretation: 2-4 frases sobre o que significa e como um profissional o usa. Maior valor por byte; é a diferença entre recitar e raciocinar. - Saída estável em bytes:
sort_keys=True, ordenações totais com desempate por um campo único, sem carimbo de data/hora excetogenerated_on. Um byte variável recobra o prefixo em cache em cada mensagem. - Camada, e deixe camadas melhores substituírem as mais antigas; dois blocos fornecendo números diferentes para uma pergunta fazem o modelo arbitrar no meio da resposta. Substitua no nível sub-chave quando um bloco for misto.
- Arquive completo, publique compacto (arquivos gêmeos
.compact.json), recorrendo ao arquivo se um gêmeo estiver faltando. - Remova e-mails pessoais de pesquisas mescladas: na escala de anúncios, o modelo transforma a caixa de entrada de um funcionário público em seu canal de saída. Departamento + telefone diz o mesmo.
Passo 3: enumere o que os registros não podem
Um feed de listagem superficial quase não vê nada. Pesquise "próximo" em uma grade de pequenos círculos, depois junte cada resultado ao registro do condado (uma execução: 307 complexos -> 208 parcelas correspondentes -> 9.736 unidades).
- Círculos pequenos (~3,5 km em uma grade de ~3,9 km): a API limita resultados por chamada, então uma consulta em toda a metrópole retorna silenciosamente apenas os lugares mais conhecidos.
- Deixe o registro público decidir o que algo é, não a fonte da qual você enumerou (um "apartamento" de diretório que o condado registra como instalação de cuidados; um pátio de carros usados marcado como multifamiliar).
- Em um mercado onde nada está listado, as pessoas que vale a pena contactar são as que não estão vendendo.
Passo 4: as armadilhas de dados (leia duas vezes)
Cada bug aqui produziu um número errado plausível, nunca um erro. Orçamente tempo de QA contra um fixture conhecido como correto.
- Reconsulte a fonte antes de planejar com base em sua descrição. Um nome de camada em um documento é uma hipótese. Leia os metadados do serviço (para ArcGIS
?f=json,editingInfo.dataLastEditDate) e os valores reais dos campos antes de confiar no nome de um campo. - Verifique contra algo que você conhece. Um prédio conhecido por ter 36 unidades analisado como 10: um fixture pegou o pior bug. Melhor ainda, envie uma amostra de sua saída de volta para a API do próprio editor em um quadro de coordenadas diferente e compare.
- Cuidado com inversões, não apenas valores atípicos: propriedades pequenas com valor por porta maior que as grandes significa que o analisador está errado, não o mercado.
- Faça os dados se verificarem. Onde existe uma verificação cruzada (m² por unidade), calcule ambas as leituras de um campo ambíguo e deixe a faixa plausível escolher; se nenhuma se encaixar, sinalize e exclua.
- Desduplique antes de agregar. Um feed listando uma propriedade sob todo tipo de ativo que se encaixa: 623 linhas eram 206 propriedades.
- Armazene em cache o RAW, nunca o analisado, ou uma correção do analisador significa recrawlear o servidor de um condado pequeno.
- Formatos de endereço diferem do índice de registros. Abrevie direções e remova o sufixo; uma escada de variantes recuperou cerca de metade das falhas.
- Rotule amostras pequenas com seu n; às vezes a escassez é a descoberta.
- Em um corpus de avaliações, leia as CORRESPONDÊNCIAS, nunca a participação. Execute cada regex de taxonomia contra texto real de 1-3 estrelas e leia o que correspondeu. O verbo de serviço do setor é frequentemente um verbo de dano: um padrão "injury" em
cut (me|my)correspondeu a 10,7% das reclamações de salão, principalmente "paguei $40 para cortar meu próprio cabelo". Verifiquedrill(odontologia),pull(reboque),strip(detalhamento),break(vidro),shave/clip(barbearias, tosa),stick(flebotomia). E um tema que ninguém levanta permanece de fora. - O vocabulário do editor não é o do comprador. A classe "arterial" de um condado pode ser a rede de rodovias, onde nada tem frente, enquanto as ruas comerciais que um corretor significa são "collectors". Liste o conteúdo de cada balde antes de mapear e nomeie campos pelo que contêm.
- Um esquema compartilhado compartilha nomes de colunas, não convenções. Entre condados, um campo pode carregar quatro sistemas de classificação,
-9999vs0, um terceiro valor de propriedade de residência familiar. Cense cada campo por condado; trate um zero de um condado como um bug de consulta até prova em contrário; prefira testes derivados (valor do prédio = 0 e valor do terreno > 0 para vacância). - Um nome são várias coisas (uma rodovia e sua via marginal compartilham um nome). Retorne as alternativas e faça o modelo dizer qual usou.
- Coisas que "deveriam" se encontrar uma vez se encontram muitas vezes (duas estradas se cruzando em seis lugares). A média dos pontos cai em um campo; agrupe, mantenha cada localização, escolha por uma regra declarada.
- Um total derivado descarta silenciosamente linhas que você nunca computou. Envie a contagem de cobertura junto com qualquer total com entradas parciais e faça com que seja lido como um piso.
Passo 5: matemática determinística vai em uma ferramenta, nunca no prompt
DSCR, TIR, cash-on-cash, dosagens, impostos: uma ferramenta, computada, retornando suas premissas e avisos. A aritmética de um modelo é plausivelmente errada (um DSCR de 1,19 que na verdade é 1,09 vai para um credor). Isso força um loop real de agente (stream -> executar ferramentas -> alimentar de volta -> stream), incluindo manipulação de pause_turn e max_tokens.
Passo 6: custo de prompt, medido
- Conte tokens com a API. JSON denso executa ~2,4 bytes/token, não ~4.
- Imponha um teto de bytes/token em um teste: enviar o arquivo em vez do twin compacto não tem sintoma, exceto a conta.
- O TTL do cache segue o tráfego. Uso esparso, compartilhado manualmente: o padrão de 5 minutos (uma gravação de 1h é uma sobretaxa que ninguém reutiliza). Tráfego pago contínuo: 1h, porque os visitantes compartilham o prefixo.
Passo 7: implantação
- Derive a página de um gerador; cada substituição afirma que sua âncora existe, e as proteções verificam ambas as direções (o conteúdo removido sumiu e o recurso sobreviveu).
- Se for um destino de anúncio: URLs personalizadas como redirecionamentos temporários (os permanentes são armazenados em cache pela plataforma de anúncios), verificando se a string de consulta sobrevive; um nome de evento de pixel por campanha; TTL de cache de 1h; e atribuição fixada em
sessionStorageno hit de destino e transportada em cada turno (nãolocalStorage, ou a visita orgânica da próxima semana será creditada ao anúncio de hoje). - Verifique o estado da implantação, não o log de build; um limite de função serverless ou um arquivo não rastreado pode falhar por trás de um log verde. Importe arquivos de dados estaticamente para que o bundler os inclua.
Regras rígidas para o prompt
- Nunca invente um número. Substrato, uma chamada de ferramenta realmente executada ou uma estimativa sinalizada.
- Nunca apresente um valor de registro público como valor de mercado. Diga qual você está fornecendo.
- Declare o limite de cobertura na descrição da ferramenta E no prompt (quais condados). Uma regra em um lugar é contornada.
- Registro público um de cada vez, não como uma lista. A consulta do proprietário para a propriedade perguntada é aceitável; listas em massa de nomes e endereços podem violar a lei estadual de registros abertos para uso comercial.
- Reveja o que o prompt chama de impossível. Uma falsidade confiante sobre o que não pode ser sabido é pior do que a lacuna.
Agentes de pesquisa para camadas de contexto
Dê a agentes de pesquisa paralelos um orçamento de token (e a proporção de 2,4 bytes/token), diga-lhes para cortar a figura em vez da ressalva e espere que corrijam seu trabalho anterior.
Passo 8: o encerramento fora do setor
Alguns visitantes não são seu usuário (uma loja de brechós em um agente de restaurantes). O padrão "Não tenho isso" perde o melhor sinal que você obterá: um proprietário real nomeando o setor a ser construído em seguida.
- Uma ferramenta
flag_out_of_scope(sector): o cliente renderiza três opções tocáveis; uma ferramentasubmit_feature_requestarquiva o toque. - Tudo na primeira resposta: a profundidade mediana da sessão é um turno.
- Não invente o que o agente carrega em vez disso (um corte reduziu uma resposta de 1.275 para 124 caracteres).
- As opções são renderizadas pelo cliente, nunca uma lista numerada em prosa (um "2" solto pode acionar a habilidade 2).
- Diga ao modelo onde as opções renderizam; ele não pode ver o cliente.
- Mapeie opções para capacidades universais para que uma solicitação arquivada nomeie uma capacidade para um setor.
Passo 9: a camada espacial ("o que está ao lado")
- Encontre a organização ArcGIS Online do condado, não seu host GIS bloqueado por WAF; serviços hospedados geralmente atendem anonimamente. Solicite geometria na referência espacial nativa da camada.
- Quando duas fontes se encontram, solicite a segunda no quadro da primeira (
outSR), e afirme que as extensões se sobrepõem antes de emitir linhas: uma incompatibilidade de quadro não cruza nada e relata "cada parcela sem zoneamento". No DuckDB,ST_Transformprecisa dealways_xy := trueou retornaPOINT(inf inf)silenciosamente. - Zoneamento por centróide; zoneamento dividido precisa de um limite de participação (>5% do lote), comparando distritos, não polígonos. Uma interseção simples chamou 37% das parcelas de divididas; o limite deu ~4%.
- Os códigos de zoneamento de uma cidade são dessa cidade. O mesmo código significa distritos diferentes ao lado; publique a cidade e o nome publicado com cada código.
- Pré-calcule offline, publique um índice livre de geometria, não adicione rota de API: GIS do condado -> espelho espacial DuckDB -> um índice JSON consolidado; o tempo de execução faz apenas consultas e haversine. Uma dependência espacial com falha degrada para uma lista de vizinhos vazia, uma resposta errada confiante. Valide o índice no carregamento e lance.
- Uma desigualdade em qualquer lugar em uma junção espacial rebaixa o predicado espacial a um pós-filtro (
ON a.id < b.id AND ST_Intersects(...)testou ~29 bilhões de pares). Deixe o predicado sozinho,EXPLAINparaSPATIAL_JOIN, emita chaves, depois desduplique: 7 minutos inacabados tornaram-se 19 segundos. - Escopo do índice publicado para o que o comprador transaciona mais vizinhos imediatos, e sinalize parcelas de "contexto" que carregam menos dados.