スタートアップのBIプロジェクトは、多くの場合、早すぎる段階で大きく始まりすぎます。
Founderがシンプルな問いを投げます。「このチャネルから来たユーザーは、最初のRunのあと戻ってきているのか?」本来なら、これはクエリで答えられるべき問いです。ところが実際には、あらゆるデータソースを接続し、warehouseを作り、イベントを定義し、IDを整理し、dashboardを組み、そして待つ、というプラットフォームプロジェクトになりがちです。
もちろん、その仕事はいずれ重要になります。しかし小さなチームにとって、それは最初の一手として重すぎることがあります。プロダクトのデータベースには、Founderが知りたいことの多くがすでに入っています。誰が登録したか、誰が何かを実行したか、何を使ったか、どれだけコストがかかったか、何が失敗したか、そして戻ってきたか。
本当の問題は、真実がどこにあるかではありません。Agentにその真実を分析させながら、raw production databaseを露出させない方法です。
VM0で使っているのはこのパターンです。maskedかつread-onlyのNeon branchを用意し、AgentがBIを行うのに十分な真実を渡しながら、見せるべきでないデータは見せない。
Founderの問題: Data teamより先に質問が来る
初期の会社に質問が足りないことはありません。足りないのは時間です。
Founder teamは毎日、こうしたことを知りたくなります。
- 昨日のtrafficは実際のユーザーになったのか?
- どのsignup channelが、本当に何かを実行するユーザーを連れてきているのか?
- First Runをしたユーザーは7日後、30日後に戻ってくるのか?
- どのpaid accountが静かになっているのか?
- どのmodel routeがコストを押し上げているのか?
- trial abuseがconvert前にcomputeを燃やしていないか?
- 昨日からproduct healthは良くなったのか、悪くなったのか?
どれも特別な問いではありません。スタートアップの日々の運営そのものです。
しかし従来型のBIの進め方で答えようとすると、大きなoverheadが生まれます。まずプロダクトDBから別のシステムにデータを移し、正規化し、metricを定義し、関係性を再構築し、dashboardを作る。チームはきれいなanalytics stackを手に入れますが、FounderはSQLから始められたはずの答えを、何日も何週間も待つことになります。
小さなスタートアップにとって、この順番は逆かもしれません。最初の20個の運営上の問いに答えるために、完全なdata platformは必要ありません。すでにあるsource of truthを安全に問う方法が必要なのです。
データベースはすでにSource of Truthである
VM0では、Founderレベルの意思決定に必要な事実の多くがプロダクトDBに入っています。
- Organizationとuser
- Signupとsubscription state
- Agent runsとschedules
- Credit consumptionとusage events
- Selected modelとprovider routes
- Connector state
- Failure stateとtimestamps
これらの関係性はすでに存在しています。どの下流dashboardよりも新しく、プロダクトの実態に近いものです。
これは重要です。初期のBIの問いの多くはrelationalだからです。Founderが知りたいのはpage viewsやrun countだけではありません。システム全体で行動をつなげたいのです。
このチャネルから登録したユーザーのうち、day zeroで何かを実行したのは何人で、その後first runのあと戻ってきたのは何人か?
あるいは:
この7日間まったくrunしていないpaid organizationはどれか?以前はactiveに見えていたのか?
あるいは:
abuse patrolを変える前後で、新しいtrial accountは最初の6時間にどれだけcomputeを使ったのか?
こうした問いは、プロダクトDBの中で自然に表現できます。すべての答えが、まず別のplatformへデータを移すことから始まると、途端に難しくなります。
危険な近道はraw production access
誘惑は明らかです。Agentにproductionを直接queryさせればよい。
しかしそれは受け入れられません。
Production databaseには、会社で最も敏感な情報が含まれます。email address、prompt、chat content、credential、encrypted provider state、log、error message、API key、内部運用記録。Agentが注意深くても、raw accessは境界の問題を作ります。Agentが見すぎてしまう。query、report、screenshotの一つのミスで、本来共有すべきでない情報が漏れる可能性があります。
write accessはさらに悪いです。BIがproductionを変更できてはいけません。人間であれAgentであれ、分析者が一つの悪いcommandでuser dataを変えられる状態にしてはいけません。
だから問題は、AgentがSQLを書けるかどうかではありません。書けます。問題は、privacyとsafetyを固い制約にしたまま、役に立つだけの真実を渡せるかどうかです。
私たちにとって、その制約こそが出発点でした。
- Agentはraw promptを見てはいけない。
- Agentはraw emailを見てはいけない。
- Agentはcredentialやsecretを見てはいけない。
- Agentはsensitive free-text logを見てはいけない。
- AgentはBI sourceにwrite accessを持ってはいけない。
- Founder teamは、それでも素早く運営上の問いを投げられるべき。
これが、私たちが必要としていたシステムの形でした。
安全な中間地点: masked read-only database
Neonはこのパターンを可能にします。branchがPostgres databaseの軽量で隔離されたcopyだからです。productionに近いbranchを作り、それを変換し、productionそのものではなくそのbranchを公開できます。
VM0ではこれをMaskDBと呼んでいます。
流れはシンプルです。
- Neonのproduction parent branchから始める。
- scheduleで新しいbranchを作る。
- PostgreSQL AnonymizerとVM0固有のmasking helperをinstallする。
- sensitive columnにsecurity labelを適用する。
- branch上でstatic anonymizationを実行する。
- 特別なfieldにfinal custom maskを適用する。
SELECT権限だけを持つmasked_readonlyroleを作る。- Agentにはproductionではなく、そのroleをqueryさせる。
重要なのは、maskingがstaticであることです。Agentが接続する前に、sensitive valueはmasked branch上で書き換えられます。これは、後続のqueryすべてに「何をselectしてはいけないか」を覚えさせるのとは違います。branchそのものが境界になります。
私たちのMaskDBでは、credentialとsecretはredactされます。emailとphone numberはpartial maskされます。prompt、chat message、schedule prompt、agent outputのようなuser contentは削除されます。error textはfull stackやmessageではなくclassに縮約されます。分析に出すべきでないtableはまるごとdropできます。
一方で、org_id、user_id、clerk_user_idのようなopaque identifierはjoin可能なまま残します。これがBIを可能にします。Agentが個人のemail addressやprompt textを知る必要はありません。しかし、同じorganizationが登録し、taskをrunし、creditを消費し、subscribeし、dormantになり、あとで戻ってきたことは知る必要があります。
要点はこのバランスです。人間が読めるsensitive materialをmaskし、relational spineを残す。
境界ができるとAgentに何ができるか
masked read-only databaseが存在すると、Agentはすぐに役に立ちます。
プロダクトデータに対して直接質問できます。
- 7-day / 30-day user retention
- Registration-to-first-run activation
- First-run-anchored retention
- Dormant paid orgs
- Subscription stateとchurn watch
- Selected model別のmodel usage
- Built-in routeとuser-provider route
- Trial compute consumption
- Model別cost per run
- Cohort別failure rateとcompletion rate
さらに、そのdatabase truthを周囲のsystemと組み合わせることもできます。
私たちのMorning Briefは、Plausible、Axiom、Sentry、Google Ads、GitHubなどのoperational sourceから情報を集めます。databaseはuserとorgが何をしたかを示します。Plausibleはsite上で何が起きたかを示します。PostHogはproduct event contextを補えます。Axiomはlogとrequest pathを示します。Sentryはerrorを捕捉します。StripeとClerkはbillingとidentityを説明します。GitHubはengineering throughputを示します。
目的は、すべてのtoolをSQLで置き換えることではありません。Founderが本当に気にする事実をAgentがつなげられるようにすることです。
たとえば:
昨日はPaid Googleのtrafficがorganicを上回った。そのuserは本当にfirst runまで到達したのか、それともfunnel上部で止まったのか?
あるいは:
trial-abuse patrolを変更した。新しいtrial accountは最初の数時間に燃やすcomputeが減ったのか?
あるいは:
このmodel routeはrunあたり安い。実際のhistorical chat usageにもそれは出ているのか、それともpricing theoryだけなのか?
これらはdashboardの問いではありません。運営の問いです。週ごとに、時には日ごとに変わります。安全なdatabase accessを持つAgentなら、Engineeringに毎回新しいviewを作ってもらわなくても答えられます。
実例: retentionとexternal user health
私たちの内部日次分析の一つは、過去24時間のexternal user healthを見ます。
reportはMaskDBから始まり、厳格なexclusion setを適用します。内部VM0 orgを除外します。Clerkでbannedまたはlockedされたspam orgを除外します。同じexclusion setをすべてのmetricに適用します。registration countやretention cohortにも適用するので、denominatorが監査可能になります。
そこからAgentはcompactなoperating reportを作れます。
- Runsとactive external orgs
- Completion rate
- Web、CLI、schedule、non-Zero routeのtrigger mix
- Model mix
- Provider mode
- Paid org activity
- Dormant paid orgs
- New paid signupsとtrialing orgs
- Churn watch
- 30-day segmentation
- Registration-to-run retention
- First-run retention
これはFounder teamが必要とするreportそのものです。raw promptは不要です。raw emailも不要です。production write accessも不要です。
必要なのは、product factを正しくjoinできることです。
あるrunでは、少数のactive external orgがvolumeの大半を生み、いくつかのpaid orgが静かになっており、最近のregistration cohortに大きなactivation cliffがあることが分かりました。おそらくspam registrationがdenominatorを膨らませていたためです。これはFounderがすぐに見るべきことです。dashboard reviewで数週間後に気づくべきことではありません。
二つ目の実例: trial abuse economics
masked product dataは、classic BI chartではない問いにも役立ちます。
trial abuseを見たとき、有用なmetricはtotal compute spentではありませんでした。total spendは古いaccountに偏ります。古いaccountほどcreditを使う時間が長いからです。よりよい問いはこれでした。
新しいaccountはsignup後の最初の数時間でどれだけtrial computeを燃やすのか?
MaskDBを使い、Agentはregistration後のmatched windowでcompute consumptionを測りました。usage eventsのcredit consumption、org metadataのregistration timestamp、subscription stateを使い、trial economicsをpaid usageから切り分けました。
patrolがliveになったあと、signup後の最初の数時間でburnされる平均trial computeは80%以上下がりました。heavy-burn tailはほぼ消えました。90th percentileでは、first-hours trial computeが約4.05ドルから約0.26ドルへ下がり、94%の低下でした。
この数字は単なるanalytics pointではありません。businessの見方を変えます。abuseを検知しているだけでなく、trialのunit economicsが正しい方向に動いていることをFounder teamに示します。
それが可能だったのは、databaseが真実を持ち、masked branchがその真実をAgentに安全に分析させたからです。
三つ目の実例: 実プロダクトでのmodel cost
pricing pageやbenchmark sheetは役立ちます。しかしFounderが本当に知りたい問いには答えません。
このmodelは、私たちの実プロダクトで、実際のrun全体を通じてどれだけコストがかかるのか?
MaskDBを使い、Agentはhistorical chat runを比較しました。run recordを、そのrun時点で選択されていたmodelとjoinし、usage eventsからcharged creditsをaggregateしました。
この違いは重要です。historical runをuserの現在のdefault model providerでattributeすべきではありません。defaultは変わるからです。run時点でselected modelだったものがsource of truthです。
私たちの分析では、DS v4 Proのmedian model-credit cost per chat runはSonnetの約49%でした。つまり実際のmedian chat runは、このrouteではおよそ51%安かったということです。
これもFounder-level BIです。product behavior、infrastructure cost、model strategyをつなぎます。新しいwarehouseは必要ありません。必要なのは、正しいrelational dataへの安全なaccessです。
これはwarehouseを永遠に置き換えるものではない
会社がより正式なdata stackを必要とする時期は来ます。
metricに強いsemantic governanceが必要になり、多くのteamが同じdefinitionに依存し、historical backfillが複雑になり、dashboardが会社のoperating systemの一部になるなら、warehouseやlakehouseは正しい答えになり得ます。
しかし多くのstartupは、その答えに早く到達しすぎます。
小さなFounder teamにとって、最初のBI systemは質問に答えるものであるべきです。保守すべき二つ目のプロダクトを作るべきではありません。masked databaseはそのbridgeになれます。data modelingが重要ではないと言っているのではありません。product databaseには、次の意思決定に必要な関係性がすでにあると認めているのです。
Agentは判断を置き換えません。分析の最初のversionを安く実行できるようにします。
Founder teamのためのパターン
パターンはシンプルです。
- Product databaseを最初のsource of truthとして扱う。
- raw productionをAgentに公開しない。
- 手作りのsample datasetではなく、production-like branchを使う。
- access前にsensitive columnをstaticにmaskする。
- analysisが機能するよう、opaque join identifierは残す。
- read-only roleでbranchを公開する。
- Agentに、MaskDBと周囲のtoolを横断してanalyst loopを実行させる。
これによりFounder teamは、完全なdata platformを先に作らなくても、実用的なoperating systemを手に入れられます。
Security postureもより明確になります。Agentには硬い境界があります。Agentが見るdatabaseはすでに変換されています。Agentが使うroleは書き込めません。Agentが作るreportはhashed identifierやaggregateに制限できます。
これがVM0で求めていたバランスでした。privacyとsecurityをtradeoffではなく土台にしながら、Founder teamがbusinessを理解する速度を大きく上げる。
Data Lakeを作る前に、product databaseのmasked read-only branchで、teamが次に本当に聞きたい20個の問いに答えられないかを考えてみてください。
私たちにとって、それがBIへの最短ルートでした。
参考
- Neon, "Create Environments with Masked Production Data Using Neon Branches": https://neon.com/blog/environments-masked-production-data
- Neon fork of PostgreSQL Anonymizer: https://github.com/neondatabase/postgresql_anonymizer


