Skip to content

yxtay/agentic-recommenders

Repository files navigation

agentic-recommenders

A simplified single-agent implementation inspired by ARAG: Agentic Retrieval Augmented Generation for Personalized Recommendation, applied to the MovieLens 1M dataset.

Overview

The ARAG paper proposes a 4-agent pipeline (User Understanding, NLI filtering, Context Summary, Item Ranker) for personalized recommendation. This project distills that into a single pydantic-ai agent that performs all reasoning stages within one LLM call, augmented with tool access for retrieval.

The agent receives text (demographics/preferences) and history (past interactions, may be empty for cold-start users) and works in three stages:

  1. Context understanding β€” analyzes the text field and fetches interacted item texts from LanceDB (if history exists) to build a preference summary
  2. Candidate retrieval β€” issues 2-4 search queries (vector, FTS, or hybrid) derived from the text field, preference summary, and retrieved item texts; interacted items are excluded
  3. Ranking β€” deduplicates candidates, excludes previously interacted items, ranks by relevance and diversity, and attaches a per-item explanation

The system is served via a FastAPI REST endpoint.

Architecture

Request (text, history: [{item_id, event_datetime, event_name, event_value}], limit)
    β”‚
    β”œβ”€ [Tool 1] get_item_texts(item_ids)    β†’ {item_id: item_text}  (skipped if cold-start)
    β”œβ”€ LLM: context understanding           β†’ preference summary
    β”œβ”€ [Tool 2] search_items(query, exclude_ids) β†’ candidates  (called 2-4Γ—)
    └─ LLM: rank + explain                 β†’ ItemRecommended list

POST /recommend      β†’ { items: [{ id, text, explanation }] }
POST /recommend/item β†’ { items: [{ id, text, explanation }] }

Requirements

  • Python 3.12+
  • uv for environment and task management β€” see pyproject.toml
  • An LLM API key matching the configured model
uv sync

Setup

1. Prepare MovieLens data

Downloads, extracts, and converts MovieLens 1M into Parquet files under data/:

uv run ml_1m

If you already have ml-1m.zip, place it under data/ before running the command.

2. Build the LanceDB indexes

Encodes items and users with sentence-transformers and writes to LanceDB:

uv run index
uv run index --parquet_path data/ml-1m/users.parquet --table_name users

3. Configure the LLM

export AGENTIC_REC_LLM_MODEL="cerebras:gpt-oss-120b"   # any pydantic-ai model string
export CEREBRAS_API_KEY="..."

Supported model strings: cerebras:gpt-oss-120b, anthropic:claude-haiku-4-5, ollama:llama3, and any other pydantic-ai provider.

4. Serve

uv run fastapi run agentic_rec.main:app

Request example:

curl -X POST http://localhost:3000/recommend \
  -H "Content-Type: application/json" \
  -d '{
    "text": "25-year-old male, software engineer, enjoys sci-fi and thriller films",
    "history": [
      {"item_id": "1193", "event_datetime": "2000-12-31T22:12:40", "event_name": "rating", "event_value": 5},
      {"item_id": "661",  "event_datetime": "2000-12-31T22:35:09", "event_name": "rating", "event_value": 3}
    ],
    "limit": 10
  }'

Modules

File Responsibility
agentic_rec/settings.py pydantic-settings Settings class: paths, model names, table names
agentic_rec/ml_1m.py MovieLens download, Parquet conversion, train/val/test split
agentic_rec/index.py LanceDB index: embedding, hybrid search, reranking (items & users)
agentic_rec/models.py Pydantic models: request/response types
agentic_rec/agent.py pydantic-ai Agent singleton with tools
agentic_rec/main.py FastAPI service entry point
agentic_rec/repositories/ Repository layer (data access)
agentic_rec/services/ Service layer (business logic)
agentic_rec/routers/ API layer (routers)
agentic_rec/dependencies.py Dependency injection

API Routes

Route Method Description
/healthz GET Service health and model configuration
/recommend POST User-based recommendations (alias: /recommend/user)
/recommend/item POST Item-based similar-item recommendations
/users/{user_id} GET Look up user by ID (text + history)
/users/{user_id}/recommend POST Recommend for an existing user by ID
/items/{item_id} GET Look up item by ID (text)
/items/{item_id}/recommend POST Similar-item recommendations for an item by ID

The /users/{user_id}/recommend and /items/{item_id}/recommend convenience routes look up the entity and then delegate to the corresponding /recommend or /recommend/item endpoint.

Development

# lint and format
uv run ruff check --fix .
uv run ruff format .

# tests
uv run pytest

References

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors