このページでは、Browserflowが何であり、どの問題を解くために存在し、どの1つの信念に基づいて作られ、このドキュメント全体がどう構成されているかを説明します。すぐに何かを実行したい場合は、クイックスタートに進むか、最初のFlowを作ってください。
ホスト型プロダクトを探していますか? Jinba Trail はBrowserflowの上に構築されたWebサービスです。ブラウザータスクを自然文で説明し、AIエージェントが記録した内容をレビューし、決定論的なHTTPSエンドポイントとして公開できます。エンジンコードは不要です。このページと残りのエンジンdocsは、その下にあるオープンソースSDKを扱います。

問題

チームは同じような自動化を2通りの方法で行いがちで、どちらも失敗します。
  • 閉じ込められたホスト型オーケストレーター。 強力ですが、自分のラップトップで動かしたり、forkしたり、安価にセルフホストしたりできません。プロセスは他者のランタイム内に置かれます。
  • 接着剤スクリプトの引き出し。 ネットワークが一瞬途切れる、依存関係が新しいバージョンへ浮動する、理解していた1人が離れる、そうした瞬間までは動きます。
どちらのモードでも、最初の犠牲者は再現性です。そして「AIにworkflowを再生成してもらえばいい」は再現性の話ではありません。余分なレイテンシとコストが付いたコイントスです。プロセスを再生成することは、同じように実行される保証とは違います。 本当に難しい部分は合成です。「価格を調べ、下がっていたらwebhookにpostしてticketを開く」。手順をつなぐところこそ、多くのシステムが上の2つのfailure modeのどちらかに戻ってしまう場所です。

1つの信念

Browserflow は、1つの信念に基づいてゼロから作られています。
プロセスの定義それが同じように実行される保証こそがプロダクトです。それ以外、storage、transport、UI、hostingはすべてadapterです。
このドキュメント全体では、それを具体化するために1つの実行例を使います。daily-price-watch です。browser tool search-price@1.2.0を実行し、結果をtransformし、価格が下がったときにsecret webhookへ条件付きでhttp.postするFlowです。一度作成してpinすれば、ラップトップ、CI、RESTエンドポイントの背後で同一に実行されます。runtimeで何かを決めるmodelはありません。
参照であり、依存ではありません。 Browserflowはsibling projectであるbrowser-flowから哲学を借りています。runtimeにLLMを置かない、author once / run forever、content-addressedなprovenance、secrets at the boundary。しかし、そのcodeは一切importしていません。自己完結しています。

何であるか

次を備えたワークフローエンジン兼サービスです。
  • 2つのオーサリング面。fluentで型安全なTypeScript SDKと、宣言的なYAML formatです。どちらも1つのFlowSpec(IR)へloweringされます。SDK and YAMLを参照してください。
  • 決定論的な実行エンジン(“Rider”)。DAG of stepsをretries、idempotency、checkpointing、resume付きでscheduleし、runtimeではmodelを呼びません。Executionを参照してください。
  • Tool contract。browser automation(Playwright)、HTTP call、shell command、pure transform、または独自処理など、任意の決定論的unit of workをwrapします。Tools and Packsを参照してください。
  • Pack system。ToolsとFlowsをまとめたversionedでcontent-addressedなbundles(デプロイする”SDKs”)を、registriesへpublishし、registries間でreplicateします。Packsを参照してください。
  • Launcher layer。CLI、REST、MCP、cron、CI、container、edgeにまたがって、engineを変更せずに実行します。Launchersを参照してください。
  • optionalなcontrol plane。engineをserviceにします。scheduling、secrets、RBAC、replication、run inspectorを追加します。Control planeを参照してください。
同じdaily-price-watch Flowを2通りで作成すると、次のようになります。2つの顔、1つの真実(tenet T1)であり、同一のFlowSpec digestへコンパイルされます。
import { flow, http, browser, transform } from "@browserflow/sdk";
import { z } from "zod";

export const dailyPriceWatch = flow("daily-price-watch")
  .input("query", z.string())
  .input("threshold", z.number())
  .input("webhook", z.string().url(), { secret: true })
  .step("lookup", browser.tool("search-price@1.2.0").with((c) => ({ query: c.input.query })))
  .step("shape", transform((c) => ({ price: c.steps.lookup.output, at: c.now })))
  .branch("dropped?", (c) => c.steps.shape.output.price < c.input.threshold, {
    yes: (f) => f.step("notify", http.post((c) => c.secret.webhook, (c) => c.steps.shape.output)),
    no:  (f) => f.noop("unchanged"),
  })
  .output((c) => ({ price: c.steps.shape.output.price }));
flow: daily-price-watch
inputs:
  - { name: query,     type: string }
  - { name: threshold, type: number }
  - { name: webhook,   type: string, secret: true }
steps:
  - id: lookup
    use: browser:search-price@1.2.0
    with: { query: ${{ input.query }} }
  - id: shape
    use: transform
    with:
      expr: { price: ${{ steps.lookup.output }}, at: ${{ now }} }
  - id: notify
    use: http.post
    when: ${{ steps.shape.output.price < input.threshold }}
    with:
      url:  ${{ secret.webhook }}
      json: ${{ steps.shape.output }}
output: { price: ${{ steps.shape.output.price }} }
正確なSDKとYAML surfaceはSDK and YAMLで定義されています。expression syntax(${{ ... }})はexpression languageで扱います。

何ではないか

意図的な非目標が4つあります。
  • AI agent frameworkではありません。 実行pathにmodelはありません。AIはFlowの作成を助けることがあります(stepをsuggestする、YAML draftを書く)。しかし、runtimeでFlowが何をするかは決めません。stepからmodelを呼ぶことはできますが、それはrecorded inputs and outputsを持つ通常のdeclared Toolであり、隠れたdecision-makerではありません。
  • general programming languageではありません。 Flowsはtyped stepsのgraphsであり、arbitrary codeではありません。escape hatch(code tool)はありますが、happy pathはdeclarativeでinspectableです。
  • 丸ごと採用しなければならないplatformではありません。 coreはlibraryとbinaryです。serviceはopt-inで置き換え可能です。Open core、Apache-2.0です。
  • infrastructureに強い意見を持ちません。 storage、queues、secrets、transportはinterfacesであり、妥当なlocal defaults(SQLite、filesystem)があります。

8つの設計原則

これらのtenetsはload-bearingです。将来のdecisionがこれらと衝突する場合、明示的に文書でoverrideされない限りtenetが勝ちます。
TenetNameGist
T1One truth, two facesSDKとYAMLは対等なfirst-class citizenです。どちらもFlowSpecへコンパイルされ、FlowSpecはYAMLへround-tripできます。片方のsurfaceでしか動かないtoolはbugです。
T2Deterministic by default, effects by permissionstepは、そうでないと宣言するまではpureです。time、randomness、environment、network、filesystem、secrets、process spawningは、ambientではなくrun contextを通じて注入されるcapabilitiesです。
T3Reproducibility is content-addressedFlowはstableなsha256 digestを持つcanonical FlowSpecへコンパイルされます。flow digest、tool/pack versions、recorded inputsをpinすれば、runは任意のmachineでofflineでも再現可能です。digestこそがversionです。
T4Portable core, pluggable edgesengineは少数のinterfaces(StoreClockRandomSecretsLoggerToolHostJournal)だけに依存します。すべてのlauncherとbackendがそれらを実装します。engineはcloud SDKをimportしません。
T5Minimal code, maximal legibility新しいtoolは、Zod-typedなinput/output schemaとrun functionを持つ小さなobjectです。新しいlauncherはengine.run()を包む薄いshellです。featureが大量のcore codeを必要とするなら、おそらくPackに属します。
T6Local-first, cloud-optionalすべてzero infrastructureで動きます。stateにはSQLite、artifactsにはfilesystem、secretsにはfileを使えます。scale outはimplementationを差し替えることであり、conceptを差し替えることではありません。
T7Fail loud, resume cleanerrorsはtyped(DomainError lineage)であり、原因となったstep、input、journal frameとともにsurfaceされます。どのrunも、完了済みstepsを再実行せず、最後のdurable checkpointからresumeします。
T8Boring on purpose, secrets at the boundarystable formats、explicit versions、clever globalsなし。secret: trueとmarkされたinputsはFlowSpec、journal、log、published Packに入りません。値は、secrets capabilityをdeclaredしたstepの内部でのみ、runtimeに解決されます。
daily-price-watch exampleは、これらの多くを同時に使います。secret WEBHOOK_URLはboundaryに留まり(T8)、browserとhttp.post stepsはbrowser/network capabilitiesをdeclaredし(T2)、Flow全体はofflineでreplayできる1つのsha256 digestにpinされます(T3)。

60秒のメンタルモデル

1

作成する

fluentなTypeScript SDKまたはdeclarativeなYAML formatで、Flowを一度書きます。どちらもfirst-classです(T1)。
2

コンパイルする

compilerはどちらのsurfaceも1つのcanonical FlowSpecへlowerし、sha256 digestを付けます。digestがversionです(T3)。
3

実行する

RiderはDAGをscheduleし、PackからresolvedしたToolsをinvokeし、Journalを書きます。retries、idempotency、resumeを備え、modelはloopに入りません。
4

リプレイする

digest、pack versions、recorded inputsをpinし、任意のmachineでofflineでもRunをバイト単位で再現します。testing and replayを参照してください。

このドキュメントの構成

コンセプト

big picture、architecture、FlowSpec、Tools、Packs、Runsを支える正確なdomain model。

オーサリング

SDKまたはYAMLでFlowsを書く方法。2つの顔、1つの真実。expression languageとcontrol flowも扱います。

Runtime: ToolsとPacks

Tool contract、standard packs(http、transform、shell、fs、control、model)、browser tool。

Service: コントロールプレーン

optionalでopt-inなplane。scheduling、secrets、RBAC、replication、run inspector。

最初のFlowを作成する

daily-price-watch Flowをend to endで構築し、実行するhands-on walkthrough。

用語集

FlowSpec、Rider、Pack、Launcher、capability、Journalなど、すべてのtermを1か所で正確に定義します。

次のステップ

インストール

browserflow binaryとSDKをlocalにセットアップします。

クイックスタート

zero infrastructureで数分のうちにFlowをcompileしてrunします。

ロードマップ

build orderを確認します。contracts、engine、authoring、browser、packs、launchers、service。

アーキテクチャ

portable coreとpluggable edgesがどう組み合わさるか。