Config 字段与配置¶
配置由 AgentConfig 描述,落盘在 $XUN_HOME/config.json。
每个智能体拿到的是全局配置的克隆,运行期改动只影响该智能体,也不会写回文件。
位置与加载¶
flowchart LR
T["内置模板<br/>带 ${XUN_*} 占位"] --> M["深度合并<br/>config.json"]
F["$XUN_HOME/config.json"] --> M
M --> S["环境变量替换"]
S --> C["AgentConfig"]
C --> A1["agent.config 克隆"]
C --> A2["子智能体克隆"]
XUN_HOME未设置时取./.xun,配置文件即./.xun/config.json。- 进程内只加载一次(
lru_cache),改过XUN_HOME需要load_config(force_reload=True)。 - 读文件前会调用
load_dotenv();默认不覆盖已有环境变量。 - 文件里只需要写想改的字段。字典递归合并,列表与标量整体替换——
例如只写
{"model": {"name": "x"}}时,model.capabilities仍是模板值,要清空必须写"capabilities": []。 - 所有模型都是
extra="forbid":写错字段名会在启动时报错,而不是静默忽略。 - 文件不存在时直接用模板,此时
XUN_OPENAI_BASE_URL与XUN_OPENAI_API_KEY必须存在于环境中。
环境变量占位¶
模板里的字符串是 string.Template,因此 ${XUN_OPENAI_API_KEY} 与 $XUN_OPENAI_API_KEY 都可用($$ 转义)。规则:
- 占位符标识符必须以
XUN_开头,否则启动即报错。 - 变量缺失时先查内置回退表,仍没有就报错:
| 变量 | 缺失时的回退 |
|---|---|
XUN_OPENAI_MODEL |
""(触发模型自动探测) |
XUN_AUTO_CONFIRM |
"false" |
XUN_ENABLE_EXTENSIONS |
"true" |
XUN_OPENAI_BASE_URL / XUN_OPENAI_API_KEY |
无回退,缺失即报错 |
- 替换发生在
json.loads之前,所以占位符可以出现在任意字符串位置(包括extension_settings里)。 反过来说,值里不要带引号、反斜杠或换行,否则会破坏 JSON。
内置映射一览:
| 环境变量 | 影响字段 |
|---|---|
XUN_OPENAI_BASE_URL |
provider.openai_base_url |
XUN_OPENAI_API_KEY |
provider.openai_api_key |
XUN_OPENAI_MODEL |
model.name |
XUN_AUTO_CONFIRM |
auto_confirm |
XUN_ENABLE_EXTENSIONS |
enable_extensions |
XUN_HOME |
配置与扩展、数据目录的根位置(不是配置字段) |
扩展也能用同一套机制
占位符替换作用于合并后的整段 JSON,扩展的配置桶里同样可以写 ${XUN_*},
密钥留在环境里而不是配置文件中。
字段表¶
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
auto_confirm |
bool | ${XUN_AUTO_CONFIRM} → false |
所有确认自动选默认项,不询问用户。/yolo 可运行时切换 |
auto_compact.enabled |
bool | true |
自动压缩的总开关 |
auto_compact.token_threshold |
int | 192000 |
触发压缩的 token 阈值,比较对象是最近一次模型调用报告的总量 |
provider.openai_base_url |
str | ${XUN_OPENAI_BASE_URL} |
OpenAI 兼容端点 |
provider.openai_api_key |
str | ${XUN_OPENAI_API_KEY} |
API 密钥 |
model.name |
str | ${XUN_OPENAI_MODEL} → "" |
模型名;解析结果为空串时在 initialize() 里从 models.list() 取第一个 |
model.capabilities |
set | ["vision"] |
能力门控,目前只有 "vision";决定带 required_capabilities 的工具是否暴露 |
model.temperature |
float | None | None |
None 时不出现在请求里 |
model.reasoning_field |
str | None | None |
推理文本的字段名;None 表示首次出现时自动探测(reasoning / reasoning_content) |
model.reasoning_effort |
str | None | None |
none / minimal / low / medium / high / xhigh / max,部分模型只接受其中一部分 |
enable_extensions |
bool | ${XUN_ENABLE_EXTENSIONS} → true |
是否在每个智能体初始化时运行扩展;内部辅助智能体自动关闭 |
load_project_instructions |
bool | true |
是否把工作目录下的 AGENTS.md 作为系统提示的独立段落加载 |
extension_settings |
dict[str, dict] | {} |
按扩展名分桶的配置,扩展通过 ctx.settings 读取 |
内部智能体会改自己的配置
会话摘要智能体会关掉 auto_compact 与 enable_extensions;命令风险评估智能体同样关掉扩展。
这些改动只发生在它们的克隆配置上。
运行期读写¶
print(agent.config.to_json_str()) # 缩进 4 的 JSON
agent.config.model.name = "my-model" # validate_assignment=True,写错类型当场报错
会话里对应 /config:不带参数打印当前配置,带 key.sub=value 修改单值(不写盘)。
load_config() 返回的是全局模板解析结果,排查单个智能体的真实配置请用 agent.config。
压缩阈值的实际行为¶
auto_compact.token_threshold 只决定「什么时候开始压」,具体策略在 AutoCompactor 上:
先回收旧工具结果(不花 API 调用),仍不够才让摘要智能体写一份摘要塞进系统提示。
可调参数(toolcall_keep_max=12、summary_keep_max=16、escalation_rounds=2、max_retries=2)
是 AutoCompactor 的字段,不在配置文件里,需要时替换 agent.compactor。
不在配置里的东西¶
以下几项常被误认为配置字段:
- 最大迭代次数:
execute(max_iterations=…)的参数,默认 512。 - 重试与超时:写死在循环里(最多 3 次重试、指数退避、流式 900 秒超时)。
- 显示层与 Web 服务参数:
Display/WebDisplay/WebDisplayService构造参数与 CLI 参数。 - 命令与路径允许列表:当前智能体的运行时状态,用
/policy管理。 - 容器与多用户:
xunc/xunx的命令行参数。