背景
PR #128 通过 ACP initialize 的 _meta 字段传入 locale,实现了 i18n。功能方向正确,但字段设计需要讨论。
需要讨论的几个问题
1. 约定合适的字段
ACP 协议(v1)的 initialize 请求结构中没有任何多语言/locale 相关字段。协议层面的字段只有:protocolVersion、clientCapabilities(fs/terminal/elicitation/configOptions)、clientInfo(name/title/version)、_meta(扩展点)。
_meta 是 ACP 协议中 AnnotatedObject 的扩展点(field_meta),设计用途就是传递实现特定的附加信息。ACP 官方文档也确认,自定义能力可以通过 _meta 字段广告扩展支持。协议层面没有其他字段可以用来传 locale。
建议 :继续用 _meta,但约定一个明确的 key 和文档:
"_meta" : { "locale" : " zh-CN" }
key 就叫 locale,值为 BCP 47 语言标签(en、zh-CN、ja-JP)
在 ACP initialize response 中可以回传支持的 locale 列表,让客户端知道服务端支持哪些语言
在代码中用结构化的方式提取(一个 _extract_locale() 函数),而不是散落在各处
2. 配置如何通过 initialize 生效
PR #128 的链路是对的:
client initialize (_meta.locale)
→ AgentPoolACPAgent.initialize() 提取 locale
→ 透传到 ACPSessionManager.create_session() / resume_session()
→ ACPSession.client_locale
→ 注入 callable system prompt
这个链路保持不变。唯一要确认的是:locale 应该是 per-connection (initialize 时设定,整个连接生效)还是 per-session (new_session 时可以覆盖)?
建议 :per-connection 为主(简单),后续如果需要 per-session 覆盖再加。
3. 环境变量控制的必要性
结论:不需要环境变量。
理由:
locale 是客户端偏好,客户端切换语言后通过 initialize 通知即可,不需要服务端环境变量
环境变量适合"服务端默认值"场景(见下),但不应作为客户端偏好的传递通道
如果客户端没传 locale,应该走服务端默认配置(YAML),而不是环境变量
4. agentpool ACP 服务如何配置默认语言
当客户端没有在 initialize 中传 locale 时,agentpool 应该有一个默认值。这个默认值应该在 YAML 配置中设定。
建议 :在 ACP server 配置或 agent 配置中加 default_locale 字段:
# 方案 A:server 级别默认
servers :
acp :
default_locale : zh-CN
# 方案 B:agent 级别默认
agents :
assistant :
default_locale : zh-CN
system_prompt : " You are a helpful assistant."
优先级 :_meta.locale(客户端传入)> default_locale(YAML 配置)> 无(agent 自行决定语言)
方案 A 更简单(一个服务一个默认语言),方案 B 更灵活(不同 agent 可以有不同默认语言)。倾向方案 A ,除非有明确的 per-agent 语言差异需求。
5. 是否需要注入到 Jinja2 模板
结论:不需要。维持 PR #128 的 callable prompt 方式。
当前 system prompt 有两种渲染机制:
Jinja2 模板渲染 (format_system_prompt()):在 sys_prompts.py 中,渲染时传入 agent、prompts、dynamic 等框架内部变量,面向的是 YAML 配置层面的静态模板渲染。
Callable prompt :pydantic-ai 在每次 model call 时调用 callable 函数,返回动态字符串拼到 system prompt 中。get_cwd_context 就是这个模式。
不注入 Jinja2 的理由:
locale 是 per-connection 的运行时值 ,不是 YAML 配置时已知的静态值。把 client_locale 塞进 Jinja2 渲染上下文会让模板变量承担不属于它的职责。
callable prompt 已经够用 。PR feat(acp): support locale injection via ACP initialize for i18n #128 的 get_locale_prompt() 返回 "Language: You MUST respond in {locale}.",每次 model call 时执行,简单直接,与 get_cwd_context 同构。
不是所有 agent 都需要 locale 注入 。用 callable prompt 时,只有客户端传了 locale 才追加这段 prompt;如果注入 Jinja2 变量,所有 agent 的模板都要改才能生效,反而增加了耦合。
总结
问题
建议
字段
_meta.locale,BCP 47 格式,文档化
生效机制
PR #128 现有链路不变
环境变量
不需要
默认语言
YAML default_locale,server 级别
Jinja2 注入
不需要,维持 callable prompt
Related
背景
PR #128 通过 ACP
initialize的_meta字段传入locale,实现了 i18n。功能方向正确,但字段设计需要讨论。需要讨论的几个问题
1. 约定合适的字段
ACP 协议(v1)的
initialize请求结构中没有任何多语言/locale 相关字段。协议层面的字段只有:protocolVersion、clientCapabilities(fs/terminal/elicitation/configOptions)、clientInfo(name/title/version)、_meta(扩展点)。_meta是 ACP 协议中AnnotatedObject的扩展点(field_meta),设计用途就是传递实现特定的附加信息。ACP 官方文档也确认,自定义能力可以通过_meta字段广告扩展支持。协议层面没有其他字段可以用来传 locale。建议:继续用
_meta,但约定一个明确的 key 和文档:locale,值为 BCP 47 语言标签(en、zh-CN、ja-JP)initializeresponse 中可以回传支持的 locale 列表,让客户端知道服务端支持哪些语言_extract_locale()函数),而不是散落在各处2. 配置如何通过 initialize 生效
PR #128 的链路是对的:
这个链路保持不变。唯一要确认的是:locale 应该是 per-connection(initialize 时设定,整个连接生效)还是 per-session(new_session 时可以覆盖)?
建议:per-connection 为主(简单),后续如果需要 per-session 覆盖再加。
3. 环境变量控制的必要性
结论:不需要环境变量。
理由:
initialize通知即可,不需要服务端环境变量4. agentpool ACP 服务如何配置默认语言
当客户端没有在
initialize中传locale时,agentpool 应该有一个默认值。这个默认值应该在 YAML 配置中设定。建议:在 ACP server 配置或 agent 配置中加
default_locale字段:优先级:
_meta.locale(客户端传入)>default_locale(YAML 配置)> 无(agent 自行决定语言)方案 A 更简单(一个服务一个默认语言),方案 B 更灵活(不同 agent 可以有不同默认语言)。倾向方案 A,除非有明确的 per-agent 语言差异需求。
5. 是否需要注入到 Jinja2 模板
结论:不需要。维持 PR #128 的 callable prompt 方式。
当前 system prompt 有两种渲染机制:
format_system_prompt()):在sys_prompts.py中,渲染时传入agent、prompts、dynamic等框架内部变量,面向的是 YAML 配置层面的静态模板渲染。get_cwd_context就是这个模式。不注入 Jinja2 的理由:
client_locale塞进 Jinja2 渲染上下文会让模板变量承担不属于它的职责。get_locale_prompt()返回"Language: You MUST respond in {locale}.",每次 model call 时执行,简单直接,与get_cwd_context同构。总结
_meta.locale,BCP 47 格式,文档化default_locale,server 级别Related