Luxx/assets/ARCHITECTURE.md

354 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Luxx 项目架构
## 技术栈
- **框架**: FastAPI 0.109+
- **数据库**: SQLAlchemy 2.0+ (同步模式)
- **认证**: JWT (PyJWT)
- **HTTP客户端**: httpx, requests
- **配置**: YAML (PyYAML)
- **代码执行**: Python 原生执行
- **网页爬虫**:
- `httpx` - HTTP 客户端
- `beautifulsoup4` - HTML 解析
- `lxml` - XML/HTML 解析器
## 目录结构
```
luxx/
├── __init__.py # FastAPI 应用工厂
├── config.py # 配置管理YAML
├── core/
│ ├── __init__.py
│ ├── config.py # 配置管理
│ └── database.py # 数据库连接
├── models/ # ORM 模型
│ ├── __init__.py
│ ├── user.py # User, LLMProvider, Project
│ ├── chat.py # Conversation, Message
│ ├── room.py # ChatRoom, Agent, RoomParticipant, ChatRoomMessage
│ └── participant.py # Participant (统一参与者抽象)
├── services/ # 服务层
│ ├── __init__.py
│ ├── chat.py # 聊天服务 (Agentic Loop)
│ ├── room.py # 聊天室服务 (多 Agent 编排)
│ ├── participant.py # 统一参与者服务
│ ├── room_ws.py # WebSocket 处理
│ ├── llm_service.py # LLM 服务
│ ├── message_service.py # 消息服务
│ ├── stream_service.py # 流式响应服务
│ ├── task.py # 任务服务
│ └── agent.py # Agent 管理
├── agents/ # Agent 系统
│ ├── __init__.py
│ ├── base.py # BaseAgent 抽象类
│ └── registry.py # Agent 注册表
├── api/ # API 路由层
│ ├── __init__.py
│ ├── auth.py # 认证 (登录/注册)
│ ├── conversations.py # 会话管理 (CRUD)
│ ├── messages.py # 消息处理
│ ├── providers.py # LLM 提供商管理
│ ├── tools.py # 工具管理
│ ├── agents.py # Agent 管理
│ └── rooms.py # 聊天室管理
├── tools/ # 工具系统
│ ├── __init__.py
│ ├── core.py # 核心类 (ToolRegistry, ToolDefinition, ToolResult)
│ ├── factory.py # @tool 装饰器
│ ├── executor.py # 工具执行器
│ └── builtin/ # 内置工具
│ ├── __init__.py
│ ├── code.py # 代码执行
│ ├── crawler.py # 网页爬虫
│ └── data.py # 数据处理
└── utils/ # 工具函数
└── helpers.py # 密码哈希、ID生成、响应封装
run.py # 应用入口文件
config.yaml # 配置文件
```
## 核心组件
### 1. 应用工厂 (`__init__.py`)
FastAPI 应用入口,使用 lifespan 管理生命周期:
- 启动:初始化数据库、注册内置工具、创建默认管理员用户
- 关闭:清理资源
### 2. 配置管理 (`core/config.py`)
使用 YAML 文件管理配置:
- 配置文件:`config.yaml`
- 环境变量替换:`${VAR_NAME}`
- 单例模式全局访问
### 3. 数据库 (`core/database.py`)
- SQLAlchemy 同步支持
- SQLite 默认数据库
- 依赖注入获取会话
### 4. ORM 模型
#### 统一参与者架构
```mermaid
classDiagram
class Participant {
+str participant_id
+str name
+ParticipantType participant_type
+from_user(User) Participant
+from_agent(...) Participant
+from_participant_id(str) Participant
}
class ParticipantType {
<<enumeration>>
USER = "user"
AGENT = "agent"
}
class RoomParticipant {
+str room_id
+str agent_id
+int user_id
+str role
+participant_id property
+participant_type property
}
class ChatRoomMessage {
+str participant_id
+sender_type property
+sender_id property
}
Participant --> ParticipantType
RoomParticipant --> Participant
ChatRoomMessage --> Participant
```
### 5. 聊天室系统
#### WebSocket 端点
- `/ws/chat-room/{room_id}?participant_type=user&participant_id=123&participant_name=John`
- `/ws/chat-room/{room_id}?participant_type=agent&participant_id=agent-1&participant_name=Assistant`
#### ParticipantService
统一处理用户和 Agent 的消息:
- `process_message()` - 处理来自任何参与者的消息
- `send_message()` - 主动发送消息
### 6. 工具系统
```mermaid
classDiagram
class ToolDefinition {
+str name
+str description
+dict parameters
+Callable handler
+str category
+to_openai_format() dict
}
class ToolResult {
+bool success
+Any data
+str error
+to_dict() dict
+ok(data) ToolResult$
+fail(error) ToolResult$
}
class ToolRegistry {
+_tools: Dict
+register(tool) void
+get(name) ToolDefinition?
+list_all() List~dict~
+execute(name, arguments) dict
}
class ToolExecutor {
+enable_cache: bool
+process_tool_calls(tool_calls, context) list
+process_tool_calls_parallel(tool_calls, context) list
}
```
#### 内置工具
| 工具 | 功能 | 说明 |
|------|------|------|
| `python_execute` | 执行 Python 代码 | 支持 print 输出、变量访问 |
| `python_eval` | 计算表达式 | 快速求值 |
| `web_search` | DuckDuckGo HTML | DuckDuckGo HTML 搜索 |
| `web_fetch` | 网页抓取 | httpx + BeautifulSoup支持 text/links/structured |
| `batch_fetch` | 批量抓取 | 并发获取多个页面 |
| `process_data` | 数据处理 | JSON 转换、格式化等 |
#### 工具开发规范
**核心原则:装饰器自动处理一切,工具函数只写业务逻辑**
```python
from luxx.tools.factory import tool
@tool(
name="my_tool",
description="工具描述",
parameters={...},
required_params=["arg1"], # 自动验证
category="my_category"
)
def my_tool(arguments: dict):
# 业务逻辑 - 只管返回数据
data = fetch_data(arguments["arg1"])
return {"items": data, "count": len(data)}
# 或者直接抛出异常(装饰器自动捕获并转换)
if invalid:
raise ValueError("Invalid input")
```
**装饰器自动处理:**
1. 必需参数验证(`required_params`
2. 所有异常捕获和转换
3. 结果格式统一包装
**返回格式转换:**
| 工具函数返回/抛出 | 装饰器转换为 |
|-------------------|-------------|
| `return {"result": "ok"}` | `{"success": true, "data": {...}, "error": null}` |
| `raise ValueError("msg")` | `{"success": false, "data": null, "error": "ValueError: msg"}` |
| `raise Exception()` | `{"success": false, "data": null, "error": "..."}` |
#### 工具调用流程
```mermaid
flowchart TD
A[LLM 请求] --> B{ToolRegistry.execute}
B --> C[@tool 装饰器]
C --> D{验证 required_params}
D -->|失败| E[返回 error]
D -->|成功| F[执行工具函数]
F --> G{try-except}
G -->|成功| H[包装 ToolResult]
G -->|异常| I[捕获并转换 error]
I --> H
H --> J[返回 ToolResult]
J --> K[前端 ProcessBlock 显示]
```
#### Message Content JSON 结构
`content` 字段统一使用 JSON 格式存储:
**User 消息:**
```json
{
"text": "用户输入的文本内容",
"attachments": [
{"name": "utils.py", "extension": "py", "content": "..."}
]
}
```
**Assistant 消息:**
```json
{
"text": "AI 回复的文本内容",
"tool_calls": [...],
"steps": [
{"id": "step-0", "index": 0, "type": "thinking", "content": "..."},
{"id": "step-1", "index": 1, "type": "text", "content": "..."},
{"id": "step-2", "index": 2, "type": "tool_call", "id_ref": "call_xxx", "name": "...", "arguments": "..."},
{"id": "step-3", "index": 3, "type": "tool_result", "id_ref": "call_xxx", "name": "...", "content": "...", "success": true}
]
}
```
**steps 字段是渲染顺序的唯一数据源**,按 `index` 顺序排列。
## 数据流
### 消息处理流程
```mermaid
sequenceDiagram
participant Client
participant API as WebSocket/API
participant PS as ParticipantService
participant RS as ChatRoomService
participant LLM as LLM API
participant TE as ToolExecutor
Client->>API: send_message(content)
API->>PS: process_message()
PS->>RS: save_message()
PS->>RS: dispatch to agents
loop Agentic Loop
RS->>LLM: call(messages, tools)
LLM-->>RS: SSE Stream
alt tool_calls
RS->>TE: process_tool_calls_parallel()
TE-->>RS: tool_results
end
end
RS-->>PS: process_step events
PS-->>Client: SSE Stream
```
## WebSocket 事件
| 事件 | 说明 |
|------|------|
| `connected` | 连接成功 |
| `history` | 历史消息 |
| `agents` | 聊天室 Agent 列表 |
| `message` | 新消息 |
| `typing` | 打字状态 |
| `process_step` | Agent 处理步骤 |
| `done` | 处理完成 |
| `error` | 错误信息 |
| `system` | 系统消息 (join/leave) |
## 配置示例
### config.yaml
```yaml
app:
secret_key: ${APP_SECRET_KEY}
debug: true
host: 0.0.0.0
port: 8000
database:
type: sqlite
url: sqlite:///./chat.db
llm:
provider: deepseek
api_key: ${DEEPSEEK_API_KEY}
api_url: https://api.deepseek.com/v1
tools:
enable_cache: true
cache_ttl: 300
max_workers: 4
max_iterations: 10
```
## 环境变量
| 变量 | 说明 | 示例 |
|------|------|------|
| `APP_SECRET_KEY` | 应用密钥 | `your-secret-key` |
| `DEEPSEEK_API_KEY` | DeepSeek API | `sk-xxxx` |
| `DATABASE_URL` | 数据库连接 | `sqlite:///./chat.db` |