# 项目架构 ## 技术栈 - **框架**: 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 应用工厂 ├── run.py # 入口文件 ├── config.py # 配置管理(YAML) ├── database.py # 数据库连接 ├── models.py # ORM 模型 ├── routes/ # API 路由层 │ ├── auth.py # 认证 │ ├── conversations.py # 会话管理 │ ├── messages.py # 消息处理 │ ├── providers.py # LLM 提供商管理 │ └── tools.py # 工具管理 ├── services/ # 服务层 │ ├── chat.py # 聊天服务 │ └── llm_client.py # LLM 客户端 ├── tools/ # 工具系统 │ ├── core.py # 核心类 │ ├── factory.py # 装饰器 │ ├── executor.py # 执行器 │ └── builtin/ # 内置工具 │ ├── code.py # 代码执行 │ ├── crawler.py # 网页爬虫 │ ├── data.py # 数据处理 │ └── weather.py # 天气查询 │ └── services.py # 工具服务层 └── utils/ # 工具函数 └── helpers.py ``` ## 核心组件 ### 1. 应用工厂 (`__init__.py`) FastAPI 应用入口,使用 lifespan 管理生命周期: - 启动:初始化数据库、加载工具 - 关闭:清理资源 ### 2. 配置管理 (`config.py`) 使用 YAML 文件管理配置: - 配置文件:`config.yaml` - 环境变量替换:`${VAR_NAME}` - 单例模式全局访问 - 默认值支持 ```yaml # config.yaml 示例 app: secret_key: ${APP_SECRET_KEY} debug: true llm: provider: deepseek api_key: ${DEEPSEEK_API_KEY} ``` ### 3. 数据库 (`database.py`) - SQLAlchemy 异步支持 - SQLite 默认数据库 - 依赖注入获取会话 ### 4. ORM 模型 (`models.py`) ```mermaid erDiagram USER { int id PK string username UK string email UK string password_hash string role boolean is_active datetime created_at } CONVERSATION { string id PK int user_id FK string project_id FK string title string model text system_prompt float temperature int max_tokens boolean thinking_enabled datetime created_at datetime updated_at } MESSAGE { string id PK string conversation_id FK string role longtext content "JSON 格式" int token_count datetime created_at } USER ||--o{ CONVERSATION : "has" CONVERSATION ||--o{ MESSAGE : "has" USER ||--o{ LLM_PROVIDER : "configures" LLM_PROVIDER { int id PK int user_id FK string name string provider_type string base_url string api_key string default_model boolean is_default boolean enabled datetime created_at datetime updated_at } ``` ### 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": "..."} ] } ``` `steps` 字段是**渲染顺序的唯一数据源**,按 `index` 顺序排列。thinking、text、tool_call、tool_result 可以在多轮迭代中穿插出现。 ### 5. 工具系统 ```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 { +registry: ToolRegistry +enable_cache: bool +cache_ttl: int +_cache: Dict +process_tool_calls(tool_calls, context) list +process_tool_calls_parallel(tool_calls, context, max_workers) list } ``` #### 内置工具 | 工具 | 功能 | 说明 | |------|------|------| | `python_execute` | 执行 Python 代码 | 支持 print 输出、变量访问 | | `python_eval` | 计算表达式 | 快速求值 | | `web_search` | DuckDuckGo HTML | DuckDuckGo HTML 搜索 | | `web_fetch` | 网页抓取 | httpx + BeautifulSoup,支持 text/links/structured | | `batch_fetch` | 批量抓取 | 并发获取多个页面 | | `get_weather` | 天气查询 | 支持城市名查询 | | `process_data` | 数据处理 | JSON 转换、格式化等 | ### 6. 服务层 #### ChatService (`services/chat.py`) 核心聊天服务: - Agentic Loop 迭代执行 - 流式 SSE 响应 - 工具调用编排 - 消息历史管理 - 自动重试机制 #### LLMClient (`services/llm_client.py`) LLM API 客户端: - 多提供商:DeepSeek、GLM、OpenAI - 流式/同步调用 - 错误处理和重试 - Token 计数 ### 7. 认证系统 (`routes/auth.py`) - JWT Bearer Token - Bcrypt 密码哈希 - 用户注册/登录 ### 8. API 路由 | 路由 | 方法 | 说明 | |------|------|------| | `/auth/register` | POST | 用户注册 | | `/auth/login` | POST | 用户登录 | | `/conversations` | GET/POST | 会话列表/创建 | | `/conversations/{id}` | GET/DELETE | 会话详情/删除 | | `/messages/stream` | POST | 流式消息发送 | | `/providers` | GET/POST | LLM 提供商列表/创建 | | `/providers/{id}` | GET/PUT/DELETE | 提供商详情/更新/删除 | | `/providers/{id}/test` | POST | 测试提供商连接 | | `/tools` | GET | 可用工具列表 | ## 数据流 ### 消息处理流程 ```mermaid sequenceDiagram participant Client participant API as POST /messages/stream participant CS as ChatService participant LLM as LLM API participant TE as ToolExecutor Client->>API: POST {content, tools} API->>CS: stream_response() loop MAX_ITERATIONS CS->>LLM: call(messages, tools) LLM-->>CS: SSE Stream alt tool_calls CS->>TE: process_tool_calls_parallel() TE-->>CS: tool_results CS->>CS: 追加到 messages end end CS->>API: SSE Stream API-->>Client: 流式响应 ``` ## SSE 事件 | 事件 | 说明 | |------|------| | `process_step` | 结构化步骤(thinking/text/tool_call/tool_result),携带 `id`、`index` 确保渲染顺序 | | `done` | 响应完成 | | `error` | 错误信息 | ### process_step 事件格式 ```json {"type": "process_step", "step": {"id": "step-0", "index": 0, "type": "thinking", "content": "..."}} {"type": "process_step", "step": {"id": "step-1", "index": 1, "type": "text", "content": "回复文本..."}} {"type": "process_step", "step": {"id": "step-2", "index": 2, "type": "tool_call", "id_ref": "call_abc", "name": "web_search", "arguments": "{\"query\": \"...\"}"}} {"type": "process_step", "step": {"id": "step-3", "index": 3, "type": "tool_result", "id_ref": "call_abc", "name": "web_search", "content": "{\"success\": true, ...}"}} ``` | 字段 | 说明 | |------|------| | `id` | 步骤唯一标识(格式 `step-{index}`) | | `index` | 步骤序号,确保按正确顺序显示 | | `type` | 步骤类型:`thinking` / `text` / `tool_call` / `tool_result` | | `id_ref` | 工具调用引用 ID(仅 tool_call/tool_result) | | `name` | 工具名称(仅 tool_call/tool_result) | | `arguments` | 工具调用参数 JSON 字符串(仅 tool_call) | | `content` | 内容(thinking 的思考内容、text 的文本、tool_result 的返回结果) | ## 配置示例 ### 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` |