How to Integrate CrewAI for investment banking with FastAPI for multi-agent systems

By Cyprian AaronsUpdated 2026-04-22
crewai-for-investment-bankingfastapimulti-agent-systems

Combining CrewAI for investment banking with FastAPI gives you a clean way to expose multi-agent workflows as production APIs. That matters when you need one endpoint to coordinate research, risk checks, and draft generation across multiple agents without turning your app into a monolith.

The pattern is simple: FastAPI handles request validation, auth, and HTTP lifecycle, while CrewAI handles task orchestration between specialized agents. For investment banking teams, that means you can wrap deal screening, market research, CIM drafting, or diligence workflows behind stable API endpoints.

Prerequisites

  • Python 3.10+
  • fastapi
  • uvicorn
  • crewai
  • pydantic
  • An LLM provider configured for CrewAI via environment variables
  • Basic familiarity with REST APIs and async web services
  • A project structure like:
    • app/main.py
    • app/agents.py
    • app/crew.py

Install the packages:

pip install fastapi uvicorn crewai pydantic

Set your model credentials before running the app:

export OPENAI_API_KEY="your-key"

Integration Steps

  1. Define your investment banking agents

Start by creating focused agents for the work you want to automate. In banking workflows, each agent should own one responsibility: market research, financial analysis, or memo drafting.

# app/agents.py
from crewai import Agent

market_research_agent = Agent(
    role="Market Research Analyst",
    goal="Collect and summarize relevant market data for an investment banking mandate",
    backstory="You analyze sector trends, comparable companies, and recent transactions.",
    verbose=True,
    allow_delegation=False,
)

risk_review_agent = Agent(
    role="Risk Review Analyst",
    goal="Identify execution risks and red flags in a transaction brief",
    backstory="You focus on concentration risk, valuation gaps, regulatory issues, and missing diligence items.",
    verbose=True,
    allow_delegation=False,
)

memo_drafting_agent = Agent(
    role="Investment Banking Associate",
    goal="Draft a concise client-ready transaction summary",
    backstory="You turn research outputs into clean banker-style language.",
    verbose=True,
    allow_delegation=False,
)
  1. Create tasks and assemble the crew

CrewAI works best when tasks are explicit. Define the sequence so each agent receives structured work from the previous step.

# app/crew.py
from crewai import Task, Crew, Process
from app.agents import market_research_agent, risk_review_agent, memo_drafting_agent

def build_investment_banking_crew(deal_name: str):
    research_task = Task(
        description=f"Research the market context for {deal_name}. Include comparable transactions and sector trends.",
        expected_output="A structured market summary with comps and key observations.",
        agent=market_research_agent,
    )

    risk_task = Task(
        description=f"Review the market summary for {deal_name} and identify execution risks.",
        expected_output="A list of deal risks with concise explanations.",
        agent=risk_review_agent,
        context=[research_task],
    )

    memo_task = Task(
        description=f"Draft an investment banking memo for {deal_name} using the research and risk findings.",
        expected_output="A polished banker-style memo suitable for internal review.",
        agent=memo_drafting_agent,
        context=[research_task, risk_task],
    )

    return Crew(
        agents=[market_research_agent, risk_review_agent, memo_drafting_agent],
        tasks=[research_task, risk_task, memo_task],
        process=Process.sequential,
        verbose=True,
    )
  1. Expose the crew through FastAPI

Now wrap the workflow in an API endpoint. Keep request/response models strict so downstream systems can rely on stable payloads.

# app/main.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from app.crew import build_investment_banking_crew

app = FastAPI(title="Investment Banking Multi-Agent API")

class DealRequest(BaseModel):
    deal_name: str

class DealResponse(BaseModel):
    result: str

@app.post("/analyze-deal", response_model=DealResponse)
def analyze_deal(payload: DealRequest):
    try:
        crew = build_investment_banking_crew(payload.deal_name)
        result = crew.kickoff()
        return DealResponse(result=str(result))
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

This is the core integration point. FastAPI receives the request, CrewAI runs the multi-agent workflow with kickoff(), and your API returns a single result object.

  1. Run it locally and validate the endpoint

Use Uvicorn to serve the application.

uvicorn app.main:app --reload --port 8000

If you want a cleaner production setup later, add background jobs or queue-based execution for longer-running banking analyses. For now, this synchronous pattern is enough to prove end-to-end connectivity.

  1. Add structured output handling

In real banking systems, returning raw text is not enough. You usually want sections like summary, risks, and recommendation separated for UI rendering or storage.

# app/main.py (extended pattern)
from fastapi import FastAPI
from pydantic import BaseModel
from app.crew import build_investment_banking_crew

class DealResponse(BaseModel):
    result: str

@app.post("/analyze-deal", response_model=DealResponse)
def analyze_deal(payload: DealRequest):
    crew = build_investment_banking_crew(payload.deal_name)
    result = crew.kickoff()

    return DealResponse(
        result=f"Completed analysis for {payload.deal_name}:\n{result}"
    )

For production use, parse the final agent output into JSON before returning it. That makes it easier to store in Postgres or feed into a frontend dashboard.

Testing the Integration

Test with curl or any REST client:

curl -X POST "http://127.0.0.1:8000/analyze-deal" \
  -H "Content-Type: application/json" \
  -d '{"deal_name":"Acquisition of MidCap Logistics"}'

Expected output:

{
  "result": "Completed analysis for Acquisition of MidCap Logistics:\n..."
}

If you want a quick Python test instead:

import requests

response = requests.post(
    "http://127.0.0.1:8000/analyze-deal",
    json={"deal_name": "Acquisition of MidCap Logistics"},
)

print(response.status_code)
print(response.json())

A successful run should return 200 and a response body containing the crew output.

Real-World Use Cases

  • Deal screening API
    Send a target company name and get back market context, valuation signals, and initial red flags before banker review.

  • Diligence assistant
    Route documents through multiple agents that extract financial risks, legal concerns, and missing data points.

  • Client memo generator
    Generate first-draft investment banking memos from structured prompts so associates spend time editing instead of starting from scratch.


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