Skip to content

Commit 09971ff

Browse files
committed
init
1 parent abd4403 commit 09971ff

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+9638
-0
lines changed

.gitignore

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
# Node / Frontend
2+
node_modules/
3+
frontend/dist/
4+
frontend/.vite/
5+
frontend/coverage/
6+
.DS_Store
7+
*.local
8+
9+
# Logs
10+
logs
11+
*.log
12+
npm-debug.log*
13+
yarn-debug.log*
14+
yarn-error.log*
15+
pnpm-debug.log*
16+
lerna-debug.log*
17+
18+
# OS generated files
19+
.DS_Store
20+
.DS_Store?
21+
._*
22+
.Spotlight-V100
23+
.Trashes
24+
ehthumbs.db
25+
Thumbs.db
26+
27+
# IDE files
28+
.idea/
29+
.vscode/
30+
*.suo
31+
*.ntvs*
32+
*.njsproj
33+
*.sln
34+
*.sw?
35+
36+
# Optional backend venv (if created in root)
37+
#.venv/
38+
39+
# Byte-compiled / optimized / DLL files
40+
__pycache__/
41+
*.py[cod]
42+
*$py.class
43+
uv.lock
44+
45+
# C extensions
46+
*.so
47+
48+
# Distribution / packaging
49+
.Python
50+
build/
51+
develop-eggs/
52+
dist/
53+
downloads/
54+
eggs/
55+
.eggs/
56+
lib64/
57+
parts/
58+
sdist/
59+
var/
60+
wheels/
61+
share/python-wheels/
62+
*.egg-info/
63+
.installed.cfg
64+
*.egg
65+
MANIFEST
66+
67+
# PyInstaller
68+
# Usually these files are written by a python script from a template
69+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
70+
*.manifest
71+
*.spec
72+
73+
# Installer logs
74+
pip-log.txt
75+
pip-delete-this-directory.txt
76+
77+
# Unit test / coverage reports
78+
htmlcov/
79+
.tox/
80+
.nox/
81+
.coverage
82+
.coverage.*
83+
.cache
84+
nosetests.xml
85+
coverage.xml
86+
*.cover
87+
*.py,cover
88+
.hypothesis/
89+
.pytest_cache/
90+
cover/
91+
92+
# Translations
93+
*.mo
94+
*.pot
95+
96+
# Django stuff:
97+
*.log
98+
local_settings.py
99+
db.sqlite3
100+
db.sqlite3-journal
101+
102+
# Flask stuff:
103+
instance/
104+
.webassets-cache
105+
106+
# Scrapy stuff:
107+
.scrapy
108+
109+
# Sphinx documentation
110+
docs/_build/
111+
112+
# PyBuilder
113+
.pybuilder/
114+
target/
115+
116+
# Jupyter Notebook
117+
.ipynb_checkpoints
118+
119+
# IPython
120+
profile_default/
121+
ipython_config.py
122+
123+
# pyenv
124+
# For a library or package, you might want to ignore these files since the code is
125+
# intended to run in multiple environments; otherwise, check them in:
126+
# .python-version
127+
128+
# pipenv
129+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
130+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
131+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
132+
# install all needed dependencies.
133+
#Pipfile.lock
134+
135+
# poetry
136+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
137+
# This is especially recommended for binary packages to ensure reproducibility, and is more
138+
# commonly ignored for libraries.
139+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
140+
#poetry.lock
141+
142+
# pdm
143+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
144+
#pdm.lock
145+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
146+
# in version control.
147+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
148+
.pdm.toml
149+
.pdm-python
150+
.pdm-build/
151+
152+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
153+
__pypackages__/
154+
155+
# Celery stuff
156+
celerybeat-schedule
157+
celerybeat.pid
158+
159+
# SageMath parsed files
160+
*.sage.py
161+
162+
# Environments
163+
.env
164+
.venv
165+
env/
166+
venv/
167+
ENV/
168+
env.bak/
169+
venv.bak/
170+
171+
# Spyder project settings
172+
.spyderproject
173+
.spyproject
174+
175+
# Rope project settings
176+
.ropeproject
177+
178+
# mkdocs documentation
179+
/site
180+
181+
# mypy
182+
.mypy_cache/
183+
.dmypy.json
184+
dmypy.json
185+
186+
# Pyre type checker
187+
.pyre/
188+
189+
# pytype static type analyzer
190+
.pytype/
191+
192+
# Cython debug symbols
193+
cython_debug/
194+
195+
# PyCharm
196+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
197+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
198+
# and can be added to the global gitignore or merged into this file. For a more nuclear
199+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
200+
#.idea/
201+
202+
backend/.langgraph_api

Dockerfile

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Stage 1: Build React Frontend
2+
FROM node:20-alpine AS frontend-builder
3+
4+
# Set working directory for frontend
5+
WORKDIR /app/frontend
6+
7+
# Copy frontend package files and install dependencies
8+
COPY frontend/package.json ./
9+
COPY frontend/package-lock.json ./
10+
# If you use yarn or pnpm, adjust accordingly (e.g., copy yarn.lock or pnpm-lock.yaml and use yarn install or pnpm install)
11+
RUN npm install
12+
13+
# Copy the rest of the frontend source code
14+
COPY frontend/ ./
15+
16+
# Build the frontend
17+
RUN npm run build
18+
19+
# Stage 2: Python Backend
20+
FROM docker.io/langchain/langgraph-api:3.11
21+
22+
# -- Copy built frontend from builder stage --
23+
# The app.py expects the frontend build to be at ../frontend/dist relative to its own location.
24+
# If app.py is at /deps/backend/src/agent/app.py, then ../frontend/dist resolves to /deps/frontend/dist.
25+
COPY --from=frontend-builder /app/frontend/dist /deps/frontend/dist
26+
# -- End of copying built frontend --
27+
28+
# -- Adding local package . --
29+
ADD backend/ /deps/backend
30+
# -- End of local package . --
31+
32+
# -- Installing all local dependencies --
33+
RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/backend
34+
# -- End of local dependencies install --
35+
ENV LANGGRAPH_HTTP='{"app": "/deps/backend/src/agent/app.py:app"}'
36+
ENV LANGSERVE_GRAPHS='{"agent": "/deps/backend/src/agent/graph.py:graph"}'
37+
38+
# -- Ensure user deps didn't inadvertently overwrite langgraph-api
39+
RUN mkdir -p /api/langgraph_api /api/langgraph_runtime /api/langgraph_license && touch /api/langgraph_api/__init__.py /api/langgraph_runtime/__init__.py /api/langgraph_license/__init__.py
40+
RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir --no-deps -e /api
41+
# -- End of ensuring user deps didn't inadvertently overwrite langgraph-api --
42+
# -- Removing pip from the final image ~<:===~~~ --
43+
RUN pip uninstall -y pip setuptools wheel && rm -rf /usr/local/lib/python*/site-packages/pip* /usr/local/lib/python*/site-packages/setuptools* /usr/local/lib/python*/site-packages/wheel* && find /usr/local/bin -name "pip*" -delete
44+
# -- End of pip removal --
45+
46+
WORKDIR /deps/backend

Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.PHONY: help dev-frontend dev-backend dev
2+
3+
help:
4+
@echo "Available commands:"
5+
@echo " make dev-frontend - Starts the frontend development server (Vite)"
6+
@echo " make dev-backend - Starts the backend development server (Uvicorn with reload)"
7+
@echo " make dev - Starts both frontend and backend development servers"
8+
9+
dev-frontend:
10+
@echo "Starting frontend development server..."
11+
@cd frontend && npm run dev
12+
13+
dev-backend:
14+
@echo "Starting backend development server..."
15+
@cd backend && langgraph dev
16+
17+
# Run frontend and backend concurrently
18+
dev:
19+
@echo "Starting both frontend and backend development servers..."
20+
@make dev-frontend & make dev-backend

README.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Gemini DeepSearch LangGraph Quickstart
2+
3+
This project demonstrates a fullstack application using a React frontend and a LangGraph-powered backend agent. The agent is designed to perform comprehensive research on a user's query by dynamically generating search terms, querying the web using Google Search, reflecting on the results to identify knowledge gaps, and iteratively refining its search until it can provide a well-supported answer with citations. This application serves as an example of building research-augmented conversational AI using LangGraph and Google's Gemini models.
4+
5+
## Features
6+
7+
- 💬 Fullstack application with a React frontend and LangGraph backend.
8+
- 🧠 Powered by a LangGraph agent for advanced research and conversational AI.
9+
- 🔍 Dynamic search query generation using Google Gemini models.
10+
- 🌐 Integrated web research via Google Search API.
11+
- 🤔 Reflective reasoning to identify knowledge gaps and refine searches.
12+
- 📄 Generates answers with citations from gathered sources.
13+
- 🔄 Hot-reloading for both frontend and backend development during development.
14+
15+
## Project Structure
16+
17+
The project is divided into two main directories:
18+
19+
- `frontend/`: Contains the React application built with Vite.
20+
- `backend/`: Contains the LangGraph/FastAPI application, including the research agent logic.
21+
22+
## Getting Started: Development and Local Testing
23+
24+
Follow these steps to get the application running locally for development and testing.
25+
26+
**1. Prerequisites:**
27+
28+
- Node.js and npm (or yarn/pnpm)
29+
- Python 3.8+
30+
- **`GEMINI_API_KEY`**: The backend agent requires a Google Gemini API key.
31+
1. Navigate to the `backend/` directory.
32+
2. Create a file named `.env` by copying the `backend/.env.example` file.
33+
3. Open the `.env` file and add your Gemini API key: `GEMINI_API_KEY="YOUR_ACTUAL_API_KEY"`
34+
35+
**2. Install Dependencies:**
36+
37+
**Backend:**
38+
39+
```bash
40+
cd backend
41+
pip install .
42+
```
43+
44+
**Frontend:**
45+
46+
```bash
47+
cd frontend
48+
npm install
49+
```
50+
51+
**3. Run Development Servers:**
52+
53+
**Backend & Frontend:**
54+
55+
```bash
56+
make dev
57+
```
58+
This will run the backend and frontend development servers. Open your browser and navigate to the frontend development server URL (e.g., `http://localhost:5173/app`).
59+
60+
_Alternatively, you can run the backend and frontend development servers separately. For the backend, open a terminal in the `backend/` directory and run `langgraph dev`. The backend API will be available at `http://127.0.0.1:2024`. It will also open a browser window to the LangGraph UI. For the frontend, open a terminal in the `frontend/` directory and run `npm run dev`. The frontend will be available at `http://localhost:5173`._
61+
62+
## How the Backend Agent Works (High-Level)
63+
64+
The core of the backend is a LangGraph agent defined in `backend/src/agent/graph.py`. It follows these steps:
65+
66+
![Agent Flow](./deepsearch.png)
67+
68+
1. **Generate Initial Queries:** Based on your input, it generates a set of initial search queries using a Gemini model.
69+
2. **Web Research:** For each query, it uses the Gemini model with the Google Search API to find relevant web pages.
70+
3. **Reflection & Knowledge Gap Analysis:** The agent analyzes the search results to determine if the information is sufficient or if there are knowledge gaps. It uses a Gemini model for this reflection process.
71+
4. **Iterative Refinement:** If gaps are found or the information is insufficient, it generates follow-up queries and repeats the web research and reflection steps (up to a configured maximum number of loops).
72+
5. **Finalize Answer:** Once the research is deemed sufficient, the agent synthesizes the gathered information into a coherent answer, including citations from the web sources, using a Gemini model.
73+
74+
## Deployment
75+
76+
In production, the backend server serves the optimized static frontend build. LangGraph requires a Redis instance and a Postgres database. Redis is used as a pub-sub broker to enable streaming real time output from background runs. Postgres is used to store assistants, threads, runs, persist thread state and long term memory, and to manage the state of the background task queue with 'exactly once' semantics. For more details on how to deploy the backend server, take a look at the [LangGraph Documentation](https://langchain-ai.github.io/langgraph/concepts/deployment_options/). Below is an example of how to build a Docker image that includes the optimized frontend build and the backend server and run it via `docker-compose`.
77+
78+
_Note: For the docker-compose.yml example you need a LangSmith API key, you can get one from [LangSmith](https://smith.langchain.com/settings)._
79+
80+
_Note: If you are not running the docker-compose.yml example or exposing the backend server to the public internet, you update the `apiUrl` in the `frontend/src/App.tsx` file your host. Currently the `apiUrl` is set to `http://localhost:8123` for docker-compose or `http://localhost:2024` for development._
81+
82+
**1. Build the Docker Image:**
83+
84+
Run the following command from the **project root directory**:
85+
```bash
86+
docker build -t deepsearch -f Dockerfile .
87+
```
88+
**2. Run the Production Server:**
89+
90+
```bash
91+
GEMINI_API_KEY=<your_gemini_api_key> LANGSMITH_API_KEY=<your_langsmith_api_key> docker-compose up
92+
```
93+
94+
Open your browser and navigate to `http://localhost:8123/app/` to see the application. The API will be available at `http://localhost:8123`.
95+
96+
## Technologies Used
97+
98+
- [React](https://reactjs.org/) (with [Vite](https://vitejs.dev/)) - For the frontend user interface.
99+
- [Tailwind CSS](https://tailwindcss.com/) - For styling.
100+
- [Shadcn UI](https://ui.shadcn.com/) - For components.
101+
- [LangGraph](https://github.com/langchain-ai/langgraph) - For building the backend research agent.
102+
- [Google Gemini](https://ai.google.dev/models/gemini) - LLM for query generation, reflection, and answer synthesis.
103+
104+
## License
105+
106+
This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file for details.

backend/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# GEMINI_API_KEY=

0 commit comments

Comments
 (0)