Bau eines vertikalen Markt-Agenten
Ein Chat-Agent, der ein allgemeines Modell in einer Branche und einer Metropolregion schlägt, weil er einen vorberechneten Datensatz echter Daten mit sich führt und während des Gesprächs Live-Daten abrufen kann. Erledigt = live auf einer URL, antwortet mit Zahlen, die auf das Substrat zurückgeführt werden können, weigert sich, diejenigen zu erfinden, die es nicht hat, und in der Produktion mit echten Tests verifiziert (nicht mit einem lokalen Test).
Schritt 0: zwei Fragen, die der Eigentümer beantwortet
- Welche Metropolregion, und warum genau diese? Wähle eine, in der du bereits Feldarbeit oder Daten hast, die dort buchstäblich wahr sind. Baue eine Metropolregion auf, dann werbe dort.
- Wird es beworben, und ist es verlinkt? Vier technische Entscheidungen hängen davon ab (Pixel, Cache-TTL, Vanity-URLs, Attribution). Siehe Schritt 7.
Schritt 1: Finde das Alleinstellungsmerkmal, bevor du Code schreibst
Zwei Arten: ein Korpus, den du abgebaut hast und besitzt (z. B. Zehntausende von Bewertungen), oder ein Join (ein Live-Angebotsfeed gegen kommunale Parzellen-, Bewertungs- und Steueraufzeichnungen: zwei freie Quellen, die niemand zusammenbringt). Bezahlte Massenerfassung scheitert oft (Guthaben aufgebraucht, Eigentümersuche fehlt).
Wenn die Massenerfassung eingeschränkt ist, ist der Einstiegspunkt die Einschränkung, nicht die Daten. Eine kommunale App, die für jede Adresse antwortet, aber keine auflistet, ist in Ordnung, sobald du Adressen anderswo auflistest (Schritt 3).
Staaten ohne Offenlegung sind eine Chance: Niemand hat Verkaufsvergleiche, auch Wettbewerber nicht, sodass die eigene Arithmetik der Gemeinde, gut organisiert, der beste Anker wird.
Schritt 2: Baue das Substrat
Ein eingefrorenes JSON-Digest, das serverseitig in den System-Prompt bei jeder Nachricht eingefügt wird.
- Überprüfe zuerst die Panel-Größe bei einem Agenten mit Bewertungskorpus. „Wo du unter den Orten wie dir rangierst“ braucht ~50+ Unternehmen mit jeweils 50+ Bewertungen. Darunter: Versende kein Ranking.
- Ein von einem Modell geschriebenes Branchenprofil ist kein Substrat. Das Laden von Text, den ein Modell geschrieben hat, sagt dem Modell, was es bereits weiß, und schafft kein Alleinstellungsmerkmal. Substrat wird gemessen.
- Fehlende Daten sind ein Backlog, kein Hindernis: Wenn du die Mittel besitzt, ein Panel abzubauen, baue es ab.
- Überprüfe die Lizenz vor dem Abbau. Daten einiger Quellen können nicht weitergegeben werden, was entscheidet, ob ein abgebautes Panel jemals ein Download sein kann.
- Jeder Block trägt eine
_interpretation: 2–4 Sätze darüber, was es bedeutet und wie ein Profi es verwendet. Höchster Wert pro Byte; es ist der Unterschied zwischen Aufsagen und Schlussfolgern. - Byte-stabile Ausgabe:
sort_keys=True, vollständige Sortierungen mit Gleichstandsregelung über ein eindeutiges Feld, kein Zeitstempel außergenerated_on. Ein variierendes Byte belastet das zwischengespeicherte Präfix bei jeder Nachricht neu. - Schichte, und lass bessere Schichten ältere ersetzen; zwei Blöcke, die unterschiedliche Zahlen für eine Frage liefern, zwingen das Modell zur Schlichtung während der Antwort. Ersetze auf Unterschlüssel-Ebene, wenn ein Block gemischt ist.
- Archiviere vollständig, versende kompakt (
.compact.json-Zwillinge), falle auf die Archivversion zurück, falls ein Zwilling fehlt. - Entferne persönliche E-Mails aus zusammengeführten Recherchen: Im Anzeigenmaßstab verwandelt das Modell den Posteingang eines einzelnen Beamten in deinen ausgehenden Kanal. Abteilung + Telefonnummer sagt dasselbe aus.
Schritt 3: Zähle auf, was die Aufzeichnungen nicht können
Ein dünner Angebotsfeed sieht fast nichts. „Suche in der Nähe“ auf einem Gitter kleiner Kreise, dann verbinde jeden Treffer mit der kommunalen Aufzeichnung (ein Durchlauf: 307 Komplexe -> 208 übereinstimmende Parzellen -> 9.736 Einheiten).
- Kleine Kreise (~3,5 km auf einem ~3,9 km Raster): Die API begrenzt die Ergebnisse pro Aufruf, sodass eine einzige metropolweite Abfrage stillschweigend nur die bekanntesten Orte zurückgibt.
- Lass das öffentliche Archiv entscheiden, was etwas ist, nicht die Quelle, die du durchsucht hast (ein Verzeichnis-„Apartment“, das die Gemeinde als Pflegeeinrichtung führt; ein Gebrauchtwagenplatz, der als Mehrfamilienhaus getaggt ist).
- In einem Markt, in dem nichts gelistet ist, sind die Leute, mit denen es sich zu sprechen lohnt, diejenigen, die nicht verkaufen.
Schritt 4: Die Datenfallen (lies zweimal)
Jeder Fehler hier erzeugte eine plausible falsche Zahl, niemals einen Fehler. Budgetiere QA-Zeit gegen eine bekannte korrekte Referenz.
- Befrage die Quelle erneut, bevor du ihre Beschreibung planst. Ein Layername in einem Dokument ist eine Hypothese. Lese die Metadaten des Dienstes (für ArcGIS
?f=json,editingInfo.dataLastEditDate) und die tatsächlichen Feld-Werte, bevor du einem Feldnamen vertraust. - Verifiziere gegen etwas, das du kennst. Ein Gebäude mit bekannten 36 Einheiten wurde als 10 geparst: Eine Referenz hat den schlimmsten Fehler aufgedeckt. Noch besser: Sende eine Stichprobe deiner Ausgabe zurück an die eigene API des Herausgebers in einem anderen Koordinatensystem und vergleiche.
- Achte auf Inversionen, nicht nur auf Ausreißer: Kleine Immobilien, die pro Tür höher bewertet werden als große, bedeuten, dass der Parser falsch ist, nicht der Markt.
- Lass die Daten sich selbst überprüfen. Wenn eine Querverbindung existiert (Quadratmeter pro Einheit), berechne beide Lesarten eines mehrdeutigen Felds und lass das plausible Band wählen; wenn keins passt, markieren und ausschließen.
- Dedupliziere vor der Aggregation. Ein Feed listet eine Immobilie unter jedem Asset-Typ, auf den sie passt: 623 Zeilen waren 206 Immobilien.
- Cache RAW, niemals geparst, sonst bedeutet eine Parser-Korrektur das erneute Crawlen des Servers einer kleinen Gemeinde.
- Adressformate unterscheiden sich vom Aufzeichnungsindex. Kürze Richtungen ab und lasse den Suffix weg; eine Variantenleiter hat etwa die Hälfte der Fehlschläge wieder eingefangen.
- Kennzeichne kleine Stichproben mit ihrem n; manchmal ist die Dünnheit die Erkenntnis.
- Lies bei einem Bewertungskorpus die ÜBEREINSTIMMUNGEN, niemals den Anteil. Führe jeden Taxonomie-Regex gegen echten 1–3-Sterne-Text aus und lies, was übereinstimmte. Das Dienstverb des Sektors ist oft ein Schadensverb: Ein „Verletzungs“-Muster auf
cut (me|my)traf auf 10,7 % der Salon-Beschwerden zu, meist „40 $ bezahlt, um mir selbst die Haare zu schneiden“. Überprüfedrill(zahnmedizinisch),pull(Abschleppen),strip(Reinigung),break(Glas),shave/clip(Friseure, Pflege),stick(Phlebotomie). Und ein Thema, das niemand anspricht, bleibt außen vor. - Das Vokabular des Herausgebers ist nicht das des Käufers. Eine „arterielle“ Klasse einer Gemeinde kann das Autobahnnetz sein, an dem nichts liegt, während die Geschäftsstraßen, die ein Makler meint, „Sammelstraßen“ sind. Liste den Inhalt jedes Eimers auf, bevor du kartierst, und benenne Felder nach ihrem Inhalt.
- Ein gemeinsames Schema teilt Spaltennamen, nicht Konventionen. Über Gemeinden hinweg kann ein Feld vier Klassifikationssysteme tragen,
-9999vs.0, einen dritten Eigenheimwert. Zähle jedes Feld pro Gemeinde; behandle eine Null von einer Gemeinde als Abfragefehler, bis sie bewiesen ist; bevorzuge abgeleitete Tests (Gebäudewert = 0 und Grundstückswert > 0 für Leerstand). - Ein Name ist mehrere Dinge (eine Autobahn und ihre Parallelstraße teilen sich einen Namen). Gib die Alternativen zurück und lass das Modell sagen, welche es verwendet hat.
- Dinge, die sich „einmal“ treffen sollten, treffen sich oft mehrmals (zwei Straßen kreuzen sich an sechs Stellen). Die Mittelung der Punkte landet auf einem Feld; clustere, behalte jeden Standort, wähle nach einer festgelegten Regel.
- Eine abgeleitete Gesamtsumme lässt stillschweigend Zeilen weg, die du nie berechnet hast. Liefere die Abdeckungsanzahl neben jeder Gesamtsumme mit teilweisen Eingaben und lass sie als Untergrenze lesen.
Schritt 5: Deterministische Mathematik gehört in ein Tool, niemals in den Prompt
DSCR, IRR, Cash-on-Cash, Dosierungen, Steuern: ein Tool, berechnet, das seine Annahmen und Warnungen zurückgibt. Die Arithmetik eines Modells ist plausibel falsch (ein 1,19 DSCR, der eigentlich 1,09 ist, geht zu einem Kreditgeber). Dies erzwingt eine echte Agenten-Schleife (Stream -> Tools ausführen -> zurückgeben -> Stream), einschließlich pause_turn- und max_tokens-Handhabung.
Schritt 6: Prompt-Kosten, gemessen
- Zähle Token mit der API. Dichtes JSON läuft mit ~2,4 Bytes/Token, nicht ~4.
- Erzwinge eine Byte/Token-Obergrenze in einem Test: Das Versenden des Archivs anstelle des kompakten Zwillings hat kein Symptom außer der Rechnung.
- Cache-TTL folgt dem Datenverkehr. Spärlich, manuell geteilt: Die 5-Minuten-Standardeinstellung (ein 1h-Schreiben ist ein Zuschlag, den niemand wiederverwendet). Kontinuierlicher bezahlter Verkehr: 1h, weil Besucher sich das Präfix teilen.
Schritt 7: Auslieferung
- Leite die Seite von einem Generator ab; jeder Ersatz behauptet, dass sein Anker existiert, und Wächter prüfen beide Richtungen (entfernter Inhalt ist weg und das Feature hat überlebt).
- Wenn es ein Anzeigenziel ist: Vanity-URLs als temporäre Weiterleitungen (permanente werden von der Anzeigenplattform zwischengespeichert), überprüfen, ob die Abfragezeichenfolge erhalten bleibt; ein Pixel-Ereignisname pro Kampagne; Cache-TTL 1h; und Attribution an
sessionStoragebeim Landungstreffer gebunden und bei jeder Runde mitgeführt (nichtlocalStorage, sonst wird der organische Besuch nächste Woche der heutigen Anzeige gutgeschrieben). - Überprüfe den Bereitstellungszustand, nicht das Build-Protokoll; eine Serverless-Funktionsbegrenzung oder eine unverfolgte Datei kann hinter einem grünen Protokoll fehlschlagen. Importiere Datendateien statisch, damit der Bundler sie einschließt.
Harte Regeln für den Prompt
- Erfinde niemals eine Zahl. Substrat, ein tatsächlich ausgeführtes Tool oder eine gekennzeichnete Schätzung.
- Präsentiere niemals einen öffentlichen Aufzeichnungswert als Marktwert. Sage, welchen du angibst.
- Gib die Abdeckungsgrenze in der Tool-Beschreibung UND im Prompt an (welche Gemeinden). Eine Regel an einer Stelle wird umgangen.
- Öffentliche Aufzeichnungen einzeln, nicht als Liste. Eigentümersuche für die angefragte Immobilie ist in Ordnung; Massenlisten von Namen und Adressen können bei gewerblicher Nutzung gegen staatliche Rechtsvorschriften verstoßen.
- Überprüfe, was der Prompt für unmöglich hält. Eine zuversichtliche Falschaussage darüber, was nicht bekannt sein kann, ist schlimmer als die Lücke.
Forschungsagenten für Kontextschichten
Gib parallelen Forschungsagenten ein Token-Budget (und das 2,4 Bytes/Token-Verhältnis), sage ihnen, sie sollen die Zahl kürzen, nicht die Einschränkung, und erwarte, dass sie deine frühere Arbeit korrigieren.
Schritt 8: Das branchenfremde Ende
Manche Besucher sind nicht dein Nutzer (ein Secondhand-Laden in einem Restaurant-Agenten). Das Standard-„Das habe ich nicht“ verliert das beste Signal, das du bekommen wirst: ein echter Eigentümer, der die Branche nennt, die als nächstes gebaut werden soll.
- Ein
flag_out_of_scope(sector)-Tool: Der Client rendert drei antippbare Optionen; einsubmit_feature_request-Tool speichert den Tipp. - Alles in der ersten Antwort: Die mittlere Sitzungstiefe ist eine Runde.
- Zähle nicht auf, was der Agent stattdessen mit sich führt (ein Schnitt reduzierte eine Antwort von 1.275 auf 124 Zeichen).
- Optionen werden vom Client gerendert, niemals als nummerierte Liste im Text (eine bloße „2“ kann Skill 2 auslösen).
- Sage dem Modell, wo Optionen gerendert werden; es kann den Client nicht sehen.
- Ordne Optionen universellen Fähigkeiten zu, sodass eine eingereichte Anfrage eine Fähigkeit für einen Sektor benennt.
Schritt 9: Die räumliche Schicht („Was liegt daneben“)
- Finde die ArcGIS Online-Organisation der Gemeinde, nicht ihren WAF-blockierten GIS-Host; gehostete Dienste bedienen oft anonym. Fordere Geometrie in der nativen Raumbezug der Schicht an.
- Wenn zwei Quellen aufeinandertreffen, fordere die zweite im Rahmen der ersten an (
outSR), und behaupte, dass sich die Ausdehnungen überlappen, bevor du Zeilen ausgibst: Ein Rahmenkonflikt überschneidet nichts und meldet „jede Parzelle ohne Zonierung“. In DuckDB benötigtST_Transformalways_xy := trueoder gibt stillschweigendPOINT(inf inf)zurück. - Zonierung nach Schwerpunkt; geteilte Zonierung benötigt einen Anteilsschwellenwert (>5 % des Grundstücks), wobei Bezirke, nicht Polygone, verglichen werden. Ein einfacher Überschneidungsaufruf bezeichnete 37 % der Parzellen als geteilt; der Schwellenwert ergab ~4 %.
- Die Zonierungscodes einer Stadt sind die dieser Stadt. Derselbe Code bedeutet in der Nachbarstadt andere Bezirke; liefere die Stadt und den veröffentlichten Namen mit jedem Code.
- Berechne offline vor, versende einen geometriefreien Index, füge keine API-Route hinzu: Kommunales GIS -> DuckDB Spatial Mirror -> ein festgeschriebener JSON-Index; Laufzeit führt nur Lookups und Haversine durch. Ein fehlgeschlagener räumlicher Abbau degradiert zu einer leeren Nachbarliste, einer zuversichtlichen falschen Antwort. Validiere den Index beim Laden und wirf.
- Eine Ungleichheit an irgendeiner Stelle in einem räumlichen Join stuft das räumliche Prädikat zu einem Nachfilter herab (
ON a.id < b.id AND ST_Intersects(...)testete ~29 Milliarden Paare). Lass das Prädikat allein stehen,EXPLAINfürSPATIAL_JOIN, gib Schlüssel aus, dann dedupliziere: 7 Minuten unvollendet wurden zu 19 Sekunden. - Beschränke den ausgelieferten Index auf das, was der Käufer handelt, plus unmittelbare Nachbarn, und markiere „Kontext“-Parzellen, die weniger Daten tragen.