guy-hartstein/company-research-agent: a LangGraph multi-agent pipeline for company diligence
An agentic company research tool powered by LangGraph and Tavily that conducts deep diligence on companies using a multi-agent framework. It leverages Google's Gemini 2.5 Flash and OpenAI's GPT-5.1 on the backend for inference.
At a glance
- What is it?
- The repository wires four research nodes and four processing nodes into a LangGraph pipeline that writes company reports with Gemini 2.5 Flash and GPT-5.1. It is a strong fit if you already pay for Tavily, Gemini and OpenAI and want a self-hosted report generator; it is a poor fit if you need one vendor, no API keys, or a deterministic financial model.
- Who is it for?
- Adopt it if you want a self-hosted, Apache-2.0 report generator and already hold Tavily, Gemini and OpenAI keys, or if you want to read a working LangGraph pipeline with separate research and editing stages. Do not adopt it if you need one vendor, offline operation, or auditable financial figures, because the output is model-written prose over search results.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 7 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What company-research-agent actually produces, and for whom
The repository describes itself as "a multi-agent tool that generates comprehensive company research reports." The output is a written report assembled from web sources: the company's own site, news articles, financial reports and industry analyses, according to the feature list. That places it in the same category as a research analyst's first pass, not a data terminal. Nothing in the repository claims structured financial statements, a valuation model, or verified figures.
The intended user is someone who needs a readable briefing on an unfamiliar company and is willing to pay three API vendors to get it. The pipeline needs a Tavily API key for search, a Gemini key for synthesis, and an OpenAI key for editing. A Google Maps API key is also listed as required in the setup section, and a MongoDB URI is marked optional for persistence. That is a real adoption cost before the first report exists.
It is a weak fit for regulated workflows. There is no citation enforcement described in the README, no schema for financial numbers, and no statement about how the models are prevented from asserting a figure that no source contained. If your diligence process requires a traceable number, this tool gives you prose you then have to check by hand.
The eight-node LangGraph pipeline, from search to edited report
The architecture splits into two halves. Four research nodes run first: CompanyAnalyzer for core business information, IndustryAnalyzer for market position and trends, FinancialAnalyst for financial metrics, and NewsScanner for recent developments. Four processing nodes follow: Collector aggregates their output, Curator filters it, Briefing writes category summaries, and Editor compiles the final document.
The model split is the design decision worth noting. Briefing runs on Gemini 2.5 Flash, which the README justifies on context length: it "excels at processing and summarizing large volumes of data." Editor runs on GPT-5.1, chosen for following formatting instructions precisely. The repository frames this as combining "Gemini's strength in handling large context windows with GPT-5.1's precision in following specific formatting instructions."
Curation is the part that decides what the models ever see. Documents receive relevance scores from Tavily's search, and a minimum threshold of 0.4 must be met before a document proceeds. Content is normalized and cleaned, URLs are deduplicated and standardized, and the surviving documents are sorted by score. That threshold is a single tunable number sitting between search quality and report quality, and the README does not discuss what happens when a legitimate company has thin coverage and everything scores below it.
Execution is asynchronous. FastAPI runs research tasks in the background, the client receives a job_id, and it polls GET /research/{job_id}/report until the report is ready. There is no websocket or server-sent event channel described, so progress granularity is whatever the polling endpoint returns. The README also notes real-time report streaming handled by the GPT-5.1 editor, which sits alongside the polling model rather than replacing it.
Installing company-research-agent and running a first research job
The README recommends the setup script, which detects uv and uses it for faster package installation when present. It checks Python and Node.js versions, optionally creates a virtual environment, installs both dependency sets, and walks through environment variables. Clone and run it:
git clone https://github.com/guy-hartstein/company-research-agent.git
cd company-research-agent
chmod +x setup.sh
./setup.shThe script asks for API keys during setup. If you prefer the manual path, the repository lists the Python dependencies in requirements.txt, including fastapi, langchain, langchain-openai, langchain-google-genai, tavily-python and reportlab. The uv route is the one the README highlights:
uv venv .venv
source .venv/bin/activate
uv pip install -r requirements.txtThe frontend lives in ui/ and installs separately:
cd ui
npm installTwo .env files are needed, one for the backend and one for the frontend. The backend file at the project root takes the keys shown in .env.example:
TAVILY_API_KEY=
OPENAI_API_KEY=
GEMINI_API_KEY=Note that .env.example contains only those three keys, while the setup instructions also list a Google Maps API key and an optional MongoDB URI. Fill in what your deployment needs and expect to add keys the example file does not show.
For a container run, docker-compose.yml defines a backend service on port 8000 and a frontend service on port 5174, with the frontend pointed at the API through VITE_API_URL=http://localhost:8000. Reports are written to a ./reports volume. Once both services are up, submit a request to POST /research with a company name, take the returned job_id, and poll GET /research/{job_id}/report until the report is complete. PDF export is a separate call to POST /generate-pdf.
Where the pipeline breaks: thresholds, missing sources and API dependency
The relevance threshold is the most consequential failure mode. Documents scoring below 0.4 are dropped before any model reads them. For a private company, a regional subsidiary, or a firm with little English-language coverage, that filter can remove most of the input and leave the analyzers writing around a thin corpus. The README does not describe a fallback, a warning, or a way to see what was discarded. You should check the report against the source list rather than trusting that silence means nothing was dropped.
The three-vendor dependency is a second constraint. Tavily, Gemini and OpenAI are all required for a single report. Any one of them rate-limiting, changing a model name, or failing mid-run affects the job, and the polling model means the client learns about failure only when it asks for the report. There is no described retry policy or partial-result endpoint.
The model split also creates an audit gap. Gemini writes the briefings and GPT-5.1 rewrites and formats them. A figure that Gemini summarized from a source can be rephrased by a second model during editing, and the README does not describe any check that the editor preserves numbers exactly. If a wrong figure matters to you, the editor stage is where you would need to intervene.
Finally, this is the wrong tool for quantitative work. There is no schema, no unit handling, and no arithmetic layer described. FinancialAnalyst gathers metrics; it does not compute ratios or reconcile them against filings. A spreadsheet or a market-data API is the correct instrument for that job, and this tool is the wrong one.
How it differs from n8n-style research workflows
People search for this alongside n8n company research agents, and the difference is structural. An n8n workflow is a general automation canvas: you place HTTP request nodes, a search node, an LLM node, and you own the branching, retries and error handling yourself. company-research-agent ships the graph already assembled, with named nodes, a fixed order, and a specific division of labour between two models.
That means less flexibility and less to build. In n8n you can swap the search provider by editing one node. Here, Tavily is baked into the curation design: relevance scoring comes from Tavily's search, and the 0.4 threshold is a Tavily score, so replacing the provider means rewriting the curator logic in curator.py. The trade is that you get a working pipeline, a React UI, a FastAPI backend with a job model, and PDF generation without assembling them.
The other difference is persistence and state. n8n keeps execution history in its own database. Here, MongoDB persistence is optional and off unless you set MONGODB_URI, which the README marks as optional. Without it, reports live in the reports directory and whatever the backend holds in memory.
Maintenance, releases and what the Apache-2.0 licence means here
The repository is not archived, and the last push was on 2026-09-08. Releases are sparse but real: v2.1.0 on 2026-07-04, 2.0.1 on 2025-12-17, and v2.0.0 on 2025-11-18. The gap between 2.0.0 and 2.0.1 was about a month, and the gap from 2.0.1 to v2.1.0 was roughly six and a half months. Plan for occasional version jumps rather than a steady release cadence, and read the release notes before upgrading because the model names in the pipeline are version-specific.
The dependency surface is the upgrade cost. requirements.txt pins fastapi, langchain, langchain-openai, langchain-google-genai, langchain-community, tavily-python, pymongo, reportlab, uvicorn and python-dotenv to exact versions. The LangChain family moves quickly, and langchain-google-genai and langchain-openai both track vendor SDK changes. When Gemini or OpenAI retires a model identifier, the pinned langchain packages are what you update first. The Dockerfile builds on python:3.11-slim and node:20-slim, so Node 20 and Python 3.11 are the tested baseline.
On licensing: the project is Apache-2.0, which permits commercial use and modification and includes an explicit patent grant. It does not cover the services the pipeline calls. Your Tavily, Google and OpenAI usage is governed by those vendors' terms, and report content generated from their models may carry separate conditions. That is a question for your own counsel, not something the repository answers.
Editorial conclusion
Adopt it if you want a self-hosted, Apache-2.0 report generator and already hold Tavily, Gemini and OpenAI keys, or if you want to read a working LangGraph pipeline with separate research and editing stages. Do not adopt it if you need one vendor, offline operation, or auditable financial figures, because the output is model-written prose over search results. Before committing, verify the MongoDB persistence path in backend/, confirm which Google Maps endpoints the code calls, and check what .env.example omits against the keys the backend actually reads.
Frequently asked questions
What API keys does company-research-agent need to run?
The .env.example file lists TAVILY_API_KEY, OPENAI_API_KEY and GEMINI_API_KEY. The setup section also lists a Google Maps API key as required and a MongoDB URI as optional persistence.
Which AI models does company-research-agent use?
Gemini 2.5 Flash handles the Briefing node, where the README says it summarizes large volumes of context. GPT-5.1 handles the Editor node for final compilation, deduplication and markdown formatting.
How do I submit a research request to company-research-agent?
Send a request to POST /research and keep the returned job_id. Then poll GET /research/{job_id}/report until the report is ready, since research runs asynchronously in the background.
Can I run company-research-agent with Docker?
Yes. The repository includes a docker-compose.yml with a backend service on port 8000 and a frontend service on port 5174. The frontend reads VITE_API_URL, set to http://localhost:8000 in the compose file.
What is the relevance threshold in company-research-agent?
The Curator node drops documents scoring below a default threshold of 0.4, using relevance scores from Tavily's search. Surviving documents are cleaned, deduplicated by URL, and sorted by score.
Community notes