VillaOps AI
巴厘岛别墅和酒店物业经理的人工智能运营助理。与人工智能代理聊天,该代理可以查询预订、管理酒店、联系客人并提供分析——所有这些都是通过LangGraph和MCP支持的自然语言完成的。
现场演示: villaops.esakrissa.com | API文件: villaops.esakrissa.com/docs
______________________________________________________________________
主要特点
- AI聊天工具调用 --LangGraph代理通过Streamable HTTP连接到8个MCP工具,具有实时SSE流响应
- 完整SaaS计费 --Stripe Checkout、客户门户、webhook驱动的订阅生命周期(免费/专业/业务层)
- 计划门控使用限制 --中间件强制执行属性限制、AI查询配额和每个计划的功能访问
- 多提供商OAuth --Google+GitHub OAuth以及使用JWT令牌的电子邮件/密码注册
- 实时分析仪表板 --使用Recharts构建的入住率、收入趋势和预订图表
- 多提供商LLM网关 --LiteLLM路由到Gemini(默认),Anthropic和OpenAI作为回退,加上响应缓存
- 262次测试,覆盖率82% -跨身份验证、计费、代理、MCP工具和API端点的全面测试套件
- 具有目标部署的CI/CD --GitHub Actions管道,仅通过代码更改重建和部署服务
- 部署在AWS ECS Fargate上 --使用RDS PostgreSQL、ElastiCache Redis和Cloudflare SSL的生产基础设施
______________________________________________________________________
截图
| 物业管理 | 计费和使用 |
|---|---|
| Properties | Billing |
______________________________________________________________________
它的作用
物业经理可以简单地问:
- *“显示明天的所有签到”*
- *“为约翰预订日落别墅,2月10日至15日”*
- *“我们这个月的入住率是多少?”*
- *“向明天抵达的旅客发送入住说明”*
- *“取消预订#1234”*
- *“巴厘岛这个周末的天气预报是什么?”*
AI代理理解意图,选择正确的MCP工具,执行它,并通过聊天界面实时流式传输结果。
______________________________________________________________________
建筑
应用架构
┌────────────────────────────────────────────────────────────┐
│ Next.js Frontend │
│ │
│ ┌────────┐ ┌────────┐ ┌───────────┐ ┌───────────────┐ │
│ │ Auth │ │Pricing │ │ Chat UI │ │ Dashboard │ │
│ │ Pages │ │ Page │ │ (SSE) │ │ (Bookings/ │ │
│ │ │ │ │ │ │ │ Analytics) │ │
│ └────────┘ └────────┘ └───────────┘ └───────────────┘ │
└────────┬───────────────────────────────────────────────────┘
│ REST + SSE
▼
┌────────────────────────────────────────────────────┐
│ FastAPI Backend │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Auth: JWT + Google OAuth + GitHub OAuth │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Billing: Stripe Checkout + Webhooks │ │
│ │ Plan gating middleware (usage limits) │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ ┌──────────┐ ┌────────────────────────────────┐ │
│ │ REST API │ │ Chat API (SSE streaming) │ │
│ │ /api/v1 │ │ /api/v1/chat │ │
│ └────┬─────┘ └──────────┬─────────────────────┘ │
│ │ │ │
│ │ ┌──────────▼─────────────────────┐ │
│ │ │ LangGraph Agent │ │
│ │ │ + MCP Client (Streamable HTTP) │ │
│ │ └──────────┬─────────────────────┘ │
│ │ │ Streamable HTTP │
│ │ ▼ │
│ ┌────────────────────────────────────────────┐ │
│ │ MCP Server (Streamable HTTP on /mcp) │ │
│ │ booking_search | booking_create │ │
│ │ booking_update | booking_analytics │ │
│ │ guest_lookup | property_manage │ │
│ │ send_notification | web_search │ │
│ └────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ LiteLLM Gateway │ │
│ │ Gemini (default) → Claude → GPT │ │
│ │ + caching + cost tracking + fallback │ │
│ └────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────┘
┌──────────────────┐ ┌────────────────┐ ┌─────────────┐
│ PostgreSQL │ │ Redis │ │ Stripe │
│ (8 tables) │ │ (cache) │ │ Payments │
└──────────────────┘ └────────────────┘ └─────────────┘部署架构
Cloudflare (SSL + DNS)
│
▼
┌───────────────────────┐
│ Nginx (ECS Fargate) │
│ Reverse Proxy │
└──────────┬────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌──────────────┐
│ Backend │ │ Frontend │ │ MCP Server │
│ (FastAPI) │ │ (Next.js) │ │ (FastMCP) │
│ :8000 │ │ :3000 │ │ :8001 │
└──────┬──────┘ └─────────────┘ └──────┬───────┘
│ │
┌──────┴──────┐ ┌──────┴──────┐
│ RDS │ │ ElastiCache │
│ PostgreSQL │ │ Redis │
└─────────────┘ └─────────────┘
Service Discovery: AWS Cloud Map (villaops.local)
CI/CD: GitHub Actions → ECR → ECS (targeted deploy)______________________________________________________________________
技术栈
| 层 | 技术 |
|---|---|
| 后端 | Python 3.13+,FastAPI(异步),Pydantic v2 |
| 代理 | LangGraph |
| 工具协议 | MCP(流式HTTP传输) |
| LLM网关 | LiteLLM(Gemini默认,Anthropic+OpenAI回退) |
| 支付 | Stripe(结账+Webhooks+客户门户) |
| 数据库 | PostgreSQL 16+SQLAlchemy(异步)+Alembic迁移 |
| 缓存 | Redis 7 |
| 认证 | JWT(python jose)+谷歌OAuth+GitHub OAuth(authlib) |
| 前端 | Next.js 16、React 19、TypeScript、顺风CSS v4 |
| 图表 | Recharts |
| 测试 | pytest、pytest-asyncio、httpx(262个测试,82%的覆盖率) |
| CI/CD | GitHub操作(lint+test+build+定向部署) |
| 部署 | AWS云服务器Fargate+ECR+RDS+ElastiCache+Cloudflare |
| 反向代理 | Nginx(通过AWS Cloud Map DNS进行基于路径的路由) |
______________________________________________________________________
定价
| 免费 | 专业 | 商业 | |
|---|---|---|---|
| 价格 | 0美元/月 | 29美元/月 | 79美元/月 |
| 属性 | 1 | 5 | 无限制 |
| AI查询 | 每月50次 | 每月500次 | 无限制 |
| 分析 | 基本 | 完全 | 完全+导出 |
| 通知 | -- | 是 | 是 |
______________________________________________________________________
入门指南
先决条件
- Docker&Docker编写
- Python 3.13+
- Node.js 22+
- 至少一个LLM提供程序(Gemini、Anthropic或OpenAI)的API密钥
- 条纹账户(测试模式)——本地开发人员可选,无需计费
快速入门(Docker)
- 克隆存储库
git clone https://github.com/esakrissa/villa-ops-ai.git
cd villa-ops-ai- 配置环境变量
cp .env.example .env
# Edit .env with your API keys, OAuth credentials, and Stripe keys- 启动所有服务
docker-compose up --build这将启动5个服务:FastAPI后端(:8000)、MCP服务器(:8001)、Next.js前端(:3000)、PostgreSQL和Redis。
- 运行数据库迁移和种子数据
docker-compose exec backend alembic upgrade head
docker-compose exec backend python scripts/seed_data.py- 启动Stripe webhook侦听器 (可选,用于计费功能)
stripe listen --forward-to localhost:8000/api/v1/webhooks/stripe- 打开应用程序
| 服务 | URL |
|---|---|
| 前端 | http://localhost:3000 |
| API文档(Swagger) | http://localhost:8000/docs |
| MCP服务器 | http://localhost:8001/mcp |
不使用Docker运行
Backend
cd backend
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
# Ensure PostgreSQL and Redis are running locally
alembic upgrade head
python scripts/seed_data.py
uvicorn app.main:app --reloadMCP Server
cd backend
source .venv/bin/activate
python -m app.mcp.serverFrontend
cd frontend
npm install
npm run dev______________________________________________________________________
API概述
身份验证端点
| 方法 | 端点 | 描述 |
|---|---|---|
POST | /api/v1/auth/register | 使用电子邮件/密码注册 |
POST | /api/v1/auth/login | 登录,返回JWT |
GET | /api/v1/auth/google | 谷歌OAuth重定向 |
GET | /api/v1/auth/github | GitHub OAuth重定向 |
POST | /api/v1/auth/refresh | 刷新JWT令牌 |
GET | /api/v1/auth/me | 当前用户配置文件 |
计费端点
| 方法 | 端点 | 身份验证 | 描述 |
|---|---|---|---|
GET | /api/v1/billing/plans | 否 | 列出可用计划(公开) |
GET | /api/v1/billing/subscription | 是 | 当前计划+使用情况统计 |
POST | /api/v1/billing/checkout | 是 | 创建条纹结账会话 |
POST | /api/v1/billing/portal | 是 | 获取Stripe客户门户URL |
POST | /api/v1/webhooks/stripe | 否 | 条纹webhook处理程序 |
REST端点
| 方法 | 端点 | 描述 |
|---|---|---|
GET | /api/v1/properties | 列出所有属性 |
POST | /api/v1/properties | 创建属性(强制执行计划限制) |
GET | /api/v1/bookings | 列出预订(带过滤器) |
POST | /api/v1/bookings | 创建预订 |
PATCH | /api/v1/bookings/{id} | 更新预订 |
GET | /api/v1/guests | 列出客人 |
GET | /api/v1/analytics/occupancy | 占用率分析 |
聊天端点
POST /api/v1/chat
Content-Type: application/json
Accept: text/event-stream
Authorization: Bearer
{
"message": "Show me all check-ins for tomorrow",
"conversation_id": "optional-uuid"
}将SSE事件与代理响应和工具调用结果流式传输。人工智能查询的使用将计入计划限制。
______________________________________________________________________
MCP工具
LangGraph代理通过Streamable HTTP连接到MCP服务器,可以访问8个工具:
| 工具 | 说明 |
|---|---|
booking_search | 按日期、客人、酒店或状态搜索预订 |
booking_create | 创建带有验证的新预订(可用性+冲突检查) |
booking_update | 修改或取消现有预订 |
booking_analytics | 入住率、收入和预订趋势 |
guest_lookup | 搜索客人信息和预订历史 |
property_manage | 检查可用性、阻止日期、更新定价 |
send_notification | 向客人发送模板电子邮件(仅限Pro+计划) |
web_search | 通过Exa搜索外部信息(天气、当地活动等) |
______________________________________________________________________
测试
cd backend
# Run all tests
pytest
# With coverage report
pytest --cov=app --cov-report=term-missing
# Specific test suites
pytest tests/test_api/ # API endpoints
pytest tests/test_auth/ # Authentication (JWT + OAuth)
pytest tests/test_billing/ # Stripe billing lifecycle
pytest tests/test_agent/ # Agent reasoning + tool selection
pytest tests/test_mcp/ # MCP tool edge cases
pytest tests/test_services/ # Business logic当前统计数据: 262个测试通过,代码覆盖率82%。
______________________________________________________________________
部署
应用程序部署在 AWS云服务器Fargate 通过GitHub Actions实现自动化CI/CD。
基础设施
| 资源 | 服务 |
|---|---|
| 计算 | AWS ECS Fargate(4项服务:后端、MCP、前端、nginx) |
| 数据库 | AWS RDS PostgreSQL 16 |
| 缓存 | AWS ElastiCache Redis 7 |
| 容器注册表 | AWS ECR(3个存储库) |
| 服务发现 | AWS云地图(villaops.local) |
| SSL/DNS | Cloudflare(代理A记录) |
| 反向代理 | ECS Fargate上的Nginx(通过Cloud Map DNS进行基于路径的路由) |
| CI/CD | GitHub操作(2个工作流: ci.yml + deploy.yml) |
CI/CD管道
Push to main → CI (lint + test + build) → Deploy (targeted)- 有针对性的部署 --仅部署具有实际代码更改的服务
- 后端更改→ 重建后端+MCP映像(约8分钟)
- 前端更改→ 仅重建前端图像(约5分钟)
- 无服务更改→ 跳过部署(约1分钟)
- Cloudflare DNS自动更新 --如果nginx公共IP发生变化,部署工作流会更新A记录
______________________________________________________________________
项目结构
villa-ops-ai/
├── backend/
│ ├── app/
│ │ ├── main.py # FastAPI entry point
│ │ ├── config.py # Settings (pydantic-settings)
│ │ ├── database.py # Async SQLAlchemy engine + sessions
│ │ ├── models/ # 8 SQLAlchemy models
│ │ ├── schemas/ # Pydantic request/response schemas
│ │ ├── api/v1/ # REST + Chat + Auth + Billing + Webhook routers
│ │ ├── auth/ # JWT + OAuth (Google, GitHub)
│ │ ├── billing/ # Stripe (checkout, webhooks, plan gating)
│ │ ├── agent/ # LangGraph agent + MCP client
│ │ ├── mcp/ # MCP server (Streamable HTTP)
│ │ │ ├── server.py
│ │ │ └── tools/ # 8 tool modules
│ │ └── services/ # Business logic layer
│ ├── tests/ # 262 tests (82% coverage)
│ │ ├── conftest.py
│ │ ├── test_api/
│ │ ├── test_auth/
│ │ ├── test_billing/
│ │ ├── test_agent/
│ │ ├── test_mcp/
│ │ └── test_services/
│ ├── scripts/
│ │ └── seed_data.py # Idempotent demo data seeder
│ ├── alembic/ # Database migrations
│ ├── Dockerfile
│ ├── pyproject.toml
│ └── alembic.ini
├── frontend/
│ ├── src/
│ │ ├── app/
│ │ │ ├── (auth)/ # Login, register, OAuth callbacks
│ │ │ ├── pricing/ # Public pricing page
│ │ │ ├── chat/ # Chat interface (SSE streaming)
│ │ │ └── dashboard/ # Bookings, analytics, properties, billing
│ │ ├── components/
│ │ │ ├── auth/ # OAuthButtons, LoginForm, RegisterForm
│ │ │ ├── chat/ # ChatWindow, MessageBubble, ToolCallCard
│ │ │ ├── dashboard/ # BookingTable, OccupancyChart, PropertyCard
│ │ │ ├── billing/ # PricingCard, UsageMeter, PlanBadge
│ │ │ └── ui/ # Header, Sidebar, LoadingSkeleton
│ │ └── lib/ # API client, auth helpers, hooks
│ ├── Dockerfile
│ └── package.json
├── .aws/ # AWS ECS infrastructure
│ ├── backend-task-def.json
│ ├── frontend-task-def.json
│ ├── mcp-task-def.json
│ ├── nginx-task-def.json
│ ├── setup-infra.sh
│ └── nginx/ # Nginx config + Dockerfile
├── .github/workflows/
│ ├── ci.yml # CI: lint (ruff+mypy) + test + build
│ └── deploy.yml # Deploy: targeted ECR + ECS + Cloudflare DNS
├── docker-compose.yml # Dev: 5 services (frontend + backend + MCP + postgres + redis)
├── .env.example # Environment variable template
└── README.md______________________________________________________________________
环境变量
所有变量均通过配置 .env (参见 .env.example 模板)。
| 变量 | 必填 | 描述 |
|---|---|---|
| 应用 | ||
APP_NAME | 否 | 应用程序名称(默认值: VillaOps AI) |
DEBUG | 否 | 启用调试模式(默认: true) |
ENVIRONMENT | 没有 | development 或 production |
| 数据库 | ||
DATABASE_URL | 是 | PostgreSQL异步连接字符串 |
| 缓存 | ||
REDIS_URL | 是 | Redis连接字符串 |
| 认证 | ||
JWT_SECRET_KEY | 是 | JWT令牌签名的密钥 |
JWT_ACCESS_TOKEN_EXPIRE_MINUTES | 否 | 访问令牌TTL(默认值: 30) |
JWT_REFRESH_TOKEN_EXPIRE_DAYS | 否 | 刷新令牌TTL(默认值: 7) |
GOOGLE_CLIENT_ID | 否 | 谷歌OAuth客户端ID |
GOOGLE_CLIENT_SECRET | 否 | 谷歌OAuth客户端机密 |
GITHUB_CLIENT_ID | 否 | GitHub OAuth客户端ID |
GITHUB_CLIENT_SECRET | 否 | GitHub OAuth客户端机密 |
| 条纹 | ||
STRIPE_SECRET_KEY | 否\* | 条纹密钥(*计费功能所需) |
STRIPE_PUBLISHABLE_KEY | 没有* | 条纹可发布密钥 |
STRIPE_WEBHOOK_SECRET | 否\* | 条纹webhook签名密码 |
STRIPE_PRO_PRICE_ID | 否\* | Pro计划的条纹价格ID |
STRIPE_BUSINESS_PRICE_ID | 否\* | 商业计划的条纹价格ID |
| LLM | ||
DEFAULT_LLM_MODEL | 否 | LiteLLM模型字符串(默认值: gemini/gemini-3-flash-preview) |
GEMINI_API_KEY | 是\*\* | Google Gemini API密钥(\*\*至少需要一个LLM密钥) |
ANTHROPIC_API_KEY | 否 | Anthropic API密钥(回退) |
OPENAI_API_KEY | 否 | OpenAI API密钥(回退) |
| 网络搜索 | ||
EXA_API_KEY | 没有的 | Exa API密钥 web_search 工具 |
| 服务 | ||
MCP_SERVER_URL | 是 | MCP服务器URL(默认值: http://localhost:8001/mcp) |
FRONTEND_URL | 是 | CORS和OAuth重定向的前端URL |
______________________________________________________________________
许可证
麻省理工学院
