The handbook. All of it.
Every command, every flag, every file format — condensed here, exhaustive in the repo: docs/HANDBOOK.md. Where docs and code disagree, the code is the fact.
Five-minute start
Engine keys (all 18)
Command reference
Data file formats
Acceptance DSL
Workflows
Reading the report
MCP for agents
The seven disciplines
Troubleshooting
FAQ
What this is
FasterGEO is an open-source GEO platform: it samples what 18 Chinese and global AI engines say about a brand, measures the Brand Entity Funnel — does AI know you, confuse you, mention you, rank you, cite you — and turns every gap into a ticket a machine re-verifies. Monitoring tells you a score; FasterGEO closes the loop: detect → diagnose → ticket → fact-constrained content → gated publish → re-crawl verify. Apache-2.0, self-hosted; a project is a directory of plain JSON — git init is your backup strategy.
Five-minute start
# 1. bootstrap a project from your site (unknowns marked unconfirmed, never invented) npx fastergeo bootstrap --root https://yoursite.com --llm glm --out myproject && cd myproject # 2. what AI crawlers see (no keys needed) npx fastergeo audit --root https://yoursite.com --urls /,/about,/pricing # 3. a full period in one command: sample → metrics → audit → tickets → report npx fastergeo cycle --dir . --judge glm --repeat 5 # 4. after you fix things: let the machine flip the tickets npx fastergeo verify --tickets tickets.json --root https://yoursite.com # 5. local dashboard (binds 127.0.0.1 only) npx fastergeo ui --dir .
Zero keys? sheet → import --questions → metrics — manual sampling feeds the same pipeline. import refuses to run without the question bank: probe answers must never leak into the visibility pool.
Engine keys — all 18
Convention: ${ID}_API_KEY unless named below; override with ${ID}_MODEL / ${ID}_BASE_URL (a changed base URL is labeled channel: gateway on every sample). Run fastergeo check — it distinguishes no key / auth failed / authenticated-but-model-not-enabled / network.
| id | market | key env | default model |
|---|---|---|---|
| glm | cn | ZHIPUAI_API_KEY | glm-4-flash |
| doubao | cn | ARK_API_KEY | doubao-seed-1-6 (web search) |
| deepseek | cn | DEEPSEEK_API_KEY | deepseek-chat |
| kimi | cn | MOONSHOT_API_KEY | kimi-k2 |
| minimax | cn | MINIMAX_API_KEY | MiniMax-M2 |
| qwen | cn | DASHSCOPE_API_KEY | qwen-plus |
| ernie | cn | QIANFAN_API_KEY | ernie-4.0-turbo |
| spark | cn | SPARK_API_KEY | generalv3.5 |
| nano · baidu-ai | cn | — manual sheets | — |
| openai | global | OPENAI_API_KEY | gpt-4o-mini |
| anthropic | global | ANTHROPIC_API_KEY | claude-haiku-4-5 |
| gemini | global | GEMINI_API_KEY | gemini-2.0-flash |
| grok | global | XAI_API_KEY | grok-3-mini |
| perplexity | global | PERPLEXITY_API_KEY | sonar (citations) |
| ChatGPT/Claude web · AIO | global | — manual sheets | — |
Behind a proxy: set HTTPS_PROXY (the CLI wires Node's fetch to it); exclude domestic endpoints via NO_PROXY. UI language: --lang zh or FASTERGEO_LANG=zh.
Command reference — all 24
| command | what it does |
|---|---|
| check | key health for every engine, four-state diagnosis with hints — run first |
| sample | one-off question to configured engines; prints answers + citations |
| metrics | samples → funnel metrics, sentiment, recognition, citation sources; --judge enables both LLM judges; --format geolook reads GeoLook exports |
| audit | six-dimension page scores + site checks; search-crawler bans are blockers, training opt-outs are notes; unreachable pages named |
| sources | per-market "who AI trusts in your category" from your samples' citations — the PR target list |
| botlog | your access logs → AI crawler hits by purpose (training / search-index / user-request) + AI-referred human visits; logs never leave your machine |
| official | reconcile GSC Gen-AI / Bing AI Performance CSV with your audit: blind spots, low-score winners, silent good pages |
| plan | audit+metrics → prioritized tickets, incl. off-site tickets naming cited domains and an auto-verifiable entity ticket |
| verify | re-measure acceptance: pass→done, done-then-fail→regressed, unmeasurable states why |
| outline · draft | outline / first draft from the fact store (confirmed, non-E facts only) |
| fabcheck | the fabrication gate standalone: unsourced numbers, superlatives, do-not-claim, grade-E claims |
| publish | gate + publish to WordPress / GitHub / signed webhook; gate failure refuses; --force is recorded; WP defaults to draft |
| expand | suggest mining (Baidu + Google autocomplete, intent modifiers) → question-bank candidates, never auto-added |
| products | catalog from Product JSON-LD or Shopify products.json; missing price stays null, never 0 |
| shopping | product-level metrics; wrong-price verdicts carry the evidence sentence (decimal-safe splitting) |
| bootstrap | site → brand facts (sourced), competitor candidates (noise-filtered), question-bank draft — empty over guessed |
| cycle | the full period: sample (--repeat N) → metrics → audit → tickets/verify → report + trends |
| schedule | macOS launchd job running cycle every N days |
| trends | period deltas under the two-period rule + immediate P0 alerts |
| ui | local dashboard (127.0.0.1 only; SSH-tunnel for remote) |
| report | the single-file HTML diagnosis report |
| sheet · import | zero-key manual sampling; import requires --questions to restore probe flags |
Full flags, examples and output walkthroughs: the repo handbook §6.
Data file formats
A project directory contains: brand.json (name / aliases / domains / description / competitors / auditUrls — aliases are the disambiguation bedrock, domains drive hostname-suffix citation attribution) · questions.json (id / text / market cn|global|both / brandInQuestion — hold the bank constant across periods) · samples-DATE.jsonl (one sample per line, channel honestly labeled api/gateway/ui/manual) · tickets.json · facts.json (fact store with A–E evidence grades and doNotClaim) · targets.json (publish targets; secrets by env-var name — safe to commit) · products.json · history/ (per-period metrics / audit / samples — the replay's data source). Schemas with examples: handbook §7.
The acceptance DSL — complete
site.no_ai_block zero search-serving crawler bans (training opt-outs don't fail this)
site.llms_txt · site.sitemap
site.entity_schema Organization JSON-LD + ≥2 sameAs on the root page
site.avg_score_gte:N
pages.no_blockers
pages.issue_lte:<code>:<N> codes: spa-shell · no-jsonld · block-gap:definition|statistics|
comparison|steps|faq · content-short · no-date · answer-below-fold ·
context-dependent-paragraphs · stale-content
metrics.mention_rate_gte:<market>:<x>
metrics.no_confusion:<market>
Workflows
Solo / startup — weekly
bootstrap → cycle --repeat 5 → fix per tickets → verify → schedule --every 7d. Read trends weekly; conclusions only after two consecutive same-direction periods.
Agency — the 90-day engagement
Baseline (wk 1–2) → entity & technical (wk 2–4) → knowledge base (wk 3–8) → distribution (wk 8–12) → measurement (wk 12+), each phase with a machine-checkable exit — the full phase-by-phase playbook with commands lives at /agency/.
E-commerce
products --shopify → cycle → shopping. A wrong price in an AI answer is the commerce version of brand confusion — it ships with the quoted sentence.
Earned media
sources names the domains AI already cites in your category; plan turns them into concrete off-site tickets; content flows draft → fabcheck → publish.
Migrating from GeoLook
fastergeo metrics --format geolook re-scores your existing samples directly — plus recognition, sentiment, intervals and citation sources.
Reading the report
Top to bottom: headline (worst findings first) → red banner (blockers + verbatim confusion and negative-sentiment quotes) → entity funnel (per market; without a judge the head stages show unmeasured, grey — and with 0% mentions the rank stage shows "not in the candidate set", because no rank exists) → engine table (mention rates carry Wilson-interval tooltips) → six-dimension audit → cited sources → tickets → answer replay: every sampled answer verbatim, brand hits highlighted (probe answers deliberately not — name echo isn't knowledge), confusion evidence in red, unlocatable judge quotes listed explicitly. Every number above can be cross-examined against the replay. That's the point.
MCP — for agents
claude mcp add fastergeo -- npx -y @fastergeo/mcp
Nine tools: list_engines (key presence as booleans, never values) · sample_engine · audit_page · audit_site · check_ai_crawlers (purpose-aware) · compute_metrics (optional judgeEngine) · generate_tickets · verify_tickets · check_fabrication. Unmeasured returns null and the descriptions tell your agent not to substitute zeros. Run over stdio in trusted environments only.
The seven disciplines
Full metric definitions, each pointing at the file that implements it: METHODOLOGY.md.
Troubleshooting
| symptom | cause & fix |
|---|---|
| model-unavailable | key valid, model not enabled on that console — enable it or override ${ID}_MODEL |
| global engines 403/timeout | set HTTPS_PROXY — the CLI wires Node's fetch to it |
| domestic engines fail via proxy | add their endpoints to NO_PROXY (Ark / DashScope / Qianfan…) |
| import refuses | by design — --questions restores probe flags; anything else fabricates mention rates |
| funnel head "unmeasured" | no judge ran — add --judge glm (any configured engine) |
| rank shows "—" | 0% mentions: not in the candidate set, no rank exists — honest display, not a bug |
| publish: missing env XXX | targets.json stores env names — export the variable first |
| dashboard unreachable remotely | 127.0.0.1 by design — ssh -L 8765:127.0.0.1:8765 host |
Twelve more entries in handbook §13.
FAQ
Do I need API keys?
No. Auditing needs none; sampling uses whatever you have; keyless engines go through manual sheets into the same pipeline.
Does my data leave my machine?
No. Everything is plain JSON on your disk; the web scan processes transiently at the edge and stores nothing.
Can you guarantee AI will cite me?
No — and whoever guarantees that is lying to you. What we guarantee: honest measurement, concrete fixes, and verification a machine signs off on.
Why should I trust these numbers?
You don't have to. Every metric is publicly defined and traceable to code; unmeasured renders as unmeasured; verdicts ship with verbatim quotes; even our marketing statistics are footnoted to sources.