第 20 章:配置的秘密

个人公众号
1
2
卷四:纵深
[20] 配置的秘密 <- you are here

前几章我们见过很多配置——AgentConfig、SecurityConfig、ToolsConfig。这一章深入配置系统本身:配置怎么加载?环境变量怎么覆盖?旧配置怎么升级?两层数据(config.json + agent.json)是怎么分工的?


问题

~/.qwenpaw/ 下有 config.json,每个工作区又有 agent.json。环境变量 QWENPAW_* 能覆盖配置。旧版本用 ~/.copaw 路径。这些层级怎么协调?优先级是什么?

配置的两层架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
~/.qwenpaw/
config.json # 根配置(全局)
agents.profiles: # Agent 轻量引用
default:
id, workspace_dir, enabled
channels: {...} # 全局渠道配置
security: {...} # 全局安全配置
tools: {...} # 全局工具配置

workspaces/default/
agent.json # Agent 完整配置(局部)
id, name, workspace_dir
channels, security, tools # 可覆盖全局配置
running, llm_routing # 运行时参数
system_prompt_files # 提示词文件列表

根配置存”有哪些 Agent、全局默认值”。Agent 配置存”这个 Agent 的完整设置”。加载时先读根配置找到工作区路径,再读 agent.json 获取完整配置。

配置加载链

load_config() 的完整流程:

1
2
3
4
5
6
7
8
9
1. 解析路径:get_config_path() -> ~/.qwenpaw/config.json
2. 读取文件:json_repair.repair_json() 自动修复常见问题
- 尾部逗号、缺少引号、BOM 标记
- 修复失败创建 .bak 备份
3. 路径规范化:~/.copaw -> ~/.qwenpaw
4. 向后兼容:last_api_host -> last_api.host
5. Pydantic 验证:Config.model_validate(data)
- 验证失败:尝试移除坏字段,重试一次
- 最终降级:返回 Config() 默认值

load_agent_config() 的流程:

1
2
3
4
1. 从根配置找 workspace_dir
2. 读 <workspace>/agent.json
3. 不存在?从根配置字段构建默认值并保存
4. 路径规范化

30+ 个环境变量覆盖

EnvVarLoaderconstant.py 中定义,每个环境变量都有 QWENPAW_* 和旧版 COPAW_* 两个名字:

环境变量默认值用途
QWENPAW_WORKING_DIR~/.qwenpaw数据目录
QWENPAW_SECRET_DIR~/.qwenpaw.secret密钥目录
QWENPAW_LLM_MAX_RETRIES3LLM 重试次数
QWENPAW_LLM_MAX_CONCURRENT10LLM 并发上限
QWENPAW_LLM_MAX_QPM600每分钟请求上限
QWENPAW_MEMORY_COMPACT_RATIO0.75记忆压缩触发阈值
QWENPAW_TOOL_GUARD_ENABLEDTrue安全守卫开关
QWENPAW_ENABLED_CHANNELS“”白名单渠道
QWENPAW_DISABLED_CHANNELS“”黑名单渠道

环境变量优先级最高——覆盖 config.json 中的值。

envs 模块——持久化的环境变量

envs/store.py 提供了两层持久化:

1
2
第一层:envs.json(磁盘,Fernet 加密)
第二层:os.environ(进程内)

用户通过 Web UI 设置的环境变量会被加密存储到 SECRET_DIR/envs.json。启动时 load_envs_into_environ() 读取并注入进程。受保护的键(QWENPAW_WORKING_DIR)不会被覆盖。

配置迁移——从旧版升级

应用启动时执行 4 步迁移:

1
2
3
4
1. load_envs_into_environ()       # 注入持久化环境变量
2. migrate_legacy_workspace() # ~/.copaw -> ~/.qwenpaw
3. ensure_default_agent_exists() # 创建默认 Agent
4. migrate_legacy_skills() # active_skills/ -> skill_pool/

迁移是幂等的——已经迁移过的不重复执行。路径规范化把所有 ~/.copaw 引用改成 ~/.qwenpaw

实验的工程权衡

为什么用 JSON 而非 YAML?

JSON 是 Python 标准库原生支持。QwenPaw 的配置主要由程序管理(Web UI),用户很少手动编辑。json_repair 库提供了一定的容错能力。

为什么分两层(config.json + agent.json)?

多 Agent 场景下,根配置只需要知道”有哪些 Agent”。完整配置按 Agent 分开存储,避免单个文件过大。新增 Agent 不需要修改根配置——只需添加一个 AgentProfileRef 和一个 agent.json

自检

  • 知道配置分两层:根 config.json + 工作区 agent.json
  • 知道环境变量 QWENPAW_* 优先级最高
  • 知道 envs.json 用 Fernet 加密存储敏感环境变量
  • 知道启动时有 4 步迁移逻辑

下一章我们看记忆的宫殿——Agent 怎么记住上下文,记忆压缩怎么工作。