27 KiB
27 KiB
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)
├── database.py # 数据库连接
├── models.py # ORM 模型
├── routes/ # API 路由层
│ ├── __init__.py # 路由聚合
│ ├── auth.py # 认证 (登录/注册)
│ ├── agents.py # Agent 模板管理 (CRUD)
│ ├── chat_rooms.py # 聊天室管理 (多 Agent 协作)
│ ├── conversations.py # 会话管理 (CRUD)
│ ├── messages.py # 消息处理 (流式/同步)
│ ├── providers.py # LLM 提供商管理
│ ├── agents.py # Agent 模板管理 (CRUD)
│ └── tools.py # 工具管理
├── services/ # 服务层
│ ├── __init__.py # 服务导出
│ ├── chat.py # 聊天服务门面
│ ├── chat_room.py # 多 Agent 聊天室编排器
│ ├── agentic_loop.py # Agentic Loop 执行器
│ ├── stream_context.py # 流式状态管理
│ ├── events.py # SSE 事件工具
│ ├── llm_response.py # LLM 响应数据类
│ ├── task.py # 任务系统 (Task/TaskGraph/TaskService)
│ ├── llm_client.py # LLM 客户端
│ └── llm_adapters/ # LLM API 适配器
│ ├── __init__.py # 适配器导出
│ ├── base.py # ProviderAdapter 基类
│ ├── openai_adapter.py # OpenAI/DeepSeek/GLM 适配器
│ └── anthropic_adapter.py # Anthropic Claude 适配器
├── tools/ # 工具系统
│ ├── __init__.py # 工具注册入口
│ ├── core.py # 核心类 (ToolRegistry, ToolDefinition, ToolResult, ToolContext)
│ ├── factory.py # @tool 装饰器
│ ├── executor.py # 工具执行器 (缓存/并行)
│ ├── services.py # 工具服务层
│ └── builtin/ # 内置工具
│ ├── __init__.py # 工具注册入口
│ ├── code.py # 代码执行 (python_execute, python_eval)
│ ├── crawler.py # 网页爬虫 (web_search, web_fetch, batch_fetch)
│ ├── data.py # 数据处理 (process_data)
│ ├── file.py # 文件操作 (file_read, file_write, file_list, file_exists, file_grep)
│ └── shell.py # Shell 命令 (shell_execute)
└── utils/ # 工具函数
├── __init__.py
└── helpers.py # 密码哈希、ID生成、响应封装
run.py # 应用入口文件
config.yaml # 配置文件
核心组件
1. 应用工厂 (__init__.py)
FastAPI 应用入口,使用 lifespan 管理生命周期:
- 启动:初始化数据库、注册内置工具、创建默认管理员用户
- 关闭:清理资源
# 默认管理员账号
username: admin
password: admin123
2. 配置管理 (config.py)
使用 YAML 文件管理配置:
- 配置文件:
config.yaml - 环境变量替换:
${VAR_NAME} - 单例模式全局访问
- 默认值支持
# config.yaml 示例
app:
secret_key: ${APP_SECRET_KEY}
debug: true
host: 0.0.0.0
port: 8000
database:
type: sqlite
url: sqlite:///./chat.db
workspace:
root: ./workspaces # 用户工作空间根目录
auto_create: true # 自动创建用户目录
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
logging:
level: INFO
工作空间隔离机制:
- 每个用户的工作空间路径基于
user_id的 SHA256 哈希值 - 格式:
{workspace_root}/{hash_of_user_id} - 所有文件操作必须在用户工作空间内,防止路径穿越攻击
### 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
int permission_level "1=READ_ONLY, 2=WRITE, 3=EXECUTE, 4=ADMIN"
string workspace_path "用户工作空间路径"
boolean is_active
datetime created_at
}
USER_SETTINGS {
int id PK
int user_id FK UK
int default_provider_id FK "optional"
float temperature
int max_tokens
boolean thinking_enabled
text system_prompt
datetime created_at
datetime updated_at
}
PROJECT {
string id PK
int user_id FK
string name
text description
datetime created_at
datetime updated_at
}
CONVERSATION {
string id PK
int user_id FK
int provider_id FK "optional"
string project_id FK "optional"
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 "optional"
string room_id FK "optional"
string role
longtext content "JSON 格式"
int token_count
text usage "JSON 格式"
string sender_name "聊天室: 发送者名称"
string sender_color "聊天室: 发送者颜色"
int round_number "聊天室: 轮次编号"
datetime created_at
}
LLM_PROVIDER {
int id PK
int user_id FK
string name
string provider_type
string base_url
string api_key
string default_model
int max_tokens
boolean is_default
boolean enabled
datetime created_at
datetime updated_at
}
AGENT {
int id PK
int user_id FK
string name
string role
int provider_id FK "optional"
string model
text system_prompt
string color
datetime created_at
datetime updated_at
}
CHAT_ROOM {
string id PK
int user_id FK
string title
text task
string status "idle/running/paused/completed/error"
int max_rounds
int current_round
datetime created_at
datetime updated_at
}
ROOM_AGENT {
int id PK
string room_id FK
int agent_id FK "optional"
string name
string role
int provider_id FK "optional"
string model
text system_prompt
string color
int turn_order
}
USER ||--|| USER_SETTINGS : "has"
USER ||--o{ PROJECT : "has"
USER ||--o{ CONVERSATION : "has"
USER ||--o{ LLM_PROVIDER : "configures"
USER ||--o{ AGENT : "creates"
USER ||--o{ CHAT_ROOM : "creates"
PROJECT ||--o{ CONVERSATION : "contains"
LLM_PROVIDER ||--o{ CONVERSATION : "uses"
LLM_PROVIDER ||--o{ AGENT : "used_by"
LLM_PROVIDER ||--o{ ROOM_AGENT : "used_by"
CONVERSATION ||--o{ MESSAGE : "has"
CHAT_ROOM ||--o{ MESSAGE : "has"
CHAT_ROOM ||--o{ ROOM_AGENT : "contains"
AGENT ||--o{ ROOM_AGENT : "linked_to"
用户权限级别 (permission_level):
| 级别 | 名称 | 说明 |
|---|---|---|
| 1 | READ_ONLY | 只读权限 |
| 2 | WRITE | 写入权限(文件写入) |
| 3 | EXECUTE | 执行权限(代码执行、Shell命令) |
| 4 | ADMIN | 管理员权限 |
Message Content JSON 结构
content 字段统一使用 JSON 格式存储:
User 消息:
{
"text": "用户输入的文本内容",
"attachments": [
{"name": "utils.py", "extension": "py", "content": "..."}
]
}
Assistant 消息:
{
"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 顺序排列。thinking、text、tool_call、tool_result 可以在多轮迭代中穿插出现。
注意:text 和 content 字段通过解析 steps 中所有 type: "text" 的内容动态计算得出。
5. 工具系统
classDiagram
class ToolDefinition {
+str name
+str description
+dict parameters
+Callable handler
+str category
+CommandPermission required_permission
+to_openai_format() dict
}
class ToolContext {
+int user_id
+str username
+str workspace
+int user_permission_level
}
class CommandPermission {
<<enumeration>>
READ_ONLY = 1
WRITE = 2
EXECUTE = 3
ADMIN = 4
}
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~
+list_by_category(category) List~dict~
+execute(name, arguments, context) dict
+remove(name) bool
}
class ToolExecutor {
+enable_cache: bool
+cache_ttl: int
+max_workers: int
+_cache: Dict
+_call_history: List
+process_tool_calls(tool_calls, context) list
+process_tool_calls_parallel(tool_calls, context) list
+clear_cache() void
+get_history(limit) List
}
内置工具
代码执行 (code.py)
| 工具 | 功能 | 权限 |
|---|---|---|
python_execute |
执行 Python 代码 | EXECUTE |
python_eval |
计算表达式 | EXECUTE |
文件操作 (file.py)
| 工具 | 功能 | 权限 |
|---|---|---|
file_read |
读取文件内容 | READ_ONLY |
file_write |
写入文件内容 | WRITE |
file_list |
列出目录内容 | READ_ONLY |
file_exists |
检查文件是否存在 | READ_ONLY |
file_grep |
正则搜索文件内容 | READ_ONLY |
Shell 命令 (shell.py)
| 工具 | 功能 | 权限 |
|---|---|---|
shell_execute |
执行 Shell 命令 | EXECUTE |
网页爬虫 (crawler.py)
| 工具 | 功能 | 权限 |
|---|---|---|
web_search |
DuckDuckGo HTML 搜索 | READ_ONLY |
web_fetch |
网页抓取 | READ_ONLY |
batch_fetch |
批量并发抓取 | READ_ONLY |
数据处理 (data.py)
| 工具 | 功能 | 权限 |
|---|---|---|
process_data |
JSON 转换、格式化 | READ_ONLY |
权限检查机制
工具执行时自动检查用户权限:
工具要求的权限 <= 用户拥有的权限 → 允许执行
工具要求的权限 > 用户拥有的权限 → 拒绝执行
工具开发规范
所有工具必须遵循统一的开发规范,确保错误处理和返回格式一致。
核心原则:装饰器自动处理一切,工具函数只写业务逻辑
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")
装饰器自动处理:
- 必需参数验证(
required_params) - 所有异常捕获和转换
- 结果格式统一包装
返回格式转换
| 工具函数返回/抛出 | 装饰器转换为 |
|---|---|
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": "..."} |
工具调用流程
LLM 请求
↓
ToolRegistry.execute(name, args)
↓
@tool 装饰器
├─ 验证 required_params
├─ 执行工具函数 (try-except 包裹)
├─ 捕获异常 → 转换为 error
├─ 包装返回格式
└─ 返回 ToolResult
↓
ToolExecutor 返回结果
↓
前端 ProcessBlock 显示
6. 服务层
LLM 适配器 (services/llm_adapters/)
适配器模式统一处理不同 LLM API 格式:
classDiagram
class ProviderAdapter {
<<abstract>>
+str provider_type
+build_request() tuple
+parse_stream_chunk() AsyncGenerator
+parse_response() Dict
+supports_thinking() bool
+supports_tools() bool
}
class OpenAIAdapter {
+str provider_type = "openai"
+build_request() tuple
+parse_stream_chunk() AsyncGenerator
+parse_response() Dict
+supports_tools() bool
}
class AnthropicAdapter {
+str provider_type = "anthropic"
+build_request() tuple
+parse_stream_chunk() AsyncGenerator
+parse_response() Dict
+supports_thinking() bool
+supports_tools() bool
}
ProviderAdapter <|-- OpenAIAdapter
ProviderAdapter <|-- AnthropicAdapter
支持的功能对比:
| 适配器 | 工具调用 | Thinking/Reasoning | 流式响应 |
|---|---|---|---|
| OpenAI | ✅ | ✅ (DeepSeek) | ✅ |
| Anthropic | ✅ | ✅ | ✅ |
LLM 响应数据类 (services/llm_response.py)
class StepType:
"""步骤类型常量"""
THINKING = "thinking"
TEXT = "text"
TOOL_CALL = "tool_call"
TOOL_RESULT = "tool_result"
@dataclass
class Step:
"""单个步骤 - 用于存储和传输"""
id: str
index: int
type: str # thinking, text, tool_call, tool_result
content: str = ""
name: str = "" # tool_call/tool_result
arguments: str = "" # tool_call
id_ref: str = "" # tool_result
success: bool = True
@dataclass
class ParsedDelta:
"""LLM 流式响应增量"""
thinking: str = "" # 思考内容(增量)
text: str = "" # 文本内容(增量)
tool_call: Optional[Dict] = None # 单个工具调用
usage: Dict[str, int] = {} # Token 用量
is_complete: bool = False
ChatService (services/chat.py)
核心聊天服务:
- Agentic Loop 迭代执行(最多 10 轮)
- 流式 SSE 响应
- 工具调用编排(并行执行)
- 消息历史管理
- Token 用量追踪
- 工作空间上下文传递
AgenticLoop (services/agentic_loop.py)
执行 Agentic Loop 的核心循环:
- 调用 LLM 获取响应(流式)
- 解析 ParsedDelta,更新步骤状态
- 管理 thinking/text/tool_call/tool_result 步骤
- 工具并行执行
- 最大迭代次数:10
# 执行流程
async for delta in llm.stream_call(...):
events = self._process_delta(delta, context, total_usage)
yield from events
# 工具调用时
tool_results = self.tool_executor.process_tool_calls_parallel(...)
messages.append({"role": "assistant", ...})
messages.extend(tool_results)
StreamContext (services/stream_context.py)
流式状态管理:
- 追踪当前步骤类型和索引
- 累积 thinking 和 text 内容
- 管理 tool_calls 列表和 tool_results
- 生成 SSE 事件
- 构建完整消息内容
LLMClient (services/llm_client.py)
LLM API 客户端:
- 多提供商:OpenAI、DeepSeek、Anthropic
- 自动适配器选择
- 流式/同步调用
- 错误处理和重试
- Token 计数
7. 任务系统 (services/task.py)
用于自主任务执行和依赖管理:
classDiagram
class Task {
+str id
+str name
+str goal
+TaskStatus status
+List~Step~ steps
+List~Task~ subtasks
}
class Step {
+str id
+str name
+List~str~ depends_on
+StepStatus status
}
class TaskGraph {
+topological_sort() List~Step~
+get_ready_steps() List~Step~
+detect_cycles() List~List~str~~
+validate() tuple
}
class TaskService {
+create_task() Task
+get_task() Task
+update_task_status() Task
+add_steps() List~Step~
+build_graph() TaskGraph
}
Task "1" o-- "*" Step
Task "1" o-- "*" Task
TaskService ..> TaskGraph
任务状态 (TaskStatus):
PENDING- 待处理READY- 就绪RUNNING- 运行中BLOCK- 阻塞TERMINATED- 已终止
步骤状态 (StepStatus):
PENDING- 待执行RUNNING- 执行中COMPLETED- 已完成FAILED- 失败SKIPPED- 跳过
7. 认证系统 (routes/auth.py)
- JWT Bearer Token
- Bcrypt 密码哈希
- 用户注册/登录
8. Agent 系统 (routes/agents.py, models.py)
Agent 是独立的可复用 AI 助手模板,可以在聊天室中使用:
classDiagram
class Agent {
+int id
+int user_id
+str name
+str role
+int provider_id
+str model
+str system_prompt
+str color
+to_dict() dict
}
class LLMProvider {
+int id
+str name
+str api_key
+str default_model
}
Agent --> LLMProvider : uses
Agent 字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
id |
int | Agent 唯一标识 |
user_id |
int | 所属用户 ID |
name |
string | Agent 显示名称 |
role |
string | Agent 角色描述(如"后端开发") |
provider_id |
int | 使用的 LLM 提供商 |
model |
string | 模型名称 |
system_prompt |
string | 系统提示词 |
color |
string | 显示颜色(Hex) |
9. 聊天室系统 (routes/chat_rooms.py, services/chat_room.py)
聊天室支持多个 Agent 同时参与讨论,协作完成复杂任务:
classDiagram
class ChatRoom {
+str id
+int user_id
+str title
+str task
+str status
+int max_rounds
+int current_round
+List~RoomAgent~ agents
}
class RoomAgent {
+int id
+str room_id
+int agent_id
+str name
+str role
+str model
+str system_prompt
+str color
+int turn_order
}
class ChatRoomOrchestrator {
-Dict~str, Task~ _running_rooms
+is_running(room_id) bool
+cancel(room_id) void
+run_room(room_id) AsyncGenerator
}
ChatRoom "1" o-- "*" RoomAgent : contains
ChatRoomOrchestrator ..> ChatRoom : orchestrates
ChatRoomOrchestrator ..> RoomAgent : executes
聊天室状态:
| 状态 | 说明 |
|---|---|
idle |
空闲,未开始 |
running |
运行中 |
paused |
已暂停(被手动停止) |
completed |
已完成(达到最大轮次) |
error |
错误(执行出错) |
聊天室执行流程:
1. 用户调用 /chat-rooms/{id}/start
2. ChatRoomOrchestrator.run_room() 被调用
3. 按 turn_order 顺序执行每个 Agent 的发言轮次
4. 每个 Agent 根据历史消息和系统提示生成回复
5. SSE 流式推送消息块 (message_chunk)
6. 消息结束时推送 message_end
7. 一轮结束后推送 round_end
8. 达到 max_rounds 或被停止时结束
SSE 事件流:
room_started → round_start → (message_start → message_chunk* → message_end → message) × N_agents
→ round_end → (重复下一轮) → room_completed
10. API 路由
| 路由 | 方法 | 说明 |
|---|---|---|
/auth/register |
POST | 用户注册 |
/auth/login |
POST | 用户登录 |
/auth/logout |
POST | 用户登出 |
/auth/me |
GET | 当前用户信息 |
/auth/users |
GET | 用户列表(管理员) |
/auth/users/{user_id} |
PUT | 更新用户权限 |
/conversations |
GET | 会话列表(分页) |
/conversations |
POST | 创建会话 |
/conversations/{id} |
GET | 会话详情 |
/conversations/{id} |
PUT | 更新会话 |
/conversations/{id} |
DELETE | 删除会话 |
/messages |
GET | 消息列表 |
/messages |
POST | 发送消息(同步) |
/messages/stream |
POST | 发送消息(流式 SSE) |
/messages/{id} |
DELETE | 删除消息 |
/providers |
GET | LLM 提供商列表 |
/providers |
POST | 创建提供商 |
/providers/{id} |
GET | 提供商详情 |
/providers/{id} |
PUT | 更新提供商 |
/providers/{id} |
DELETE | 删除提供商 |
/providers/{id}/test |
POST | 测试提供商连接 |
/agents |
GET | Agent 列表 |
/agents |
POST | 创建 Agent |
/agents/{id} |
GET | Agent 详情 |
/agents/{id} |
PUT | 更新 Agent |
/agents/{id} |
DELETE | 删除 Agent |
/chat-rooms |
GET | 聊天室列表 |
/chat-rooms |
POST | 创建聊天室 |
/chat-rooms/{id} |
GET | 聊天室详情 |
/chat-rooms/{id} |
PUT | 更新聊天室 |
/chat-rooms/{id} |
DELETE | 删除聊天室 |
/chat-rooms/{id}/start |
POST | 启动聊天室 |
/chat-rooms/{id}/stop |
POST | 停止聊天室 |
/chat-rooms/{id}/reset |
POST | 重置聊天室 |
/chat-rooms/{id}/messages |
GET | 聊天室消息 |
/chat-rooms/{id}/agents |
POST | 添加 Agent |
/chat-rooms/{id}/agents/{agent_id} |
PUT | 更新 Agent |
/chat-rooms/{id}/agents/{agent_id} |
DELETE | 移除 Agent |
/tools |
GET | 可用工具列表 |
/tools/{name} |
GET | 工具详情 |
/tools/{name}/execute |
POST | 执行工具 |
/health |
GET | 健康检查 |
/ |
GET | 服务信息 |
数据流
消息处理流程
sequenceDiagram
participant Client
participant API as POST /messages/stream
participant CS as ChatService
participant AL as AgenticLoop
participant Parser as LLMResponseParser
participant LLM as LLM API
participant TE as ToolExecutor
Client->>API: POST {content, tools, thinking_enabled}
API->>CS: stream_response()
CS->>AL: execute()
loop MAX_ITERATIONS (10)
AL->>LLM: stream_call(messages, tools)
LLM-->>AL: SSE Stream
AL->>Parser: parse_chunk()
Parser-->>AL: ParsedDelta {thinking, text, tool_calls}
alt tool_calls
AL->>TE: process_tool_calls_parallel()
TE-->>AL: tool_results
AL->>AL: 追加到 messages
end
end
AL->>CS: done event
CS->>CS: _save_message()
CS->>API: SSE Stream
API-->>Client: 流式响应
SSE 事件
普通会话 SSE 事件
| 事件 | 说明 |
|---|---|
process_step |
结构化步骤(thinking/text/tool_call/tool_result),携带 id、index 确保渲染顺序 |
done |
响应完成,携带 message_id、token_count、usage |
error |
错误信息 |
聊天室 SSE 事件
| 事件 | 说明 |
|---|---|
room_started |
聊天室启动,携带 room_id 和 task |
round_start |
回合开始,携带 round 和 max_rounds |
message_start |
消息开始,携带 msg_id、sender_name、sender_color、round_number |
message_chunk |
消息内容增量,携带 content 和 accumulated |
message_end |
消息结束,携带 msg_id、content、token_count |
message |
完整消息(用于存储和显示) |
round_end |
回合结束 |
room_completed |
聊天室完成 |
room_paused |
聊天室暂停 |
agent_error |
Agent 执行错误 |
error |
通用错误 |
process_step 事件格式
{"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 的返回结果) |
success |
工具执行是否成功(仅 tool_result) |
done 事件格式
{"type": "done", "message_id": "uuid", "token_count": 1234, "usage": {"prompt_tokens": 100, "completion_tokens": 200, "total_tokens": 300}}
配置示例
config.yaml
app:
secret_key: ${APP_SECRET_KEY}
debug: true
host: 0.0.0.0
port: 8000
database:
type: sqlite
url: sqlite:///./chat.db
workspace:
root: ./workspaces # 用户工作空间根目录
auto_create: true # 自动创建用户工作空间
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
logging:
level: INFO
环境变量
| 变量 | 说明 | 示例 |
|---|---|---|
APP_SECRET_KEY |
应用密钥 | your-secret-key |
DEEPSEEK_API_KEY |
DeepSeek API | sk-xxxx |
DATABASE_URL |
数据库连接 | sqlite:///./chat.db |
LLM 适配器配置
OpenAI 兼容 (DeepSeek/GLM 等)
llm:
provider: openai
api_key: ${API_KEY}
api_url: https://api.deepseek.com/v1 # 或其他兼容端点
Anthropic Claude
llm:
provider: anthropic
api_key: ${ANTHROPIC_API_KEY}
api_url: https://api.anthropic.com/v1
项目结构说明
入口文件
run.py- 启动 Uvicorn 服务器
响应格式
所有 API 统一使用响应封装:
// 成功
{"success": true, "data": {...}, "message": "操作成功"}
// 错误
{"success": false, "error": "错误信息", "code": 404}
工具缓存机制
ToolExecutor 支持结果缓存:
- TTL: 5 分钟(可配置)
- 缓存 Key:
{tool_name}:{sorted_arguments_json} - 调用历史记录最近 1000 条
流式响应特点
- 实时返回 thinking_content(模型思考过程)
- 实时返回 text 增量更新
- 工具调用并行执行,结果批量返回
- 最终
done事件包含完整 message_id 和 token 用量
工作空间隔离
每个用户的工作空间完全隔离:
- 用户目录基于 user_id 的 SHA256 哈希生成
- 所有文件操作强制在用户工作空间内
- 支持权限级别控制文件操作能力
MessageBuilder
用于构建发送给 LLM 的消息列表:
add_system()- 添加系统消息add_user()- 添加用户消息(JSON 格式)add_assistant()- 添加助手消息add_tool_result()- 添加工具结果消息extract_text()- 从 JSON 内容中提取文本