Development¶
Guide for engineers contributing to Eagle-RAG. The backend is Python 3.12+ (eagle_rag/); the frontend is Next.js 16 with Bun (frontend/).
Canonical constraints for humans and coding agents: AGENTS.md. Product overview: README.md.
First-time setup¶
git clone https://github.com/fintax-ai/eagle-rag.git
cd eagle-rag
task setup # .env, knowhere/.env, knowhere-net, uv sync, bun install
# Edit .env — VLM_API_KEY, LLM_API_KEY, embedding keys, etc.
task up # Docker full stack (knowhere + eagle-rag dev)
task db:migrate # Alembic against running Postgres
Local hybrid (infra in Docker, code on host):
task knowhere:up
docker compose up -d postgres redis minio milvus etcd
task be:api # terminal 1
task be:worker # terminal 2
task fe:dev # terminal 3
Documentation map¶
| Page | Contents |
|---|---|
| Project structure | Directory layout, module dependency graph |
| Contributing | PR workflow, review checklist, CI gates |
| Coding standards | Python/TS style, docstrings, AGENTS.md rationale |
| Testing | pytest layout, fixtures, unit vs integration |
Operations (Docker, observability, backup): docs/en/ops/.
Toolchain¶
| Tool | Role | Install |
|---|---|---|
| uv | Python deps + venv | curl -LsSf … or brew |
| Bun | Frontend package manager | brew / curl |
| Task | Task runner | brew / go install |
| Docker Compose | Full stack | Docker Desktop / engine |
Backend dev dependencies (uv sync --group dev):
pytest,pytest-asyncioruff,mypy
Quality gates (run before PR)¶
task be:lint # ruff check
task be:format # ruff format
task be:typecheck # mypy eagle_rag
task be:test # pytest
cd frontend && bun run lint && bun run format
All five should pass. See Contributing — PR checklist.
Architecture constraints (summary)¶
From AGENTS.md:
| Topic | Rule |
|---|---|
| Parsers | Knowhere HTTP :5005 via official SDK; PixelRAG in-process library only |
| Removed | No LibreOffice, pixelrag-serve, FAISS, OpenAI, Cohere adapters |
| Models | DeepSeek + Qwen only (LLM, VLM, embeddings, rerank) |
| Multi-tenancy | Propagate kb_name; dedup (sha256, kb_name) |
| DB | SQLModel + Alembic; no DDL in stores |
| API | No auth (intranet); response_model on routers |
| Celery | Three queues; @with_retry + dead letter |
Full rationale: Coding standards — AGENTS.md.
Configuration¶
Single source: eagle_rag/settings.yaml with ${ENV:-default} placeholders, loaded by eagle_rag/config.py.
When adding a setting:
- Add YAML key with env placeholder.
- Extend pydantic model in
config.py. - Document in README / architecture docs if behaviour-facing.
- Never commit secrets in YAML — use
.env.
Database workflow¶
# After changing eagle_rag/db/models/
uv run alembic revision --autogenerate -m "describe change"
task db:migrate
Deploy migrations: task db:migrate in CI/CD or container entrypoint — not at import time in stores.
API development¶
- Schemas:
eagle_rag/api/schemas/ - Routers mounted in
eagle_rag/api/app.py - OpenAPI:
http://localhost:8000/docswhen API running
Streaming endpoints:
POST /query/stream— SSE (session,step,sources,token,done)POST /search/stream— retrieval-only stream
Frontend development¶
Stack: Next.js 16, React 19, HeroUI v3, Tailwind v4, next-intl (zh/en), light theme only.
NEXT_PUBLIC_API_BASE must point at the API origin the browser can reach.
MCP tools¶
Register new tools in:
eagle_rag/api/mcp_server.py—@mcp.tool()handlerTOOL_DEFINITIONSlist (mirrors OpenAPI for/mcp/tools)- Tests under
tests/test_mcp_*.py
Decorate with @with_metrics("tool_name") when exposing via standalone MCP HTTP.
Celery task development¶
Task modules are explicitly included in celery_app.py include=[...].
Pattern:
from eagle_rag.tasks.dead_letter import with_retry
@with_retry(name="eagle_rag.tasks.my_task", queue="knowhere_queue")
def my_task(self, document_id: str, kb_name: str) -> None:
...
Dispatch with trace propagation:
from eagle_rag.telemetry import send_task_with_trace
send_task_with_trace("eagle_rag.tasks.my_task", queue="knowhere_queue", kwargs={...})
After editing task code in Docker dev, restart workers (no Celery autoreload):
Telemetry in new code¶
from eagle_rag.telemetry import get_logger, get_ai_logger, trace_span, bind_context
logger = get_logger(__name__)
ai_logger = get_ai_logger(__name__)
with trace_span("my_operation"):
ai_logger.info("step_done", key=value)
See Observability.
Docs site¶
Edit docs/en/ and docs/zh/; navigation in mkdocs.yml. Do not create markdown docs unless requested (AGENTS.md).
Architecture change checklist¶
When behaviour changes, sync:
Getting help¶
| Question | Where |
|---|---|
| How does ingest route? | eagle_rag/ingest/router.py, docs/backend |
| Milvus schema | eagle_rag/index/milvus_*_store.py |
| Ops / probes | docs/en/ops/ |
| Agent rules | AGENTS.md |