Files
ars-backend/CLAUDE.md
Roog fa00da5966 调整 Docker 环境与依赖配置:
- 替换基础镜像为 `php:8.4.15-cli-alpine3.23`,重构依赖安装流程
- 切换包管理工具为 `apk`,添加必要系统库及扩展
- 更新 Composer 脚本及依赖映射
- 优化命令与环境变量配置,增强一致性与兼容性
2025-12-17 17:13:37 +08:00

9.3 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. 自然语言使用中文。

项目概述

这是一个基于 Laravel 12 + Octane + Docker 的 Agent Runtime Server (ARS),用于提供可部署的 Agent 运行时服务。核心特性包括:

  • 兼容多种 Agent 模型
  • Web 终端实时交互,支持断线重连
  • 后台任务持续执行,重连后可续传会话

技术栈

  • PHP: 8.2+
  • Laravel Framework: 12.x
  • Laravel Octane: 2.x (FrankenPHP)
  • Laravel Horizon: 5.x (队列监控)
  • Laravel Telescope: 5.x (调试工具)
  • 数据库: PostgreSQL 16
  • 缓存/队列: Redis 7
  • 认证: JWT (php-open-source-saver/jwt-auth)
  • 容器化: Docker Compose

核心架构

数据模型

ChatSession (会话)

  • session_id (UUID, 主键): 会话唯一标识
  • session_name: 会话名称
  • status: 会话状态 (OPEN/LOCKED/CLOSED)
  • last_seq: 最后消息序号
  • last_message_id: 最后消息ID

Message (消息)

  • message_id (UUID, 主键): 消息唯一标识
  • session_id: 所属会话ID
  • role: 消息角色 (USER/AGENT/TOOL/SYSTEM)
  • type: 消息类型 (user.prompt/agent.message/run.status等)
  • content: 消息内容 (text)
  • payload: 附加数据 (jsonb)
  • seq: 会话内序号 (单调递增)
  • reply_to: 回复的消息ID
  • dedupe_key: 幂等去重键
  • 约束: unique(session_id, seq)unique(session_id, dedupe_key)

会话状态与门禁规则

  • OPEN: 正常追加所有消息
  • LOCKED: 拒绝 role=USER && type=user.prompt
  • CLOSED: 拒绝追加,例外允许 role=SYSTEM && type in [run.status, error]
  • 状态变更规则: CLOSED 状态的会话不能重新打开

Agent Run 执行流程

  1. 用户发送 user.prompt 消息后自动触发,或通过 API 手动触发
  2. RunDispatcher 检查幂等性(基于 trigger_message_id
  3. 检查会话是否已有 RUNNING 状态的 run单会话单任务限制
  4. 创建 run.status=RUNNING 消息并派发 AgentRunJob
  5. RunLoop 执行 Agent 调用流程:
    • ContextBuilder 构建上下文
    • AgentProviderInterface 调用 Agent当前为 DummyAgentProvider
    • CancelChecker 检查取消信号
    • OutputSink 写入 agent.message
  6. 完成后写入 run.status=DONE/FAILED/CANCELED

实时消息推送 (SSE)

  • 端点: GET /api/sessions/{id}/sse?after_seq=123
  • 机制:
    1. 先从数据库补发历史消息seq > after_seq
    2. 订阅 Redis 频道 session:{id}:messages 监听新消息
    3. 支持 Last-Event-ID 自动续传
  • 事件格式: SSE event id 为消息 seq

服务层架构

  • ChatService: 会话和消息的核心业务逻辑

    • 使用行锁 (lockForUpdate) + 事务保证消息 seq 单调递增
    • 通过 dedupe_key 实现幂等性
    • 消息追加后发布 Redis 事件用于 SSE 推送
  • RunDispatcher: Agent Run 调度器

    • 检查 trigger_message_id 幂等性
    • 确保同会话只有一个 RUNNING 状态的 run
  • RunLoop: Agent 执行循环

    • 协调 ContextBuilder、AgentProvider、OutputSink、CancelChecker
  • OutputSink: 统一的消息写入接口

    • appendAgentMessage(): 写入 agent 回复
    • appendRunStatus(): 写入 run 状态
    • appendError(): 写入错误信息

常用开发命令

Docker 容器操作

# 构建并启动所有服务
docker compose build
docker compose up -d app horizon pgsql redis

# 停止服务
docker compose stop

# 查看日志
docker compose logs -f app
docker compose logs -f horizon

# 进入容器 shell
docker compose exec app bash

数据库操作

# 运行迁移
docker compose exec app php artisan migrate

# 回滚迁移
docker compose exec app php artisan migrate:rollback

# 刷新数据库(危险:删除所有表并重新迁移)
docker compose exec app php artisan migrate:fresh

# 运行 seeder
docker compose exec app php artisan db:seed

测试

# 运行所有测试
docker compose exec app php artisan test

# 运行特定测试套件
docker compose exec app php artisan test --testsuite=Feature
docker compose exec app php artisan test --testsuite=Unit

# 运行特定测试文件
docker compose exec app php artisan test tests/Feature/ChatSessionTest.php

# 运行特定测试方法(使用 filter
docker compose exec app php artisan test --filter=testCreateSession
docker compose exec app php artisan test --filter=testAppendMessageWithDedupe

# 显示测试覆盖率
docker compose exec app php artisan test --coverage

代码质量

# 运行 Laravel Pint 格式化代码
docker compose exec app vendor/bin/pint

# 只检查格式问题(不修改)
docker compose exec app vendor/bin/pint --test

# 格式化脏文件git 变更的文件)
docker compose exec app vendor/bin/pint --dirty

队列与任务

# 查看 Horizon 仪表板
# 访问 http://localhost:8000/horizon

# 手动运行队列 worker开发调试用
docker compose exec app php artisan queue:work

# 查看失败的任务
docker compose exec app php artisan queue:failed

# 重试失败的任务
docker compose exec app php artisan queue:retry all

开发调试

# 启动 Tinker REPL
docker compose exec app php artisan tinker

# 查看路由列表
docker compose exec app php artisan route:list

# 清除缓存
docker compose exec app php artisan cache:clear
docker compose exec app php artisan config:clear
docker compose exec app php artisan route:clear

# 查看实时日志(使用 Laravel Pail
docker compose exec app php artisan pail

Artisan 生成器

# 生成 Model推荐带选项一次性生成相关文件
docker compose exec app php artisan make:model ChatSession -mfs
# -m: migration, -f: factory, -s: seeder

# 生成 Controller
docker compose exec app php artisan make:controller ChatSessionController

# 生成 Form Request用于验证
docker compose exec app php artisan make:request AppendMessageRequest

# 生成 ResourceAPI 响应格式化)
docker compose exec app php artisan make:resource ChatSessionResource

# 生成 Job
docker compose exec app php artisan make:job AgentRunJob

# 生成 Service 类
docker compose exec app php artisan make:class Services/ChatService

# 生成测试
docker compose exec app php artisan make:test ChatSessionTest --phpunit
docker compose exec app php artisan make:test ChatServiceTest --unit --phpunit

API 路由结构

所有 API 路由均在 /api/* 下,除登录和健康检查外均需 JWT 认证:

  • POST /api/login: 用户登录
  • GET /api/health: 健康检查
  • GET /api/me: 获取当前用户信息

用户管理

  • GET /api/users: 用户列表
  • POST /api/users: 创建用户
  • PUT /api/users/{user}: 更新用户
  • POST /api/users/{user}/deactivate: 停用用户
  • POST /api/users/{user}/activate: 激活用户

会话管理

  • POST /api/sessions: 创建会话
  • GET /api/sessions: 会话列表(支持分页、状态过滤、关键词搜索)
  • GET /api/sessions/{session_id}: 获取会话详情
  • PATCH /api/sessions/{session_id}: 更新会话(重命名、状态变更)
  • POST /api/sessions/{session_id}/archive: 归档会话(幂等,设为 CLOSED

消息管理

  • POST /api/sessions/{session_id}/messages: 追加消息(支持幂等 dedupe_key
  • GET /api/sessions/{session_id}/messages: 获取消息列表(支持 after_seq 增量拉取)
  • GET /api/sessions/{session_id}/messages/{message_id}: 获取单条消息

实时与 Agent Run

  • GET /api/sessions/{session_id}/sse: SSE 实时消息流
  • POST /api/sessions/{session_id}/runs: 手动触发 Agent Run

开发注意事项

Laravel 12 新特性

  • app/Console/Kernel.phpapp/Http/Kernel.php
  • 中间件、路由、异常处理在 bootstrap/app.php 配置
  • 服务提供者在 bootstrap/providers.php 注册
  • Commands 自动注册(无需手动注册)

数据库操作规范

  • 消息追加必须使用 ChatService::appendMessage(),不要直接操作 Message 模型
  • 会话状态变更必须通过 ChatService::updateSession()
  • 所有涉及 seq 递增的操作必须在事务 + 行锁中完成

测试规范

  • 所有测试使用 PHPUnit非 Pest
  • Feature 测试必须测试完整的 HTTP 请求流程
  • 测试中使用 Factory 创建模型数据
  • 修改代码后必须运行相关测试确保通过

队列配置

  • 开发环境可使用同步队列:.env 中设置 QUEUE_CONNECTION=sync
  • 生产环境使用 Redis 队列 + Horizon 监控
  • AgentRunJob 在队列中异步执行

幂等性设计

  • 所有可能重复调用的操作都使用 dedupe_key
  • RunDispatcher 通过 trigger_message_id 确保不会为同一 prompt 重复创建 run
  • SSE 通过 Last-Event-ID / after_seq 支持断线续传

环境变量关键配置

# Octane 服务器
OCTANE_SERVER=frankenphp

# 数据库PostgreSQL
DB_CONNECTION=pgsql
DB_HOST=pgsql
DB_PORT=5432
DB_DATABASE=ars_backend

# Redis
REDIS_HOST=redis
REDIS_PORT=6379

# 队列
QUEUE_CONNECTION=redis  # 或 sync开发用

# JWT 认证
JWT_SECRET=<生成的密钥>
AUTH_GUARD=api

# CORS
CORS_ALLOWED_ORIGINS=http://localhost:5173

相关文档

  • API 详细文档:docs/ChatSession/chat-session-api.md
  • OpenAPI 规范:docs/ChatSession/chat-session-openapi.yaml
  • 用户管理文档:docs/User/user-api.md