refactor: update agent documentation to streamline architecture and implementation details

This commit is contained in:
2026-06-17 19:30:41 +08:00
parent 826e7f1547
commit 51cd44572f
2 changed files with 28 additions and 145 deletions
+28 -109
View File
@@ -1,117 +1,36 @@
# Agent Alpha — AI Agent Instructions
# Agent Implementation & Architecture
## Project Overview
## Overview
This document outlines the architecture and implementation requirements for AI agents within the Agent Alpha platform. All agent logic must strictly adhere to the **Repository + Service** pattern defined in `/docs/architecture.md`.
**Agent Alpha** is an agentic AI backend (FastAPI + pydantic-ai) with a React + Vite + Tailwind frontend. Users chat with an AI agent powered by a llama.cpp server (OpenAI-compatible endpoint).
## Agent Structure
Agents are built using the `pydantic-ai` framework. Every agent must be modularized as follows:
```
agent_alpha/
├── backend/ # FastAPI application
│ ├── app.py # AppBuilder factory (DI, lifespan, CORS)
│ ├── main.py # Uvicorn entry point
│ ├── core/
│ │ ├── agent.py # AgentService (lazy init, capabilities)
│ │ ├── config.py # pydantic-settings from .env
│ │ ├── database.py# SQLAlchemy async engine + Valkey client + migrations; session created_at tracking
│ │ ├── dependencies.py # FastAPI DI providers
│ │ └── models.py # SQLAlchemy ORM models (User)
│ └── routes/
│ ├── admin.py # GET /api/admin/* (admin dashboard — stats, users, sessions)
│ ├── auth.py # POST /api/auth/{login,register,logout}, GET /api/auth/me
│ ├── chat.py # POST /api/chat, GET /api/chat/{history,sessions}
│ ├── health.py # GET /api/health
│ └── users.py # CRUD /api/users
├── frontend/ # React + Vite SPA
│ ├── src/
│ │ ├── Admin.tsx # Admin dashboard (overview, users, sessions tabs)
│ │ ├── App.tsx # Auth + Chat UI + admin routing
│ │ └── api.ts # Fetch client (chat, auth, users, admin)
│ └── nginx.conf # Production SPA + API proxy
├── skills/ # pydantic-ai skill definitions
└── docker-compose.yml # Full stack orchestration (docker compose / podman compose)
```
### 1. Core Agent (`backend/core/`)
The core module should only handle high-level agent lifecycle and basic configuration. It is a "Thin Service" that orchestrates the interaction between the user request, the dependencies, and the LLM.
## Tech Stack
### 2. Factory Layer (`backend/services/agent_factory.py`)
Complex logic for initializing agents—including model provider setup, Logfire integration, capability registration (`CodeMode`, `ToolSearch`, `MCP`, `WebSearch`, guardrails), subagent setup, skills discovery, and RAG tool injection—resides in the `build_agent()` factory function.
| Layer | Technology |
|-------|-----------|
| **Backend** | Python 3.12+, FastAPI, Uvicorn |
| **AI** | pydantic-ai-slim, pydantic-ai-harness, pydantic-ai-shields |
| **Database** | PostgreSQL 16 (asyncpg + SQLAlchemy async) |
| **Cache** | Valkey 8 (Redis-compatible, via `redis[hiredis]`) |
| **Frontend** | React 18, TypeScript 5.6, Vite 6, Tailwind CSS 3.4 |
| **Infra** | Docker Compose / Podman Compose (backend, frontend/nginx, postgres, valkey) |
| **Pkg Mgr** | `uv` (Python), `bun` (frontend) |
### 3. Service Layer (`backend/services/`)
Business logic related to agent capabilities must be moved to dedicated services:
- **Agent Factory** (`agent_factory.py`): `build_agent()` wires model, capabilities, subagents, skills, and RAG tools into a configured `pydantic-ai` agent.
- **RAG Service** (`rag_service.py`): Constructs retrieval tools for vector search (by document, by collection) and registers them as agent tools.
- **Chat Service** (`chat_service.py`): Manages conversation history, session metadata, and title generation via Valkey.
- **Auth Service** (`auth_service.py`): Handles user registration, password hashing, login, and token lifecycle.
## Build & Run Commands
### 4. Repository Layer (`backend/repositories/`)
All direct interactions with data sources (SQLAlchemy models, Milvus vector store, local filesystems) must be abstracted into repositories.
- Repositories are responsible for CRUD operations and state persistence.
- Repositories use `db.flush()` to ensure data integrity without premature commits in transactional blocks.
- **MemoryRepository** (`memory_repository.py`): Encapsulates agent memory filesystem persistence via `LocalBackend`; provides both the memory directory path and the backend instance for agent `RunContext`.
```bash
make install # uv sync — install Python deps
make run # Start backend on :8000 (reload)
## Tooling & Skills
- **Tools**: Must be decorated with `@agent.tool`. Descriptions must be highly descriptive for LLM comprehension.
- **Skills**: Modular capabilities stored in `/skills/`. These are automatically discovered and registered by `create_deep_agent` when `include_skills=True` and `skill_directories=["./skills"]` are set in the factory.
- **Dependencies**: Use FastAPI's Dependency Injection system to provide Repositories and Services to Agent logic via `RunContext`.
make frontend-install # bun install
make frontend-dev # Start Vite on :5173
make compose-up # Start all containers (detached; auto-detects podman or docker)
make compose-rebuild # Rebuild images & restart
make compose-logs # Follow logs
make compose-down # Stop everything
```
## Coding Conventions
### Python
- **`from __future__ import annotations`** at the top of every module.
- **Type hints** required on all function signatures, including async return types.
- **Docstrings**: module-level Google-style with `::` usage examples.
- **Imports**: stdlib → third-party → local, grouped with blank lines.
- **Async-first**: all I/O uses `async`/`await` (FastAPI routes, DB sessions, Valkey).
- **Settings**: use `pydantic-settings` (`Settings` class in `config.py`); field names are snake_case, env vars are UPPER_SNAKE_CASE.
- **Error handling**: `HTTPException(status_code=500, detail=str(exc))` in routes; `try/except` with graceful fallback for optional components (e.g., Logfire).
- **DI pattern**: FastAPI `Depends()` with providers in `dependencies.py`. Provider functions use module-level singletons.
- **Factories**: use `AppBuilder` class for app construction, accept optional `Settings` for testability.
### TypeScript / React
- **Functional components** only (hooks, no classes).
- **Interfaces** at file top, exported when reused.
- **Tailwind utility classes** inline; no CSS modules or styled-components.
- **API client** isolated in `api.ts` — exports for chat (`sendMessage`, `getHistory`), auth (`login`, `register`, `getMe`, `logout`), users (`listUsers`, `createUser`, `getUserSessions`), and admin (`getAdminStats`, `adminListUsers`, `adminUpdateUser`, `adminListSessions`, `adminDeleteSession`). Auth token managed via `localStorage` + `Authorization: Bearer` header helpers.
- **Session metadata**: Session creation timestamps (`chat:{session_id}:created_at`) are stored in Valkey via `SETNX` on the first message. The `GET /api/users/{user_id}/sessions` endpoint returns `session_id`, `title`, `created_at` (ISO-8601), and `message_count`, sorted newest-first. The frontend displays relative time via `formatSessionTime()` in the sessions sidebar.
## Key Architecture Decisions
### Dependency Injection
`dependencies.py` provides `get_settings()`, `get_agent_service()`, and `get_db_session()` as FastAPI `Depends()` callables. `AgentService` is lazily initialized (not built at import time). `AppBuilder` accepts optional `Settings` for test overrides.
### Capabilities Stack
Agent capabilities are assembled in `AgentService._build_capabilities()` — a list that includes code execution, web search, MCP, sub-agents, cost tracking, input/tool guards, secret redaction, and stuck-loop detection.
### Lifecycle
FastAPI's `lifespan` context manager handles startup (initialize agent, DB engine, Valkey) and shutdown (close agent, DB pool, Valkey connection). See `AppBuilder._lifespan()` in `app.py`.
### Configuration
Environment variables loaded from `.env` via `pydantic-settings` (`backend/core/config.py`). Key vars: `LLM_BASE_URL`, `LLM_MODEL`, `LLM_API_KEY`, `LOGFIRE_TOKEN`, `DATABASE_URL`, `VALKEY_URL`.
## Common Pitfalls
1. **Container DNS caching**: nginx caches DNS at startup. Podman does not use Docker's `127.0.0.11` resolver, so the `resolver` + variable trick doesn't work. If the backend restarts, also restart the frontend container (`podman compose restart frontend` or `docker compose restart frontend`).
2. **Slow LLM responses**: The LLM may take minutes to respond. Nginx `proxy_read_timeout` is set to 600s. Backend timeouts should match.
3. **Logfire is optional**: `logfire.configure()` is wrapped in `try/except` — omit `LOGFIRE_TOKEN` to disable.
4. **API key for local LLMs**: Set `LLM_API_KEY=no-key-required` (or leave empty) for llama.cpp / local endpoints; the OpenAI client requires a non-None value.
5. **uv vs pip**: Always use `uv sync` / `uv add`, never `pip install`. The lock file is `uv.lock`.
6. **bun for frontend**: Use `bun install` / `bun run dev` for frontend, not `npm`.
7. **Container orchestration**: Backend depends on postgres + valkey being healthy. Use `depends_on` with `condition: service_healthy`. Run with `docker compose up -d` or `podman compose up -d`. The Makefile auto-detects the available runtime.
8. **Schema migrations**: `init_db()` in `database.py` runs `Base.metadata.create_all` followed by `ALTER TABLE ... ADD COLUMN IF NOT EXISTS` for new columns. Existing tables are never rebuilt — new columns are added in-place.
9. **bcrypt on container restart**: `bcrypt` is a native dependency. If the container fails to start with an import error, ensure `bcrypt` is in `pyproject.toml` and `uv sync` was run during the container build.
## Key Conventions
- `db.flush()` in repositories, not `commit()`
## More Info
- `docs/architecture.md` - Architecture details
- `docs/patterns.md` - Code patterns
- `docs/adding_features.md` - How to add features
## Patterns
- **Async First**: All agent operations must be asynchronous.
- **Thin Routes**: FastAPI endpoints must only validate input schemas and call the appropriate Service.
- **Dependency Injection**: Never instantiate repositories or services directly inside an agent tool; always use the provided context dependencies.
-36
View File
@@ -1,36 +0,0 @@
# Agent Implementation & Architecture
## Overview
This document outlines the architecture and implementation requirements for AI agents within the Agent Alpha platform. All agent logic must strictly adhere to the **Repository + Service** pattern defined in `/docs/architecture.md`.
## Agent Structure
Agents are built using the `pydantic-ai` framework. Every agent must be modularized as follows:
### 1. Core Agent (`backend/core/`)
The core module should only handle high-level agent lifecycle and basic configuration. It is a "Thin Service" that orchestrates the interaction between the user request, the dependencies, and the LLM.
### 2. Factory Layer (`backend/services/agent_factory.py`)
Complex logic for initializing agents—including model provider setup, Logfire integration, capability registration (`CodeMode`, `ToolSearch`, `MCP`, `WebSearch`, guardrails), subagent setup, skills discovery, and RAG tool injection—resides in the `build_agent()` factory function.
### 3. Service Layer (`backend/services/`)
Business logic related to agent capabilities must be moved to dedicated services:
- **Agent Factory** (`agent_factory.py`): `build_agent()` wires model, capabilities, subagents, skills, and RAG tools into a configured `pydantic-ai` agent.
- **RAG Service** (`rag_service.py`): Constructs retrieval tools for vector search (by document, by collection) and registers them as agent tools.
- **Chat Service** (`chat_service.py`): Manages conversation history, session metadata, and title generation via Valkey.
- **Auth Service** (`auth_service.py`): Handles user registration, password hashing, login, and token lifecycle.
### 4. Repository Layer (`backend/repositories/`)
All direct interactions with data sources (SQLAlchemy models, Milvus vector store, local filesystems) must be abstracted into repositories.
- Repositories are responsible for CRUD operations and state persistence.
- Repositories use `db.flush()` to ensure data integrity without premature commits in transactional blocks.
- **MemoryRepository** (`memory_repository.py`): Encapsulates agent memory filesystem persistence via `LocalBackend`; provides both the memory directory path and the backend instance for agent `RunContext`.
## Tooling & Skills
- **Tools**: Must be decorated with `@agent.tool`. Descriptions must be highly descriptive for LLM comprehension.
- **Skills**: Modular capabilities stored in `/skills/`. These are automatically discovered and registered by `create_deep_agent` when `include_skills=True` and `skill_directories=["./skills"]` are set in the factory.
- **Dependencies**: Use FastAPI's Dependency Injection system to provide Repositories and Services to Agent logic via `RunContext`.
## Patterns
- **Async First**: All agent operations must be asynchronous.
- **Thin Routes**: FastAPI endpoints must only validate input schemas and call the appropriate Service.
- **Dependency Injection**: Never instantiate repositories or services directly inside an agent tool; always use the provided context dependencies.