How to Integrate Next.js for investment banking with Vercel AI SDK for AI agents

By Cyprian AaronsUpdated 2026-04-21
next-js-for-investment-bankingvercel-ai-sdkai-agentsnextjs-for-investment-banking

Why this integration matters

If you’re building AI agents for investment banking, the real problem is not chat. It’s getting the agent to sit inside a production web app, call approved tools, and return controlled outputs that bankers can trust. Next.js gives you the application layer; Vercel AI SDK gives you the agent orchestration layer.

The useful pattern here is simple: Next.js handles the authenticated UI and server routes, while Vercel AI SDK runs the model/tool loop behind an API boundary. That gives you a clean path for deal workflows, research assistants, document Q&A, and internal copilots.

Prerequisites

  • Python 3.10+
  • Node.js 18+ for the Next.js app
  • A Next.js investment banking application scaffolded with API routes or App Router route handlers
  • A Vercel account and an AI SDK-compatible model provider key
  • pip installed packages:
    • requests
    • pydantic
    • python-dotenv
  • Access to your internal banking APIs or mock services for:
    • deal data
    • market data
    • document retrieval
  • Environment variables configured:
    • VERCEL_AI_API_KEY
    • NEXTJS_APP_URL
    • BANKING_API_BASE_URL

Integration Steps

  1. Expose a Next.js route for the agent backend

    In this pattern, Next.js becomes the public entrypoint for your agent. The route handler receives user intent from the UI and forwards it to a Python service that runs the orchestration logic.

    import os
    import requests
    from pydantic import BaseModel
    
    class AgentRequest(BaseModel):
        user_id: str
        prompt: str
        context_id: str | None = None
    
    def forward_to_agent_service(payload: AgentRequest):
        url = f"{os.environ['NEXTJS_APP_URL']}/api/agent"
        response = requests.post(url, json=payload.model_dump(), timeout=30)
        response.raise_for_status()
        return response.json()
    
  2. Call the Vercel AI SDK-compatible agent endpoint from Python

    The Vercel AI SDK is usually consumed in TypeScript, but in a bank stack you often want Python services for risk checks, document parsing, or workflow orchestration. The clean integration point is an HTTP endpoint that uses Vercel AI SDK on the Next.js side.

    In Next.js, your route handler can use streamText from ai and expose it as /api/agent. Your Python service just posts to it.

    import os
    import requests
    
    def ask_agent(prompt: str) -> dict:
        payload = {
            "messages": [
                {"role": "system", "content": "You are an investment banking assistant."},
                {"role": "user", "content": prompt},
            ]
        }
    
        response = requests.post(
            f"{os.environ['NEXTJS_APP_URL']}/api/agent",
            json=payload,
            headers={
                "Authorization": f"Bearer {os.environ['VERCEL_AI_API_KEY']}",
                "Content-Type": "application/json",
            },
            timeout=60,
        )
        response.raise_for_status()
        return response.json()
    
  3. Add tool execution in Python for banking workflows

    Keep sensitive business logic in Python where you can validate inputs and log every action. The agent should request tools like get_deal_summary, fetch_market_comps, or search_filing, and your Python layer should execute them deterministically.

    import os
    import requests
    
    def get_deal_summary(deal_id: str) -> dict:
        url = f"{os.environ['BANKING_API_BASE_URL']}/deals/{deal_id}/summary"
        response = requests.get(url, timeout=20)
        response.raise_for_status()
        return response.json()
    
    def fetch_market_comps(ticker: str) -> dict:
        url = f"{os.environ['BANKING_API_BASE_URL']}/market/comps"
        response = requests.get(url, params={"ticker": ticker}, timeout=20)
        response.raise_for_status()
        return response.json()
    
  4. Wire tool results back into the agent loop

    Once your Python service gets tool calls from the Next.js/Vercel AI SDK layer, execute them and send results back as structured messages. This keeps prompts short and makes outputs auditable.

    import json
    from typing import Any
    
    def run_tool(tool_name: str, arguments: dict[str, Any]) -> dict:
        if tool_name == "get_deal_summary":
            return get_deal_summary(arguments["deal_id"])
        if tool_name == "fetch_market_comps":
            return fetch_market_comps(arguments["ticker"])
        raise ValueError(f"Unsupported tool: {tool_name}")
    
    def process_agent_request(agent_payload: dict) -> dict:
        messages = agent_payload["messages"]
        last_user_message = next(m for m in reversed(messages) if m["role"] == "user")["content"]
    
        # Example deterministic routing before calling model-backed reasoning.
        if "deal summary" in last_user_message.lower():
            tool_result = run_tool("get_deal_summary", {"deal_id": "D-10291"})
            return {
                "type": "tool_result",
                "data": tool_result,
            }
    
        return {
            "type": "message",
            "data": {"content": "No matching workflow found."},
        }
    
  5. Return structured JSON to Next.js and render it in the UI

    Bank users need predictable output, not free-form text blobs. Return fields like recommendation, confidence, sources, and next_action so your Next.js frontend can render them cleanly.

    import json
    
    def format_agent_response(tool_result: dict) -> dict:
        return {
            "recommendation": tool_result.get("recommendation", "Review required"),
            "confidence": tool_result.get("confidence", 0.0),
            "sources": tool_result.get("sources", []),
            "next_action": tool_result.get("next_action", "Escalate to coverage banker"),
        }
    
    # Example usage:
    result = format_agent_response({
        "recommendation": "Proceed to IC memo draft",
        "confidence": 0.86,
        "sources": ["deal_db", "market_data"],
        "next_action": "Generate first draft",
    })
    print(json.dumps(result, indent=2))
    

Testing the Integration

Use a simple smoke test that posts a banker-style query to your Next.js /api/agent route and checks for structured output.

import os
import requests

def test_agent_endpoint():
    payload = {
        "messages": [
            {"role": "system", "content": "You are an investment banking assistant."},
            {"role": "user", "content": "Summarize deal D-10291 and tell me if it is ready for IC."}
        ]
    }

    r = requests.post(
        f"{os.environ['NEXTJS_APP_URL']}/api/agent",
        json=payload,
        timeout=60,
    )
    r.raise_for_status()
    data = r.json()

    assert isinstance(data, dict)
    assert "recommendation" in data or "text" in data

    print(data)

test_agent_endpoint()

Expected output:

{
  "recommendation": "Proceed to IC memo draft",
  "confidence": 0.86,
  "sources": ["deal_db", "market_data"],
  "next_action": "Generate first draft"
}

Real-World Use Cases

  • Deal desk copilot

    • Pulls live deal summaries, compares comps, drafts IC notes, and flags missing diligence items.
  • Research assistant for bankers

    • Answers questions over filings, internal notes, and market snapshots with source-backed responses.
  • Client coverage workflow automation

    • Generates meeting prep packs, CRM updates, follow-up emails, and pipeline status summaries from approved data sources.

Keep learning

By Cyprian Aarons, AI Consultant at Topiax.

Want the complete 8-step roadmap?

Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.

Get the Starter Kit

Related Guides