配置¶
文件位置与加载¶
flowchart TD
A["XUN_HOME,未设置则 ./.xun"] --> B["config.json"]
B --> C["与内置模板深合并"]
C --> D["替换 ${XUN_...} 占位符"]
D --> E["pydantic 校验"]
E --> F["Agent.config 取深拷贝"]
get_home_dir():XUN_HOME优先,否则当前工作目录下的.xun/。容器镜像内固定XUN_HOME=/.xun。- 同一目录下还有:
conversation/(历史)、extensions/(扩展)、x/xunx.db(xunx用户库)。 xunc/xunx建容器时从宿主 xun home 只拷HOME_COPY_INCLUDE(config.json、extensions)。xun_version()(包顶层导出)返回安装的发布版本,源码运行没有包元数据时返回None,扩展的版本门槛据此放行,见 扩展系统。- 读取入口
load_config(force_reload: bool = False) -> AgentConfig:进程内缓存;Agent.config默认是它的深拷贝,因此改单个智能体的配置不影响全局。 - 加载时会
load_dotenv(),密钥建议放.env。 - 没有写回 API:
config.json由用户手写;to_json()仅用于/config打印,/yolo与扩展里的改动只存在于内存。
结构与字段¶
所有配置模型都是 extra="forbid":写错字段名会直接报错,而不是被忽略。
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
auto_confirm |
bool |
${XUN_AUTO_CONFIRM},回落 false |
自动确认提示(选择取默认项,source="auto");不写入允许列表;ask_preference 工具会跳过自动确认,始终询问 |
enable_extensions |
bool |
true |
是否加载扩展;内部辅助智能体(风险评估、摘要)自行关闭 |
provider.openai_base_url |
str |
${XUN_OPENAI_BASE_URL} |
OpenAI 兼容端点,缺失即报错 |
provider.openai_api_key |
str |
${XUN_OPENAI_API_KEY} |
密钥,缺失即报错 |
model.name |
str |
${XUN_OPENAI_MODEL},回落 "" |
空串时在初始化阶段取 models.list() 第一项(多于一个会告警,一个都没有则报错) |
model.capabilities |
set["vision"] |
["vision"] |
取值域目前仅 vision(ModelCapabilityType),填别的值校验失败;用于过滤 required_capabilities 工具 |
model.temperature |
float \| None |
None |
None 时不下发该参数 |
model.reasoning_field |
str \| None |
None |
reasoning 或 reasoning_content;None 表示首见时自动探测并缓存 |
model.reasoning_effort |
"none"\|"minimal"\|"low"\|"medium"\|"high"\|"xhigh"\|"max" | None |
None |
部分模型只支持其中几档 |
auto_compact.enabled |
bool |
true |
自动压缩开关 |
auto_compact.token_threshold |
int |
192000 |
上一次模型调用的 token 超过该值即触发压缩 |
内置模板(配置文件按字段深合并覆盖它):
{
"auto_confirm": "${XUN_AUTO_CONFIRM}",
"enable_extensions": true,
"auto_compact": { "enabled": true, "token_threshold": 192000 },
"provider": {
"openai_base_url": "${XUN_OPENAI_BASE_URL}",
"openai_api_key": "${XUN_OPENAI_API_KEY}"
},
"model": { "name": "${XUN_OPENAI_MODEL}", "capabilities": ["vision"] }
}
占位符规则¶
- 占位符必须以
XUN_开头,否则RuntimeError: Invalid placeholder ...。 - 取值顺序:
os.environ→ 内置回落表(XUN_OPENAI_MODEL=""、XUN_AUTO_CONFIRM="false")→ 都没有则RuntimeError: Missing environment variable ...。 - 替换发生在 JSON 解析之前,替换结果永远是字符串,由 pydantic 宽松模式转成
bool/int。因此XUN_AUTO_CONFIRM=""(存在但为空)不会被回落值救回,会在校验阶段失败。
环境变量清单¶
| 变量 | 读取处 | 作用 |
|---|---|---|
XUN_HOME |
get_home_dir() |
配置/扩展/历史根目录;容器转发时被排除 |
XUN_OPENAI_BASE_URL |
配置模板 | 端点 |
XUN_OPENAI_API_KEY |
配置模板 | 密钥 |
XUN_OPENAI_MODEL |
配置模板 | 模型名,空则自动探测 |
XUN_AUTO_CONFIRM |
配置模板 | 自动确认 |
_XUN_DEFAULT_MAX_ITER |
agent.py |
execute() 的默认 max_iterations(内置 512) |
_XUN_INFO_TOOL_OVERRIDE |
toolbox.py |
打印工具覆盖/替换信息 |
XUN_* / _XUN_* |
容器入口 | xunc --env / xunx serve --env 总是转发的模式 |
以 _XUN_ 开头的是内部开关(get_internal_env() / get_internal_env_bool()),不是面向用户的配置项。
常见改法¶
{
"model": { "name": "my-model", "temperature": 0.2, "reasoning_effort": "low" },
"auto_compact": { "token_threshold": 64000 }
}
export XUN_OPENAI_BASE_URL=https://api.example.com/v1
export XUN_OPENAI_API_KEY=sk-...
export XUN_AUTO_CONFIRM=true
from xun import Agent
from xun.config import load_config
cfg = load_config().clone() # 读 config.json(含 .env)后深拷贝
cfg.model.name = "my-model"
cfg.auto_compact.enabled = False
agent = Agent(config=cfg)
# $XUN_HOME/extensions/use_weak_model.py
"""Pin a small model for every agent."""
from xun import ExtensionContext
def setup_extension(ctx: ExtensionContext) -> None:
ctx.agent.config.model.name = "small-model"
扩展在模型自动探测之前执行,所以这里的覆盖会生效。
提示词¶
系统提示词不是配置项,而是 src/xun/prompt.py 里的常量:主智能体用 get_system_prompt(),子智能体用 get_subagent_prompt();压缩另有专用模板(见 会话与自动压缩)。更换方式:
agent = setup_agent(default_system_prompt=False)
agent.system("You are a terse assistant. Answer in one sentence.")
system() 覆盖会话第 0 条消息,随时可再调用(摘要压缩也会重写这条消息)。压缩用的 AGENTS.md 约定同样来自提示词文本:框架要求智能体先查看并遵循工作目录下的 AGENTS.md——这是提示层约定,代码不会解析该文件。