Deep Research 是一个面向研究型问答的全栈应用:前端使用 Next.js,后端使用 FastAPI,研究流程由 LangGraph / LangChain 编排,支持 OpenAI 兼容模型、Supabase 存储和可选 Langfuse 观测。
Deep Research 旨在把一次复杂研究拆解成可追踪、可复用、可展示的完整流程。用户输入一个研究问题后,系统会围绕问题进行搜索、信息筛选、分析整理和报告生成,并在前端以对话进度、来源列表、推理状态和最终报告的形式呈现结果。
项目的核心目标不是简单返回一段回答,而是提供一个更接近“研究助手”的工作台:前端负责承载清晰的交互体验和报告阅读体验,后端负责组织模型调用、搜索工具、状态流和持久化数据。它可以用于人物背景调查、主题研究、资料汇总、竞品分析、内容选题调研等需要多步骤信息处理的场景。
当前项目已经包含本地开发、Docker 热更新、生产构建、服务器部署和 GitHub Actions 自动部署流程,适合作为一个可继续扩展的 AI research 产品原型。
生产环境当前部署在:
https://hasmodream.com/ds
健康检查:
https://hasmodream.com/ds/health
- 研究问题输入、执行和结果展示
- LangGraph 驱动的搜索、分析、报告生成流程
- 支持本地 JSON 存储或 Supabase 持久化
- 支持 Google 登录和用户隔离
- 支持 Langfuse trace,用于观察研究流程质量
- Docker Compose 部署
- GitHub Actions 自动部署到服务器
前端:
- Next.js 16 App Router
- React 19
- TypeScript
- Tailwind CSS
- Radix UI / shadcn 风格组件
- Zustand
- Supabase JS
后端:
- Python 3.11+
- FastAPI
- Uvicorn
- LangGraph
- LangChain
- OpenAI / OpenAI-compatible API
- Supabase Python SDK
部署:
- Docker / Docker Compose
- Nginx 反向代理
- GitHub Actions
deep-research/
├── api/ # FastAPI 后端
│ ├── main.py # 应用入口
│ ├── agents/ # LangGraph agent
│ ├── core/ # 配置
│ ├── database/ # Supabase SQL schema
│ ├── models/ # Pydantic model
│ ├── routers/ # API routes
│ ├── services/ # 业务服务
│ └── tests/ # 后端测试
├── web/ # Next.js 前端
│ ├── app/ # App Router pages
│ ├── components/ # UI 和业务组件
│ └── lib/ # API client、auth、状态和研究逻辑
├── docs/
│ └── deployment/ # 部署文档
├── scripts/
│ └── deploy-production.sh # 生产部署脚本
├── docker-compose.yml
└── .github/workflows/deploy.yml
- Node.js 18+
- pnpm 10+
- Python 3.11+
- Docker,可选
- Supabase 项目,可选,使用
RESEARCH_STORAGE_BACKEND=supabase时需要 - OpenAI 或兼容接口 key
cd api
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env编辑 api/.env,至少配置:
OPENAI_API_KEY=
OPENAI_BASE_URL=
FRONTEND_URL=http://localhost:3000
RESEARCH_STORAGE_BACKEND=json如果使用 Supabase 存储,还需要:
SUPABASE_URL=
SUPABASE_KEY=
SUPABASE_SERVICE_KEY=
RESEARCH_STORAGE_BACKEND=supabase如果要把 LangGraph 线程 checkpoint 持久化到 Supabase Postgres,再配置:
LANGGRAPH_CHECKPOINT_BACKEND=postgres
LANGGRAPH_CHECKPOINT_POSTGRES_URL=postgresql://.../postgres?sslmode=require
LANGGRAPH_CHECKPOINT_SETUP=true这里需要 Supabase 的 Postgres 直连或 Session Pooler 连接串,不是 SUPABASE_URL REST API。不要优先使用 Transaction Pooler,除非确认底层驱动已关闭 prepared statements。
研究任务默认使用进程内 memory 队列。Docker Compose 默认启用 Redis Streams;本地直接运行后端时,如果要让多个 API worker 共享研究任务,也可以切到 Redis:
RESEARCH_QUEUE_BACKEND=redis
REDIS_URL=redis://redis:6379/0
RESEARCH_QUEUE_STREAM=deep-research:jobs
RESEARCH_QUEUE_GROUP=deep-research-workers项目内置了一个 news-trading agent skill,可以通过 twitter-cli 抓取配置账号和搜索词,再让 ReAct agent 分析潜在买入候选、观察列表和风险。
先安装并认证 twitter-cli:
uv tool install twitter-cli
twitter status --yamltwitter-cli 默认从本机浏览器提取 X/Twitter cookies;如果失败,先在 Chrome/Arc/Firefox/Brave 登录 x.com 后重试。
创建配置:
cp api/config/news_trading.example.json api/config/news_trading.json编辑 api/config/news_trading.json:
{
"tracking_accounts": [
{"handle": "elonmusk", "label": "Tesla / X", "max_posts": 5, "enabled": true}
],
"search_queries": [
{"query": "NVDA earnings guidance", "label": "Nvidia", "tab": "Latest", "max_posts": 10, "enabled": true}
],
"analysis": {
"assets": ["TSLA", "NVDA", "BTC"],
"default_horizon": "intraday",
"min_confidence": 0.65
}
}可选环境变量:
NEWS_TRADING_CONFIG_PATH=config/news_trading.json公网部署先使用服务器环境变量,不在网页里管理 X/Twitter 登录态:
TWITTER_AUTH_TOKEN=
TWITTER_CT0=
TWITTER_PROXY=建议使用专门的 X/Twitter 小号,只用于读取公开信息。twitter-cli 子进程运行时只会收到最小必要环境变量,包括 PATH、HOME、locale 和 TWITTER_* 相关变量,不会继承 OPENAI_API_KEY、SUPABASE_SERVICE_KEY 等后端密钥。
然后在前端或 API 里问:
使用 news-trading 分析我配置的账号和搜索词,现在有什么可以买?同时搜索 "Bitcoin ETF inflows"。
第一版只生成交易假设、买入候选、观察列表和风险说明,不会自动下单。实盘前需要另接 broker/exchange API、仓位限制、止损、冷却时间和人工确认。
启动后端:
cd api
source venv/bin/activate
uvicorn main:app --reload --port 8000访问:
http://localhost:8000/health
http://localhost:8000/docs
cd web
pnpm install
cp .env.example .env.local编辑 web/.env.local:
NEXT_PUBLIC_API_URL=http://localhost:8000
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=
NEXT_PUBLIC_AUTH_CALLBACK_PATH=/auth/callback启动前端:
cd web
pnpm dev访问:
http://localhost:3000
Supabase schema 在:
api/database/schema.sql
初始化步骤:
- 创建 Supabase 项目。
- 在 SQL Editor 执行
api/database/schema.sql。 - 启用
pgvector扩展。 - 如果要启用 Google 登录,在 Supabase Authentication Providers 中开启 Google。
- Google OAuth 回调 URL 使用 Supabase 提供的
/auth/v1/callback。 - Supabase redirect URL 至少加入:
http://localhost:3000/auth/callback
https://hasmodream.com/ds/auth/callback
详细说明见:
api/database/README.md
常用接口:
GET /health
POST /api/research/
POST /api/research/execute
GET /api/research/documents
POST /api/research/documents
DELETE /api/research/documents/{id}
添加文档示例:
curl -X POST http://localhost:8000/api/research/documents \
-H "Content-Type: application/json" \
-d '{
"content": "文档正文",
"metadata": {"source": "example"}
}'项目保留两种 Docker 模式:
- 生产模式:使用
docker-compose.yml,构建 Next standalone 和 FastAPI runtime,和线上部署一致。 - 热更新模式:叠加
docker-compose.dev.yml,仍使用同一套服务、端口、.env和 Dockerfile,只把命令切换成pnpm dev与uvicorn --reload。
首次启动:
cp .env.deploy.example .env
docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build后续启动:
docker compose -f docker-compose.yml -f docker-compose.dev.yml up本地默认端口:
Web: http://localhost:3000
API: http://localhost:8000
热更新模式会挂载:
./web -> /app
./api -> /app
前端依赖和 .next 缓存在 Docker volume 中,不会写进宿主机项目目录:
web-node-modules
web-next-cache
web-pnpm-store
停止热更新环境:
docker compose -f docker-compose.yml -f docker-compose.dev.yml down如果要清掉前端依赖缓存:
docker compose -f docker-compose.yml -f docker-compose.dev.yml down -v本地生产模式用于验证“构建后”的效果,不提供热更新:
cp .env.deploy.example .env
docker compose up --build -d
docker compose ps修改代码后需要重新构建:
docker compose build web api
docker compose up -d生产服务器当前布局:
/ds 前端源码、docker-compose.yml、部署 .env
/api 后端源码、api/.env
生产环境关键变量:
API_PORT=8000
WEB_PORT=3002
API_BUILD_CONTEXT=/api
WEB_BUILD_CONTEXT=/ds
API_ENV_FILE=/api/.env
NEXT_PUBLIC_API_URL=https://hasmodream.com/ds
FRONTEND_URL=https://hasmodream.com
NEXT_PUBLIC_AUTH_CALLBACK_PATH=/ds/auth/callback
NEXT_PUBLIC_BASE_PATH=/dsGitHub Actions workflow:
.github/workflows/deploy.yml
触发方式:
- push 到
main - GitHub Actions 页面手动
workflow_dispatch
部署脚本:
scripts/deploy-production.sh
GitHub Secrets 需要配置在 Production environment 下:
DEPLOY_HOST=103.112.1.107
DEPLOY_USER=root
DEPLOY_PORT=22
GOMAMI_SSH_PRIVATE_KEY=<gomami 部署私钥>
TWITTER_AUTH_TOKEN=<X/Twitter auth_token>
TWITTER_CT0=<X/Twitter ct0>
TWITTER_PROXY=<可选,仅服务器无法直连 X 时需要>
部署脚本会:
- 同步
web/到服务器/ds。 - 同步
api/到服务器/api。 - 保留服务器上的
/ds/.env,并在/api/.env中补齐NEWS_TRADING_CONFIG_PATH和可选TWITTER_*secrets。 - 如果
/api/config/news_trading.json不存在,则从 example 初始化一份。 - 执行
docker-compose build api web。 - 执行
docker-compose up -d api web。 - 配置 Nginx
/ds反向代理。 - 检查
https://hasmodream.com/ds和https://hasmodream.com/ds/health。
如果 X/Twitter cookie 经常轮换,不需要为了更新 token 而 push。先更新本地 api/.env 中的 TWITTER_AUTH_TOKEN 和 TWITTER_CT0,然后运行:
scripts/update-production-twitter-env.sh脚本会只读取本地 api/.env 中的 TWITTER_* 项,更新服务器 /api/.env,并强制重新创建 api 容器,让 Docker Compose 重新读取 env_file。
更多细节见:
docs/deployment/docker-local.md
docs/deployment/github-actions.md
docs/deployment/docker.md
查看生产容器:
ssh summi-netcup
cd /ds
sudo docker-compose ps查看日志:
cd /ds
sudo docker-compose logs -f --tail=100 api web手动重启:
cd /ds
sudo docker-compose restart本地运行前端 lint:
cd web
pnpm lint运行前端 Node 测试示例:
node --test web/lib/auth/callback-redirect.test.mts- 不要提交
.env、私钥、OpenAI key、Supabase service key。 NEXT_PUBLIC_*会进入浏览器 bundle,只能放公开值。- 生产前端挂在
/ds下,Next.js 通过NEXT_PUBLIC_BASE_PATH=/ds构建。 - 前端 OAuth 回调路径是
/ds/auth/callback。 - 如果修改
NEXT_PUBLIC_*,需要重新 build 前端镜像。
MIT