|
| 1 | +# LangChain Deep Agents + KYC Onboarding (Python) |
| 2 | + |
| 3 | +This example builds a KYC onboarding agent that runs automated due diligence on a company |
| 4 | +using LangChain Deep Agents for orchestration, Stagehand for browser interactions, and |
| 5 | +Browserbase for headless browser sessions. |
| 6 | + |
| 7 | +The agent navigates real portals — Secretary of State sites, FinCEN BOI, OFAC, PACER, SEC EDGAR, |
| 8 | +and news publishers — rather than relying on search or fetch APIs alone. Browserbase Agent Identity |
| 9 | +handles anti-bot measures and CAPTCHAs automatically. |
| 10 | + |
| 11 | +## Architecture |
| 12 | + |
| 13 | +**Phase 1 — five-track fan-out:** |
| 14 | + |
| 15 | +| Subagent | Portals | |
| 16 | +|---|---| |
| 17 | +| `corporate-registry` | Secretary of State portals (Delaware, California, New York, UK Companies House) | |
| 18 | +| `beneficial-ownership` | FinCEN BOI, UK PSC register, EU member-state registries | |
| 19 | +| `sanctions-pep` | OFAC SDN, EU consolidated list, UK HMT financial sanctions | |
| 20 | +| `litigation-regulatory` | PACER, state courts, SEC EDGAR | |
| 21 | +| `adverse-media` | Reuters, Bloomberg, FT, WSJ, SEC newsroom, DOJ press releases | |
| 22 | + |
| 23 | +**Phase 2 — individual KYC fan-out:** |
| 24 | + |
| 25 | +After the `beneficial-ownership` subagent returns a list of ultimate beneficial owners (UBOs), |
| 26 | +the orchestrator delegates one `individual-kyc` subagent call per person. Each individual check |
| 27 | +covers sanctions screening, PEP status, and adverse media. |
| 28 | + |
| 29 | +**Tools (defined in `kyc_tools.py`):** |
| 30 | + |
| 31 | +- `kyc_search`: Browserbase Search for initial discovery before opening portals |
| 32 | +- `kyc_fetch`: Browserbase Fetch for static pages (EDGAR filings, public registries) |
| 33 | +- `kyc_extract_from_portal`: opens a Browserbase session and extracts structured data from a |
| 34 | + rendered portal page using Stagehand `extract` |
| 35 | +- `kyc_search_portal`: opens a Browserbase session and runs a multi-step browser task (form fills, |
| 36 | + paginated search navigation) using a Stagehand agent — gated behind human approval |
| 37 | + |
| 38 | +Every browser session produces a session replay URL included in the tool response for audit purposes. |
| 39 | + |
| 40 | +## Requirements |
| 41 | + |
| 42 | +- Python 3.11+ |
| 43 | +- `BROWSERBASE_API_KEY` for Browserbase Search, Fetch, and browser sessions (including Stagehand) |
| 44 | +- An OpenAI-compatible model for the Deep Agent orchestrator |
| 45 | + |
| 46 | +The sample accepts `OPENAI_API_KEY` for direct OpenAI access, or `BROWSERBASE_API_KEY` paired with |
| 47 | +`DEEPAGENT_BASE_URL` for a Browserbase-backed OpenAI-compatible gateway. |
| 48 | + |
| 49 | +Default models: |
| 50 | +- Deep Agent orchestrator: `gpt-4o` |
| 51 | +- Stagehand extraction: `google/gemini-3-flash-preview` |
| 52 | +- Stagehand interactive agent: `anthropic/claude-sonnet-4-6` |
| 53 | + |
| 54 | +## Install |
| 55 | + |
| 56 | +```bash |
| 57 | +cd examples/integrations/langchain/kyc-onboarding |
| 58 | +python3 -m venv .venv |
| 59 | +source .venv/bin/activate |
| 60 | +pip install -r requirements.txt |
| 61 | +``` |
| 62 | + |
| 63 | +## Environment |
| 64 | + |
| 65 | +Copy `.env.example` to `.env` and fill in your keys: |
| 66 | + |
| 67 | +```bash |
| 68 | +cp .env.example .env |
| 69 | +``` |
| 70 | + |
| 71 | +```ini |
| 72 | +BROWSERBASE_API_KEY=bb_... |
| 73 | + |
| 74 | +# Use direct OpenAI |
| 75 | +OPENAI_API_KEY=sk-... |
| 76 | + |
| 77 | +# Or use the Browserbase Model Gateway instead (no separate OpenAI key needed) |
| 78 | +# DEEPAGENT_BASE_URL=https://<your-gateway> |
| 79 | + |
| 80 | +# Optional model overrides |
| 81 | +# DEEPAGENT_MODEL=gpt-5.4 |
| 82 | +# STAGEHAND_MODEL=google/gemini-3-flash-preview |
| 83 | +# STAGEHAND_AGENT_MODEL=anthropic/claude-sonnet-4-6 |
| 84 | +``` |
| 85 | + |
| 86 | +## Run |
| 87 | + |
| 88 | +Use the default demo company: |
| 89 | + |
| 90 | +```bash |
| 91 | +python main.py |
| 92 | +``` |
| 93 | + |
| 94 | +Run on a specific company and jurisdiction: |
| 95 | + |
| 96 | +```bash |
| 97 | +python main.py "Stripe, Inc." --jurisdiction Delaware |
| 98 | +python main.py "Revolut Ltd" --jurisdiction "United Kingdom" |
| 99 | +``` |
| 100 | + |
| 101 | +Override the model: |
| 102 | + |
| 103 | +```bash |
| 104 | +python main.py "Acme Corp Inc." --jurisdiction Delaware --model gpt-4o |
| 105 | +``` |
| 106 | + |
| 107 | +## Approval flow |
| 108 | + |
| 109 | +`kyc_search_portal` is gated behind `interrupt_on`. Whenever the agent wants to submit a search |
| 110 | +form, navigate paginated results, or interact with a portal, the script pauses and prompts: |
| 111 | + |
| 112 | +``` |
| 113 | +Pending tool call |
| 114 | +Tool: kyc_search_portal |
| 115 | +Arguments: |
| 116 | +{ |
| 117 | + "start_url": "https://icis.corp.delaware.gov/ecorp/entitysearch/namesearch.aspx", |
| 118 | + "task": "Search for 'Acme Corp Inc.' and extract the entity status, formation date, and registered agent." |
| 119 | +} |
| 120 | +Allowed decisions: approve, edit, reject |
| 121 | +Decision [approve/edit/reject]: |
| 122 | +``` |
| 123 | + |
| 124 | +- `approve` — run the task as proposed |
| 125 | +- `edit` — provide replacement JSON args before running |
| 126 | +- `reject` — skip this action |
| 127 | + |
| 128 | +This puts human review at the tool boundary rather than inside ad hoc shell calls. |
| 129 | + |
| 130 | +## Notes |
| 131 | + |
| 132 | +- `kyc_extract_from_portal` maps to Stagehand `extract` — structured, read-only extraction from a rendered page. |
| 133 | +- `kyc_search_portal` maps to Stagehand `agent().execute()` — multi-step agentic browsing for portals that require interaction. |
| 134 | +- Browserbase Agent Identity manages browser fingerprinting, residential proxy routing, and CAPTCHA solving. No additional configuration is needed beyond `BROWSERBASE_API_KEY`. |
| 135 | +- Each `kyc_search_portal` and `kyc_extract_from_portal` response includes a `session_url` field linking to the Browserbase session replay. These replays provide visual evidence for audit workpapers. |
| 136 | +- The individual-kyc Phase 2 fan-out is driven by the orchestrator parsing the `beneficial-ownership` subagent report. If the registry is not publicly searchable, the subagent notes this explicitly and Phase 2 proceeds with whatever names were found. |
| 137 | + |
| 138 | +## Suggested prompts |
| 139 | + |
| 140 | +- `python main.py "Anthropic, PBC" --jurisdiction Delaware` |
| 141 | +- `python main.py "Klarna Bank AB" --jurisdiction Sweden` |
| 142 | +- `python main.py "Acme Corp Inc." --jurisdiction Delaware` (demo company, expect sparse results) |
0 commit comments