03 配置系统
第二层:配置系统
📌 核心文件:
nanobot/config/schema.py- 配置数据模型nanobot/config/loader.py- 配置加载器
概述
nanobot 使用基于 Pydantic 的配置系统,特点:
- 单一 JSON 配置文件(
~/.nanobot/config.json) - 类型安全的配置模型
- 自动验证配置正确性
- 支持嵌套配置结构
配置模型定义
完整的配置结构
from pydantic import BaseModel, Field
from typing import Dict, Optional
class ProviderConfig(BaseModel):
"""单个提供商配置"""
apiKey: str
apiBase: Optional[str] = None
class AgentDefaults(BaseModel):
"""Agent 默认设置"""
model: str = "anthropic/claude-opus-4-5"
maxIterations: int = 20
class TelegramConfig(BaseModel):
"""Telegram 配置"""
enabled: bool = False
token: Optional[str] = None
allowFrom: list[str] = Field(default_factory=list)
class WhatsAppConfig(BaseModel):
"""WhatsApp 配置"""
enabled: bool = False
allowFrom: list[str] = Field(default_factory=list)
class WebSearchConfig(BaseModel):
"""Web 搜索配置"""
apiKey: Optional[str] = None
class Config(BaseModel):
"""根配置模型"""
providers: Dict[str, ProviderConfig] = Field(default_factory=dict)
agents: AgentDefaults = Field(default_factory=AgentDefaults)
channels: ChannelsConfig = Field(default_factory=ChannelsConfig)
tools: ToolsConfig = Field(default_factory=ToolsConfig)
配置示例
{
"providers": {
"openrouter": {
"apiKey": "sk-or-v1-xxx",
"apiBase": null
},
"groq": {
"apiKey": "gsk_xxx"
}
},
"agents": {
"defaults": {
"model": "anthropic/claude-opus-4-5",
"maxIterations": 20
}
},
"channels": {
"telegram": {
"enabled": true,
"token": "123456:ABC...",
"allowFrom": ["123456789"]
},
"whatsapp": {
"enabled": false,
"allowFrom": []
}
},
"tools": {
"web": {
"search": {
"apiKey": "BSA-xxx"
}
}
}
}
配置加载器
class ConfigLoader:
"""配置加载器"""
def __init__(self, config_path: Path | None = None):
self.config_path = config_path or (Path.home() / ".nanobot" / "config.json")
def load(self) -> Config:
"""加载并验证配置"""
if not self.config_path.exists():
raise FileNotFoundError(f"Config not found: {self.config_path}")
# 读取 JSON
data = json.loads(self.config_path.read_text())
# Pydantic 自动验证
try:
config = Config(**data)
return config
except ValidationError as e:
logger.error(f"Config validation failed: {e}")
raise
def save(self, config: Config):
"""保存配置"""
self.config_path.write_text(
config.model_dump_json(indent=2, exclude_none=True)
)
配置验证
Pydantic 自动验证数据类型和约束:
# ❌ 错误的配置
{
"agents": {
"defaults": {
"maxIterations": "twenty" # 应该是整数
}
}
}
# 抛出 ValidationError:
# validation error for Config
# agents -> defaults -> maxIterations
# value is not a valid integer
环境变量支持
虽然当前实现不直接支持环境变量,但可以轻松扩展:
class ProviderConfig(BaseModel):
apiKey: str
@field_validator('apiKey')
def resolve_env_var(cls, v):
"""支持 ${ENV_VAR} 语法"""
if v.startswith("${") and v.endswith("}"):
env_var = v[2:-1]
return os.getenv(env_var, "")
return v
配置访问模式
# 加载配置
config = ConfigLoader().load()
# 访问配置
model = config.agents.defaults.model
api_key = config.providers.get("openrouter").apiKey
telegram_enabled = config.channels.telegram.enabled
# 修改配置
config.agents.defaults.model = "anthropic/claude-sonnet-4-5"
ConfigLoader().save(config)
小结
- ✅ 基于 Pydantic 的类型安全配置
- ✅ 单一 JSON 文件,简单直观
- ✅ 自动验证,防止错误配置
下一步:04-消息总线.md