TerraQuotes
Инструмент с поданной заявкой на патент, который рассчитывает стоимость работ на участке по открытым данным о недвижимости, чтобы владелец дома узнал цену до того, как к нему кто-то приедет.
Запущен
Моя роль
Основатель, продуктовый инженер и инженер машинного обучения
- Компания
- Good Citizens
- Отрасль
- Ландшафтные услуги
- Годы
- С 2025 по 2026
- Команда
- Единственный разработчик
- В одиночку за 17 месяцев сделал TerraQuotes, от вопроса одного домовладельца до рабочего продукта, которым пользуется пилотный оператор Quiet Village Landscaping.
- Спроектировал калькулятор так, чтобы владельцу дома ничего не нужно было измерять: площадь участка по данным округа минус постройки, умноженная на собственную ставку подрядчика за квадратный фут.
- Задал правила для ценовой модели до того, как она чему-либо научилась: она может лишь слегка корректировать цену в записанных пределах и не может учиться, пока не наберётся 75 выигранных и 225 проигранных работ.
- В работе у пилотного оператора Quiet Village Landscaping, который считает цены для участков реальных домовладельцев
- 1 адрес вот и всё, что вводит домовладелец, чтобы получить четыре ежемесячных плана с ценами, без звонка продавца
- 9 из 38 заявок закончились записью на визит после мгновенного расчёта цены, и 4 превратились в заказы
- 49 из 225 проигранных предложений записано на сегодня при том количестве, которое нужно модели, прежде чем ей разрешат учиться
Кратко
Друг спросил у ландшафтного подрядчика, сколько будет стоить его новый газон. В ответ он получил план, костровую чашу, о которой обмолвился мимоходом, и счёт на семьдесят пять долларов в час за дизайн. А ему нужна была только цифра. TerraQuotes даёт домовладельцу эту цифру по адресу, используя площади участков, которые округ и так бесплатно публикует.
Я сделал его один. Цену задаёт простое правило, а модель машинного обучения может лишь слегка её корректировать в пределах, которые я записал заранее. Модель всё ещё ждёт, и это намеренно: ей нужно увидеть предложения, которые подрядчики проиграли, а пока вернулись только 49 из 225 необходимых.
Кто участвовал
- Домовладельцы Хотят узнать, сколько стоят работы на участке, до того, как кто-то к ним приедет.
- Ландшафтные подрядчики Пилотный оператор Quiet Village Landscaping уже пользуется инструментом, и цены берутся из его собственного прайс-листа.
- Jeff Haring, Sundown Landscaping Посмотрел раннюю версию и провёл границу между уходом за участком и монтажными работами.
Контекст
Чтобы назвать домовладельцу цену до того, как к нему кто-то приедет, мне нужно было знать размер его участка, не выезжая на место. Самой рискованной была гипотеза о том, что бесплатный источник площадей участков вообще существует и достаточно хорош, чтобы по нему считать цены. От этого зависел весь продукт, а ни один общенациональный сервис такого не предлагал.
Трудность была не в том, чтобы показать покупателю диапазон цифр. Трудно было удержаться от соблазна построить огромный инструмент ландшафтного дизайна для самостоятельной работы и не отходить от одного вопроса: на какие цены люди соглашаются? В отрасли это называют конверсией, то есть тем, как часто предложение превращается в оплаченный заказ.
Исследование
Прежде чем что-то строить, я записал каждое предположение в виде проверяемой гипотезы вместе с тем, что докажет мою неправоту. Затем я расставил их по тому, насколько больно будет ошибиться и сколько выиграет клиент, если я прав, и строил в этом порядке.
Сначала я обратился к данным округов: города Сент-Луис, округа Сент-Луис и округа Марикопа в Аризоне. Сент-Луис бесплатно публикует площадь земли и построек в квадратных футах для каждого участка, и тот же подход сработал в двух других. Раннюю версию я показал Jeff Haring из Sundown Landscaping, а когда пришла Quiet Village, проверил идею на их реальном прайс-листе.
Ключевые гипотезы
Чтобы это стоило делать, должны были подтвердиться три гипотезы. Вот каждая из них и её текущее состояние.
Я проверил эти три гипотезы на реальном прайс-листе, когда пришёл первый подрядчик, Quiet Village. Их цены вошли в модель, а их записи о клиентах дали мне два вопроса, которые меня действительно волнуют: приближается ли оценка к тому, за сколько работы реально продаются, и может ли машина научиться понимать, какие предложения выигрывают.
Доверие к калькулятору
Может ли калькулятор держать разумную цену, пока человек передумывает, чего хочет? Да. Пакеты и переключатели дополнительных услуг вышли в работу, а поле, в котором люди могли незаметно ошибиться, я убрал.
Оценочная цена
Достаточно ли близка цифра, чтобы ландшафтный подрядчик всерьёз отнёсся к заявке? Пока неизвестно. Пилотный оператор использует инструмент в работе, но тест точности я отбросил до того, как его можно было оценить, так что сама цифра пока не доказана.
Расчёт по квадратным футам
Может ли ландшафтный подрядчик считать стоимость работ по квадратному футу? Да, с оговоркой. Первый пилотный клиент переписал свои расценки на уход в виде единой ставки за квадратный фут. Монтажные работы остаются за рамками, потому что никто не знает, что под газоном.
Порог обучения
Модель не может начать учиться, пока не наберётся достаточно завершённых работ.
Эти цифры не случайны. Я провёл моделирование: подавал модели пары работ, одну выигранную и одну проигранную, и просил выбрать выигравшую. Я пробовал разное число работ, для каждого прогонял моделирование 30 раз и оставил наименьшее число работ, при котором модель выбирала победителя хотя бы в 80% случаев. Получилось 75 выигранных работ и 225 проигранных. Правда, тренировочные работы были выдуманными, поэтому они говорят мне, сколько нужно реальных работ, а не о том, есть ли закономерность, которую можно найти.
Записано проигрышей
49/225
Записано выигрышей
6/75
Выигрышей для обучения
0/75
Каждая точка обозначает одно предположение, расположенное по тому, насколько оно было важно и насколько хорошо мы его знали. В правом верхнем углу ошибка обошлась бы дороже всего, а знали мы меньше всего, поэтому исследование началось именно там. В этот угол попало предположений: 2.
- Подтвердилось
- Подтвердилось частично
- Не подтвердилось
- Не проверялось
| ID | Допущение | Уверенность | Важность | Статус |
|---|---|---|---|---|
| A-001 | Vercel's hosting will scale to all tenant traffic without us running our own servers | High | High | ValidatedN/A: validated in production |
| A-002 | A free geocoder is accurate enough for residential address lookup, so we never have to pay for one | High | High | ValidatedSupplemented with county GIS parcel data as primary address source (CR-20251012) |
| A-003 | Routing geocoding through our own server removes the browser security and privacy problems | High | Medium | ValidatedN/A |
| A-004 | Public county parcel boundaries are authoritative enough to estimate service area from | High | Critical | ValidatedAddress standardization handles heterogeneous schemas; YAML configs externalize field mappings |
| A-005 | Serviceable area can be derived reliably from public parcel data | High | Critical | Validated with caveatsvaluation and tier adjustments compensate for data gaps; area model semantics documented in CR-20260116 |
| A-006 | Public property valuation is a meaningful proxy for landscaping price positioning | Medium | High | Active: monitoringPer-tenant pricing profiles can override; ML pipeline designed to learn from CRM outcomes |
| A-007 | Counting events on our own servers, in Firestore and BigQuery, gives enough insight without a tracking library in the browser | High | High | ValidatedBigQuery views provide analytical capability; Mixpanel receives PII-stripped UX events for real-time needs |
| A-008 | Labelling every event as either checking the build or testing the idea stays maintainable as the number of events grows | Medium | High | Active: enforcedCI enforcement via enforce-pr-contract.yml; event registry test validates purpose on all events |
| A-009 | Three storage tiers: Firestore for hot data, BigQuery for warm, blob storage for cold: is cost-effective at this scale | High | Medium | Validated at current scaleCost monitoring in place; PostgreSQL migration plan documented in docs/tech-debt/MIGRATION_PLAN_OSS.md |
| A-010 | The people using this are homeowners on phones and crews on tablets, so mobile-first is the right default | High | High | Assumed: reasonableDesktop progressive enhancement ensures both work; Chromatic tests both viewports |
| A-011 | Three service tiers (Curb Appeal, Full Lawn, Dream Lawn) match how residential landscaping is actually sold | High | High | Validated operationallyPer-tenant tier labels configurable; telemetry tracks tier selection for Va |
| A-012 | Automated pricing is accurate enough for lead generation, though not for invoicing | Medium | Critical | Active: high priorityML pipeline (CR-20260209) designed to close the loop; CRM outcome detection (CR-20260306) will provide ground truth |
| A-013 | A one-time code by text or email is enough to gate estimate detail and capture a lead without driving people away | Medium | High | Active: monitoringreCAPTCHA as secondary layer; rate limiting prevents abuse; verification events track completion rate |
| A-014 | One source of truth for design tokens, compiled per tenant, is enough to theme every tenant | High | High | ValidatedCompile-time is acceptable for current tenant count; revisit if dynamic tenant provisioning is needed |
| A-015 | Moving address search to the server removes the slowness caused by sending a 6MB search index to the phone | High | High | ValidatedCase study documented in docs/case-studies/ADDRESS_INDEX_ARCHITECTURE.md |
| A-016 | A public mirror of lead data gives the sales team enough visibility without exposing personal details | High | High | Validated with gapmirrorLeadToPublic Cloud Function trigger handles sync; gap indicates timing or error: needs investigation |
| A-017 | Naming the allowed host per tenant is enough to secure embedding without managing origins dynamically | High | High | Validateddata-base-url attribute provides escape hatch for edge cases; TENANT_ORIGINS mapping (CR-20260311) handles CDN proxying |
| A-018 | Working out the tenant from the web address is enough for white-label hosting, without provisioning each one | High | High | Validated at current scaleAcceptable for current 3-tenant model; dynamic provisioning deferred to future EPIC |
| A-019 | Giving each tenant its own data path prevents one tenant reading another's leads, without row-level security | High | Critical | ValidatedCross-tenant regression suite in place |
| A-020 | A baseline with a bounded override is more robust than putting the model first | High | Critical | Active: partially validatedHeuristic baseline always computed; ML is additive not required; CRM outcome data will enable validation |
| A-021 | Absorbing the typical bore cost, about $750, into irrigation base pricing produces cleaner estimates without underpricing | Medium | Medium | Active: monitoring$750 based on typical one-bore scenarios; actual bore work priced correctly during installation |
| A-022 | Carrying CRM updates on events we already send avoids duplication and keeps the CRM interchangeable | High | High | Active: partially validatedGeneric crm_* events designed for future providers; HubSpot namespace isolation prevents vendor lock-in |
| A-023 | Pulling modules out behind interfaces lets them be tested without touching the filesystem or the cloud | High | High | ValidatedRepeatable pattern documented for future module extraction |
| A-024 | Keeping each region's field mappings in validated configuration files is more maintainable than writing them in code | High | Medium | ValidatedJSON Schema export from Pydantic for IDE autocomplete is future improvement |
| A-025 | Feeding real outcomes back from the CRM will improve pricing accuracy by 15 to 25 percent within six months | Low | Critical | Unvalidated: infrastructure readyAll infrastructure in place; blocking dependency is CRM deal outcome detection (CR-20260306); measurement via BigQuery ml_hypothesis_metrics view |
| A-026 | Deals that were lost are as valuable as deals that were won for calibrating pricing | Medium | High | Active: manual capture shipped; native subscription pendingCR-20260306 epic closed 2026-03-23 (#348); manual capture path shipped July 2026; native loss-reason capture in build (#890) |
| A-027 | Partner sites will rewrite our embed script's address, so detecting where it loaded from is unreliable | High | High | Validated (learned from incident)Hardcoded TENANT_ORIGINS mapping is deterministic and CDN-immune; data-base-url attribute for edge cases |
| A-028 | Dividing Phoenix, 500 square miles, by ZIP code is explainable to buyers and maintainable for exclusivity sales | Medium | High | Active: pre-productionConfig update process needed for ZIP changes; unmapped parcels route to parent maricopa region |
| A-029 | Creating the deal automatically improves close rate by at least 10 percent against keying it in by hand | Low | High | Unvalidated: measurable via BigQueryBigQuery fact_lead_ml.deal_won rate by source enables measurement |
| A-030 | Feeding real outcomes back will close the gap between the estimate and what the job finally sold for, by 15 to 25 percent within six months | Low | Critical | Unvalidated: infrastructure readyMeasurement query defined in hypothesis registry; requires sufficient closed-deal volume first |
| A-031 | Aligning 2026 pricing to the official spreadsheet produces correct estimates for Quiet Village customers | Medium | Critical | Active: under validationyarn test:regression:quiet-village guards against drift; qvl2026PricingValidated telemetry tracks sign-off |
| A-032 | The stored area figure is already adjusted, so anything downstream must not adjust it again | High | High | Active: fix in progressSemantic model documented; regression tests will validate fix |
Дизайн
Домовладелец ничего не измеряет. Вы вводите адрес и выбираете свой дом из списка. Приложение берёт участок, вычитает постройки и показывает остаток зелёной меткой рядом с адресом. Цена равна этой площади, умноженной на собственную ставку подрядчика за квадратный фут.
Инструмент считает цены только для адресов, выбранных из списка. Если вашего адреса там нет, он прямо об этом говорит и предлагает лист ожидания, а не гадает. На код, который превращает данные округа в этот список, подана заявка на патент, но патент ещё не выдан.

Ещё экраны






Итерации
Первая версия была ориентирована на монтаж. Вы вводили адрес и выбирали один из трёх разовых пакетов, Curb Appeal, Full Lawn или Dream Lawn, а изометрический рисунок дома перерисовывал двор, показывая, что вы покупаете. Full Lawn по одному адресу стоил $106 564, или $16,30 за квадратный фут.
Инструмент считал цену не той работы. Jeff Haring посмотрел раннюю версию и сказал: «Для обслуживания это отлично; для монтажа пока не совсем готово. Там всё усложняется, как только начинаешь копать». Через пять месяцев мой первый пилотный клиент без подсказки провёл ту же границу. Поэтому пакеты превратились в ежемесячный уход: Quiet Village переписала свои цены на обслуживание в виде единой ставки за квадратный фут, её пакеты стали ежемесячными планами GEM, а земляные работы переехали на отдельную вкладку по выбору.
Некоторые уроки дались тяжело. Отправка на телефон всего списка адресов, шести мегабайт, замедляла страницу и ломалась на iPhone, поэтому теперь сервер отвечает на каждый поиск. Сайт одного партнёра переписывал адрес моего кода и ломал форму расчёта, поэтому теперь приложение знает каждого партнёра по имени, а не угадывает.



Решение, которое не сработало
Калькулятор октября 2025 года просил домовладельца ползунком указать, какой части двора нужна работа. Люди ошибались, а цена в любом случае выглядела одинаково правдоподобно. Неверный ответ, который выглядит верным, хуже отсутствия ответа, потому что его никто не замечает.
Поэтому для покоса и ухода я перестал спрашивать и стал сам измерять участок по данным округа о недвижимости. Выбор площади переехал в дополнительные услуги, где спрашивать о площади как раз уместно.
Результаты
TerraQuotes работает. Домовладелец примерно за минуту получает пакет обслуживания с ценой, без звонка продавца, а заявки уходят пилотному оператору Quiet Village Landscaping. В отчёте о продажах одного подрядчика все 38 заявок получили цифру в ту же минуту; девять записались на визит, и четыре превратились в заказы.
Чего я пока не могу сказать, так это насколько точна цена. Тест точности я отбросил до того, как его оценил, потому что в 215 из 347 старых строк о продажах ежемесячная цена смешивалась с двумя разовыми, и различить их было нечем. 14 июля 2026 года я задал планку, которую модель должна преодолеть, чтобы её стоило строить, на основе моделирования, а не догадки. Тестовая модель, обученная в июле, выбрала победителя в 47 случаях из 100 против 50 у монеты и моего порога в 60, и ни одна модель ещё ни разу не рассчитывала цену реального предложения.
Порог обучения: 75 выигранных и 225 проигранных работ, прежде чем модели разрешат учиться. Сейчас у неё 6 и 49.
63 отслеживаемых требования, и отдельным списком 19 требований, которые выходят с известным пробелом.
Для ландшафтных компаний
Мгновенные цены по вашим собственным ставкам
Домовладельцы вводят адрес и видят цену для своего участка. Без звонка продавца.




