互客鱼 返回主站

架构

技术栈和布局

互客鱼是一个包含两个前端的单一 Laravel 代码库。后端是 PHP 8.3+ 上的 Laravel 13 + Octane;管理 UI 是 Inertia v3 + React 19;访客小部件是 Preact ≤50KB。AI 技术栈默认使用 Cloudflare(Workers AI + Vectorize + Browser Rendering),以 OpenAI + Qdrant 作为备选。

技术栈

层级技术
应用框架Laravel 13(PHP 8.3+)
服务器FrankePHP 上的 Laravel Octane
实时通信Laravel Reverb(WebSocket)
队列Redis 上的 Laravel Horizon
身份验证Laravel Fortify(会话、2FA、密码重置)+ Sanctum(API token)
账单Laravel Cashier(Stripe)
数据库Postgres 16
缓存/会话Redis 7
管理前端Inertia v3 + React 19、Tailwind v4、shadcn/ui(Radix)、Vite、严格 TS
类型化路由Wayfinder(Laravel 路由的 TS 绑定)
访客小部件Preact 10(别名为 React)+ Vite + 选择性 Tailwind v4
LLM(首选)Cloudflare Workers AI —— Llama 3.3 70B + bge-base-en-v1.5
LLM(备选)OpenAI gpt-4o-mini + text-embedding-3-small(以及 OpenRouter 作为路由器)
向量存储(首选)Cloudflare Vectorize
向量存储(备选)Qdrant(HTTP 客户端)
爬虫(首选)Cloudflare Browser Rendering
爬虫(备选)Browserless → 纯 HTTP
对象存储Cloudflare R2(S3 兼容)
托管Laravel Cloud
可观测性Sentry + OpenTelemetry → Honeycomb / Grafana Cloud

仓库布局

一个位于仓库根目录的 Laravel 应用。管理前端作为 Inertia 页面在同一应用中提供; 访客小部件是第二个独立的 Vite 构建。

hukeyu/                     — Laravel 应用
├── app/
│   ├── Actions/Fortify/      — Fortify 钩子(CreateNewUser 等)
│   ├── Concerns/             — BelongsToWorkspace、BelongsToAgent traits
│   ├── Http/
│   │   ├── Controllers/Admin/    — 客户 + 管理 Inertia 控制器
│   │   ├── Controllers/Widget/   — /api/v1/widget/*(访客端,JWT)
│   │   └── Middleware/
│   ├── Models/               — Workspace、Agent、Conversation、Plan、…
│   ├── Services/
│   │   ├── Rag/              — Retriever、Chunker、PromptBuilder、CuratedAnswerMatcher
│   │   ├── Llm/              — OpenAiHttpClient、WorkersAiClient、Fakes
│   │   ├── Vector/           — VectorizeClient、QdrantHttpClient
│   │   ├── Crawl/            — CloudflareBrowserClient、AutoIndexPageVisit、PlainHttpCrawler
│   │   ├── Triggers/         — CtaSelector、LeadIntentDetector
│   │   ├── Analytics/        — EventStore(分析汇总 + 缺口检测在 app/Jobs/Analytics 中)
│   │   ├── Billing/          — StripeProductSync、MeteredBilling、PayPalClient、RazorpayClient
│   │   ├── Tools/            — ToolRegistry + EscalateToHumanTool(第 2 阶段)
│   │   ├── Vertical/         — VerticalPresetRegistry + 7 个预设类
│   │   ├── I18n/             — LocaleResolver、LocaleCatalog(132 种语言)
│   │   └── Widget/           — WidgetJwt、WidgetCopy、InlineBlockParser
│   ├── Jobs/Crawl/           — CrawlSourceJob、CrawlPageJob、IndexDocumentJob
│   ├── Jobs/Analytics/       — DetectGapJob(流后缺口检测)
│   └── Events/               — TokenStreamed、TurnCompleted、TurnFailed
├── resources/
│   ├── js/                   — 管理 Inertia(默认 Vite 构建)
│   │   ├── pages/
│   │   ├── components/
│   │   └── …
│   ├── widget/               — 访客小部件(独立 Vite 构建)
│   ├── views/                — Blade(Inertia 根 + 营销 + 文档)
│   └── css/app.css           — Tailwind v4 入口
├── routes/
│   ├── web.php
│   ├── api.php
│   └── channels.php
├── database/{migrations,factories,seeders}
├── tests/{Feature,Unit,Browser}
├── docs/PLAN.md              — 完整工程计划
└── public/widget/            — 构建的小部件包

两个前端,一个后端

管理和客户界面是同一个 Inertia 应用——相同的 Vite 构建,相同的组件库。 角色通过路由组和中间件分离,而不是通过代码库。这为设计令牌、路由帮助器和 身份验证状态保持单一事实来源。

访客小部件则相反——它有意与管理代码共享任何内容。它不能从 resources/js/ 导入;它有自己的 Vite 配置;它有自己的路由器 (只是一个 Preact 组件树)和自己的状态。大小预算是硬性的 50KB 压缩—— 管理功能不能渗入。

Reverb 和 WebSocket

Reverb 作为独立进程运行并支持:

  • 收件箱实时更新 ——操作员在新消息到达时看到它们。
  • 人工接管事件 ——当操作员认领对话时,访客的小部件获得"人工在此"事件。
  • 操作员存在 ——可用/离开状态在团队成员之间同步。

频道默认是私有的——小部件使用其 JWT 加入 conversation.{id}, 操作员应用使用其会话加入 workspace.{id}

Cloudflare 一账单模式

设置 CLOUDFLARE_ACCOUNT_ID + CLOUDFLARE_API_TOKEN, LLM、向量存储和爬虫都自动绑定到 Cloudflare。外部基础设施总成本: $5/月 Workers Paid + 按请求使用。替换任何一个部分(例如,通过设置 QDRANT_URL 将 Vectorize 换成 Qdrant),绑定就会转移。

多租户隔离

每个租户范围的查询都由 BelongsToWorkspace trait 的全局作用域过滤。 跨越边界需要显式的 withoutWorkspaceScope() 并提供合理的注释。 有一个回归测试,如果带有 workspace_id 列的模型不使用该 trait, 构建将失败。详见 多租户