CommunityRecherche & Datenanalysegithub.com

2016judea/vertical-market-agent

Baue einen Chat-Agenten, der eine Branche in einer Metropolregion besser kennt als jedes allgemeine Modell, weil er einen vorberechneten Datensatz echter öffentlicher Aufzeichnungen (oder eines ausgewerteten Bewertungskorpus) mit sich führt und während des Gesprächs Live-Daten abrufen kann – die Suche nach dem Alleinstellungsmerkmal, der Aufbau eines byte-stabilen Substrats, die Aufzählung dessen, was die Aufzeichnungen nicht können, die Datenfallen, die plausible falsche Zahlen erzeugen, deterministische Mathematik in Tools, gemessene Prompt-Kosten und Cache-TTL, die Auslieferung als Anzeigenziel, ein branchenfremdes Ende und eine vorberechnete räumliche 'Was liegt daneben'-Schicht. Verwende dies beim Bau eines vertikalen KI-Agenten, der auf Aufzeichnungen und nicht auf Allgemeinwissen basiert.

Was ist vertical-market-agent?

Dieses Skill-Paket beschreibt den vollständigen Bau eines vertikalen Markt-Agenten – eines Chat-Assistenten, der in einer einzelnen Branche und einer einzelnen Metropolregion (z. B. Restaurants in Portland oder Wohnungen in Phoenix) besser abschneidet als allgemeine Modelle. Die Kerninnovation ist ein **vorberechnetes Datensubstrat**: ein kompaktes JSON-Digest öffentlicher Aufzeichnungen oder ausgewerteter Bewertungsdaten, das serverseitig in den System-Prompt eingefügt wird, sodass der Agent überprüfbare Zahlen liefern kann, ohne zu erfinden. Der Leitfaden behandelt die Beschaffung des Substrats (Schritt 1–2), die Überwindung von API-Lücken durch Clevere Enumeration (Schritt 3) und die 13 dokumentierten Datenfallen, die plausible falsche Zahlen erzeugen (Schritt 4). Er setzt deterministische Berechnungen wie DSCR oder IRR in Tools um, nicht in Prompts (Schritt 5), misst die tatsächlichen Prompt-Kosten (Schritt 6) und liefert den Agenten als Anzeigenziel aus, mit Vanity-URLs, Sitzungsattribution und Cache-TTL (Schritt 7). Das Skill enthält außerdem Regeln zur Vermeidung von Modellerfindungen (Schritt 8) und eine räumliche 'Was liegt daneben'-Schicht, die mittels DuckDB und ArcGIS vorberechnet wird (Schritt 9). Es wird mit Claude Code, Cursor und anderen KI-Agenten-Plattformen verwendet, die Tool-Nutzung und System-Prompts unterstützen. Besonders nützlich ist es für Entwickler, die einen datengestützten vertikalen Agenten bauen, der nicht allgemein ist, sondern auf echten, überprüfbaren lokalen Aufzeichnungen basiert.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/2016judea/brick-mortar-skills/tree/HEAD/skills/vertical-market-agent

Installed? Explore more Recherche & Datenanalyse skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

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

  1. 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.
  2. 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ßer generated_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.

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. Dedupliziere vor der Aggregation. Ein Feed listet eine Immobilie unter jedem Asset-Typ, auf den sie passt: 623 Zeilen waren 206 Immobilien.
  6. Cache RAW, niemals geparst, sonst bedeutet eine Parser-Korrektur das erneute Crawlen des Servers einer kleinen Gemeinde.
  7. 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.
  8. Kennzeichne kleine Stichproben mit ihrem n; manchmal ist die Dünnheit die Erkenntnis.
  9. 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üfe drill (zahnmedizinisch), pull (Abschleppen), strip (Reinigung), break (Glas), shave / clip (Friseure, Pflege), stick (Phlebotomie). Und ein Thema, das niemand anspricht, bleibt außen vor.
  10. 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.
  11. Ein gemeinsames Schema teilt Spaltennamen, nicht Konventionen. Über Gemeinden hinweg kann ein Feld vier Klassifikationssysteme tragen, -9999 vs. 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).
  12. 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.
  13. 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.
  14. 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 sessionStorage beim Landungstreffer gebunden und bei jeder Runde mitgeführt (nicht localStorage, 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

  1. Erfinde niemals eine Zahl. Substrat, ein tatsächlich ausgeführtes Tool oder eine gekennzeichnete Schätzung.
  2. Präsentiere niemals einen öffentlichen Aufzeichnungswert als Marktwert. Sage, welchen du angibst.
  3. Gib die Abdeckungsgrenze in der Tool-Beschreibung UND im Prompt an (welche Gemeinden). Eine Regel an einer Stelle wird umgangen.
  4. Ö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.
  5. Ü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; ein submit_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ötigt ST_Transform always_xy := true oder gibt stillschweigend POINT(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, EXPLAIN für SPATIAL_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.

Individual skills in this repo

This repo contains 7 individual skills — each has its own dedicated page.

2016judea/ascii-charts

Build charts as plain Unicode-block text — bar, range, bullet, gap-bracket, star-histogram, heatmap, line, Venn, pie, donut and scatter — with a dependency-free Python script, for anywhere only monospace text survives (newsletter code blocks, Markdown, terminals, plain-text email, chat). Use when a chart has to embed as literal text instead of an image or a third-party chart service, or when you want a hand-made terminal look with no branding footer.

2016judea/buffett-checklist

Apply Warren Buffett's investment framework as a discipline lens when weighing a buy, hold, or sell decision — circle of competence, economic moat, owner earnings & intrinsic value, margin of safety, management/capital-allocation quality, and market psychology (Mr. Market, fear vs greed, temperament). Use when asked to "run this through Buffett", "what would Buffett say", "does this pass the moat test", "is this cheap enough", or for a second, more skeptical read on a name being evaluated or already held. This is a discipline overlay, not a replacement for a strategy — it applies the Buffett lens to how someone actually invests, rather than issuing generic advice.

2016judea/image-riff

Turn one or more reference images into original art in that reference's own visual language, then cut it to whatever surface it's for. Use when you paste or point at art and say "use this as the base image", "generate art from this", "riff on this", "some creative ideation with these images", "make me a channel banner / avatar / cover / plate", "wilder version of this", or want a spread of options off one piece of reference. This is the TASK skill; the engine is the `make-art` tool skill.

2016judea/leonardo

Draw the way Leonardo da Vinci drew — a study sheet, a notebook folio, a red-chalk or silverpoint study, a machine cutaway, a storm of vortices — in his real materials and page-logic, generated with the make-art engine and anchored on fifteen of his actual (public-domain) sheets. Use when you say "Leonardo", "da Vinci", "like his notebooks", "a codex page of X", "draw this as one of his study sheets", "sanguine", "silverpoint", or wants a design, diagram, or illustration in that hand. Also a reading guide to his notebooks (Richter's 1883 public-domain translation) for "what did Leonardo say about shadow / trees / water". This is a TASK skill; the engine is `make-art`.

2016judea/mcp-stack

Which free MCP server or framework to reach for, and its traps — finance/gov data (SEC EDGAR, Yahoo, SAM.gov, USAspending), web research (Exa, Firecrawl, Crawl4AI, Jina reader), design/art/brand (Canva, Inkscape, Penpot, Figma, Orshot, Hugging Face image gen, vectorizing, charts), data/spatial (DuckDB spatial, live ArcGIS layers, OpenStreetMap/Overpass, Census, MapLibre), and ops (PostHog, iMessage, context7 docs). Use when making a social post, OG card, poster, logo/vector, chart, map, or brand asset; when querying parquet/geojson/duckdb or a city's open-data layer; when an MCP "needs authentication" or fails; or when asked "what tools do we have", "is there an MCP for X", "should we add X".

2016judea/records-request

Get a specific record out of a US government office by public-records request — "request the assessor's model", "file a data practices request", "FOIA this", "open records request", "can we just ask the county for it", "who do I write to at <county>", "chase that request", "did they ever answer". Covers checking the website first, finding the right office and statute, the carve-out paragraph that makes a request answerable instead of refused, web-form traps (hidden character caps, WAFs that reject apostrophes), chasing (there is usually no deadline), whether what comes back may be republished, and parsing multi-year tables without silent errors.

2016judea/sms-native-product

Build a product whose interface is text messages rather than an app or a website — "no app, no website", "they just text a number", "chat with our agent natively in Text Messages", "can we do this over text", "an SMS bot", "a Telegram bot", "make it a group chat", "minimum viable friction". Fires equally when it has already gone wrong — "my campaign got rejected", "our number is blocked", "the texts aren't arriving", "why do I need to register". Covers the gate that decides whether such a product can send at all (US A2P 10DLC registration, SHAFT content rules, permanent rejection codes), group MMS from code, what each channel can't do, an architecture that survives losing the channel, and guarding model-rewritten user content.

Verwandte Skills