第 16 章 第二部分:架构原理

LLM Client 体系

OpenAICompatibleClient 抽象、8 种内置 Client、Cache 与确定性重放、ExtendedChatCompletion

Nexus LLM Client OpenAI HyTuner Cache

OpenAICompatibleClient 抽象

nexus/core/openai_client.py(70 行)定义了所有 LLM Client 的基类:

class OpenAICompatibleClient(ABC):
    def __init__(self, config: OpenAIConfig):
        self.config = config

    @observe('openai_completion')   # 自动 Trace
    @cacheable(tags=['llm'])        # 自动 Cache
    async def create_completion(self, messages, model=None, **kwargs):
        return await self._create_completion(messages, model, **kwargs)

    @abstractmethod
    async def _create_completion(self, messages, model=None, **kwargs):
        ...

两个关键装饰器:

  • @observe:每次 LLM 调用自动创建 Span
  • @cacheable:支持缓存和重放

8 种内置 Client

Client注册名后端适合场景
OpenAIopenaiOpenAI API通用
Azure OpenAIazure_openaiAzure OpenAI API企业 Azure
LiteLLMlitellmLiteLLM(100+ provider)多 provider 切换
Taijitaiji腾讯太极推理服务内部混元模型
HyTunerhytunerHyTuner server_managerRL 训练
InferProxyinfer_proxy混元推理代理内部推理服务
CustomFunctioncustom_function任意 Python 函数完全自定义
Mockmock预设响应测试

OpenAI Client(最基础)

@openai_client_registry.register('openai')
class OpenAIClient(OpenAICompatibleClient):
    def __init__(self, config):
        self.client = AsyncOpenAI(**config.client_args)

    async def _create_completion(self, messages, model=None, **kwargs):
        merged = {**self.config.request_args, **kwargs}
        if model: merged['model'] = model
        response = await self.client.chat.completions.create(
            messages=messages, **merged)
        return ExtendedChatCompletion.from_openai(response)

HyTuner Client(最复杂,26KB)

HyTuner Client 不调用外部 API——它使用 HyTuner 的 server_manager 直接驱动训练中的模型生成。这是 Nexus RL 训练集成的核心:

  • 接收 messages → 用 tokenizer 编码 → 调用 server_manager 生成
  • 处理 tool_call 格式解析
  • 支持 abort_event(外部中断)
  • 采集 logprobs 用于 RL 训练

logprobs 在 GPT-6 Astra 上不可用

官方 latest-model 迁移指南给 Astra 列的 “Unsupported parameters” 原文是:

Remove temperature, top_p, and top_logprobs. For Chat Completions, also remove logprobs. For Responses, remove message.output_text.logprobs from include.

这句比”废弃某个参数”更重:Astra 在两条 API 上都不再返回 token 级对数概率——Chat Completions 去掉 logprobs,Responses 去掉 include 里的 message.output_text.logprobs。凡以 Astra 为 policy model 或 teacher model、且依赖 API 侧取回 logprobs 的训练链路,这条路已断。

对 Nexus 的影响要分两层看:

  • HyTuner Client 不受影响。它走 HyTuner server_manager 直连训练中的模型,不经 OpenAI API,logprobs 由训练框架侧产出。
  • 受影响的是”用 OpenAI 兼容 API 采集 logprobs”的路径——用 openai client 接 Astra 做 teacher 蒸馏、off-policy 校正、或任何需要 token 级概率的重要性采样,在 Astra 上都不成立。Ch14 中 HyTuner Processor 输出的 logprobs 字段若来自此类外部 API 采集,需改走自托管推理。

同一份官方指南里的同批变更:

变更官方原文要点
工具调用”GPT-6 Astra supports Chat Completions, but tool calling requires Responses”
采样参数移除 temperature / top_p(官方用词是 Remove)
提示缓存从 GPT-5.5 或更早迁移时,prompt_cache_retention 改为 prompt_cache_options.ttl,值取 "30m"
安全监控异步 misalignment monitoring,必要时触发告警(官方原文 “trigger alerts”)
新增能力Responses 侧异步工具调用、WebSocket mid-turn steering(保留已完成工作并续传)

两点收敛说明:二手报道称 misalignment monitoring 可”在会话进行中中断”、以及新增 429 slow_down / 503 server_is_overloaded 错误码,本轮在官方页均未找到对应表述(官方只写 trigger alerts;429 / 503 在官方指南中零命中),故只按官方口径写”触发告警”,不写中断语义、也不写新错误码。

📌 prompt_cache_retention → prompt_cache_options.ttl 这条需与 CCI Ch19(提示缓存)同步。openai-python 主干的 Response 定义里两个字段目前并存(旧键仍在),旧键大概率不会报错,但官方已明示新键为目标形态。

✅ 2026-10-06 复测(「未变」也是结论):本轮回源复查 Astra 的两条结论——logprobs 不可用、以及 prompt_cache_retention → prompt_cache_options.ttl 的迁移项——均无新增反证,仍成立。另需说明本次复测的边界:「未变」这一判断依赖本轮检索的覆盖度,它只能证明没找到反证,不等于官方没有变更。

📌 下轮复检项:Astra 是否仍为 models 索引页的首推模型。这不只是版本号维护——本节「Astra 上不支持 logprobs」的适用范围是以 Astra 为当前旗舰为前提的;一旦它被更新的旗舰取代,凡以「新旗舰」为 policy / teacher model 的链路,其 logprobs 可用性要重判,本节这一小节的标题也要跟着改。

LiteLLM Client

包装了 LiteLLM 库,支持 Anthropic prompt caching(将 system message 标记为 cache-able)。

Mock Client

预设固定响应,支持 tool_call 模拟,用于单元测试。

ExtendedChatCompletion

OpenAI、Anthropic、Gemini 的 API 响应格式不同。Nexus 用 ExtendedChatCompletion 统一:

class ExtendedChatCompletion(BaseModel):
    id: str
    choices: list[ExtendedChoice]
    usage: ExtendedUsage | None

class ExtendedMessage(BaseModel):
    role: str
    content: str | None
    tool_calls: list | None
    thinking: list[ThinkingBlock] | None  # Anthropic 的 thinking

class ExtendedUsage(BaseModel):
    prompt_tokens: int
    completion_tokens: int
    prompt_tokens_details: ExtendedPromptTokensDetails | None  # cache 命中等
    completion_tokens_details: ExtendedCompletionTokensDetails | None

ThinkingBlock 支持 Anthropic 的 extended thinking 和 RedactedThinkingBlock(被审查的 thinking 内容)。

Cache 系统与确定性重放

@cacheable 装饰器(nexus/utils/cache.py,25KB)实现了函数级缓存:

@cacheable(tags=['llm', 'completion'], ignore_args=['self'])
async def create_completion(self, messages, model=None, **kwargs):
    ...

工作模式

  1. 首次运行:正常执行函数,缓存 (func_name, args_hash) → result
  2. 重放运行:检查缓存命中 → 直接返回缓存结果,不执行函数
  3. 部分重放:overwrite_tags=['tool'] → LLM 调用走缓存,Tool 调用真实执行

Cache 文件格式

pickle 序列化的 dict:

{
    'version': 2,
    'entries': [
        {
            'func': 'create_completion',
            'args_hash': 'abc123...',
            'result': ExtendedChatCompletion(...),
            'tags': ['llm', 'completion'],
            'timestamp': '...',
        },
        ...
    ]
}

ContextLengthExceededError

各 provider 的上下文长度超限报错格式不同。Nexus 统一包装为 ContextLengthExceededError:

class ContextLengthExceededError(Exception):
    def __init__(self, message, original_error=None):
        self.original_error = original_error

Agent 可以捕获这个异常触发 compaction,而不需要判断具体是哪个 provider 的报错。

Responses API 迁移路线图

现状判断修正

Responses API 已非”推荐入口”而是”主力入口”。截至 2026.06,推理模型的核心能力已与 Responses API 绑定:

  • GPT-5.4 推理+工具调用仅 Responses API 支持:Chat Completions 不再支持 reasoning: none 时的工具调用,推理链仅通过 Responses API 可用
  • 独占特性涌现:Tool Search(运行时按需发现工具)、Hosted Shell Tool + 容器工作空间、Skills 本地/容器执行、WebSocket mode、Conversations API(持久对话对象替代 Threads)、phase 标注(intermediate commentary vs final_answer)、server-side Compaction
  • GPT-5.6 新增独占特性(2026-07-09):Programmatic Tool Calling(模型原生程序化工具调用,仅 Responses API)、Multi-agent orchestration(beta,API 原生多 Agent 编排)、Web Search 图片结果返回(2026-06)、Workload Identity Federation(2026-05,外部身份令牌替换长期 API Key)、Secure MCP Tunnel(2026-05,企业客户托管隧道连接私有 MCP Server)
  • GPT-6 Astra(2026-09-03,模型 ID gpt-6-astra):官方定位”our most capable model, built for the hardest end-to-end work”,是 models 索引页的首推模型。规格:1,050,000 上下文窗口 / 922,000 最大输入 / 128,000 最大输出,知识截止 2026-04-30;reasoning.effort 仅支持 low / medium / high / xhigh / max(官方 Limitations 明确”does not support the none reasoning effort”);定价输入 $10、输出 $50 per 1M,cached input $1、cache writes $12.5;端点上 Chat Completions ✅、Responses ✅、Batch ✅,而 Assistants ❌、Realtime ❌、Fine-tuning ❌
  • OpenAI 官方口径已升级:从”推荐迁移”变为”强烈建议立即将工作流迁移到 Responses API”

比”建议”更硬的是能力事实:Astra 官方模型页的 Supported tools 小节标题原文即 “Tools supported by this model when using the Responses API”,下列 web_search、file_search、image_generation、code_interpreter、hosted_shell、apply_patch、skills、computer_use、mcp、tool_search 十项;官方 latest-model 指南进一步写明 “GPT-6 Astra supports Chat Completions, but tool calling requires Responses”。也就是说,新旗舰模型的工具能力面本身以 Responses API 为界——这不是排期建议,是使用前提。

272K 计费悬崖:成本模型不再是线性的

这不是 Astra 独有的一条促销条款,而是 OpenAI 长上下文计价的通用跳变点——Astra 与 gpt-5.6-cyber 两个模型页给出了措辞一致的表述。Astra 的原文是:“Prompts with more than 272K input tokens are priced at 2x input and cache rates and 1.5x output for the full request.” 注意是 for the full request——不是只对超出 272K 的部分加价,整单翻倍。

第二证来自 gpt-5.6-cyber 官方模型页,原文是:“Prompts with >272K input tokens are priced at 2x input and 1.5x output for the full request.” 与 Astra 那句几乎逐字相同,差别只有两处——cyber 版没提 cache rates,且用 >272K 而非 more than 272K。同一份模型页还写着 Maximum input tokens: 272,000,与计费条款里的 272K 是同一个数:这条跳变线就是模型的输入上限。定价上,该页给的档位是输入 $12.5 / 缓存输入 $1.25 / 输出 $75 per 1M。

⚠️ 一个容易被连带误读的点:gpt-5.6-cyber 不是随便就能换过去的 ID。官方模型页写明 “This model requires separate approval and provisioning, you can apply to join the Daybreak program”——它需要单独审批与开通。本节把它当作 272K 条款的第二证引用,不等于推荐它作为迁移目标。

这条对本节的论证有直接后果。ExtendedUsage / ExtendedPromptTokensDetails 只统计 token 数,不建模这种非线性定价,于是成本类 Processor 会系统性低估长上下文请求的成本:一次 280K 输入的请求,实际账单接近”按 280K 线性估算”的两倍。跨过 272K 的那一步,成本是跳变而非渐变。

这也给 Ch15 讨论的 compaction 提供了一个更硬的经济性论据——那里写的是”token 成本仍随长度线性增长”,在 Astra 的定价结构下这句话已不准确:压缩的收益在 272K 边界处是阶跃的,把输入压到 272K 以下与压到 300K,省下的钱差一倍量级。

OpenAI 官方迁移指南(migrate-to-responses)明确了核心格式差异:messages → input items、choices → output array、previous_response_id 链式状态、n 参数移除。

ExtendedChatCompletion v2 扩展需求

为适配 Responses API,ExtendedChatCompletion 需要扩展以下能力:

能力Chat CompletionsResponses APIExtendedChatCompletion v2
输入格式messages: list[dict]input: list[InputItem]需支持 InputItem(含 reasoning/function_call_output 等新类型)
输出格式choices: list[Choice]output: list[OutputItem]需支持多类型输出(reasoning/output_text/function_call)
推理项不暴露加密 reasoning items需支持加密推理项传回(不暴露内容但可续传)
阶段标注无phase: commentary/final_answer需支持 phase 字段
工具发现预加载所有 toolsTool Search 运行时按需发现需支持 tool_search 类型的 output item
缓存细节prompt_tokens_details含 cached_tokens已支持(ExtendedPromptTokensDetails)
非线性定价按 token 线性计费272K 整单 2× 悬崖(Astra 与 gpt-5.6-cyber 措辞一致,见上节)需能表达”本次请求所处计费档位”,否则成本类 Processor 系统性低估长上下文成本。注意这已不是”兼容某一家”的问题:只要走 OpenAI 兼容 API,成本类 Processor 都得知道本次请求落在哪个档位
可中断性无中断语义新增异步 misalignment monitoring,触发告警(详见下文风险小节)需为”平台侧干预”预留退出状态,与 Ch17 的 MainExitStatus 体系对接

工具调用的结构化字段也需要对齐。OpenAI 官方 SDK 已在 Responses 的 Response 对象落地结构化工具描述:Response.tools 是一个 Tool 联合类型(以 type 为 discriminator,含 FunctionTool、CustomTool、NamespaceTool、ToolSearchTool、Mcp、CodeInterpreter、ApplyPatchTool、LocalShell 等 16 种),函数工具带 name;命名空间不是工具的某个字段,而是一种工具类型——NamespaceTool(type: "namespace")自带 name(如 crm)与嵌套 tools 列表,把函数工具与自定义工具分组挂载。按命名空间路由应遍历 response.tools 找 type == "namespace" 的条目,而不是读某个 tool.namespace 属性。

⚠️ 2026-09-16 回源修正:本段原写”官方 SDK 已落地 tool.name / tool.namespace 字段,可直接按 response.tool.name 分支路由”。按 openai-python 主干源码核对,两处不准确——① Response 上没有单数字段 tool,只有复数 tools: List[Tool];② tool.namespace 这个字段不存在,命名空间是 NamespaceTool 类型并自带 name。原表述会直接误导实现,已按源码改写;tool.name 这部分(工具对象上的 name)成立。

版本锚点更新:上述字段形态以 openai-python 主干 v3.24.0(2026-10-02) 为准。原锚点 v2.53.0(2026-08-03)经 PyPI registry 确认确为该日发布 ✅,但它发布 9 天后 SDK 就进入了 v3.x——v3.0.0 于 2026-08-12 发布,此后 9 月以来平均 1–2 天一版(3.7.0/09-02 → 3.14.1/09-15,13 天 8 个版本)。

✅ 2026-10-06 复测:上面那条 2026-09-16 的回源修正,是在锚点 v3.14.1 下做出的。锚点已漂移到 v3.24.0,本节按新版本重新核对了 types/responses/{response,tool,namespace_tool}.py,两项修正均仍成立:Response 上依然只有 tools: List[Tool]、没有单数字段 tool;NamespaceTool 依然是自带 name(如 crm)与嵌套 tools 列表的工具类型,tool.namespace 依然不存在。另有一处需要同步:Tool 联合类型在 v3.24.0 下仍是 16 种成员,但构成有变——新增了 ProgrammaticToolCalling 与 FunctionShellTool。本节此后的字段引用以 v3.24.0 为准。

本章此后引用 SDK 字段以当前主线版本为准,v2.53.0 只作为”该字段形态何时出现”的历史锚点。这条纪律要当真:本章上一次正是靠回源才纠掉了 tool.namespace 这个根本不存在的字段,而两次回源之间只隔了 17 天、15 个版本。锚点失效期间,任何”已核实”的结论都应视为”未复核”,不能默认它仍然成立。

迁移 Gotchas

生产迁移中需注意的陷阱:

  1. n 参数消失:Chat Completions 的 n > 1 多生成需改为多次请求
  2. previous_response_id 有 30 天 TTL:chaining 仍按输入 token 计费,Conversations API 可避免 TTL 限制
  3. 加密推理项:reasoning 内容不可见但占用 token,需在 usage 统计中正确处理
  4. Tool Search 延迟加载:与 MCP 的”懒加载”理念一致,Nexus 的 OpenAI Client 可利用 Tool Search 将工具发现延迟到运行时,减少 token 占用

Tool Search 与 MCP 工具发现的关联

OpenAI Responses API 的 Tool Search 允许模型运行时按需发现工具,而非预加载所有工具描述。这减少了 token 占用并保留了缓存性能。这与 MCP 的”懒加载”理念一致——Claude Code 的 MCP Tool Search 也采用类似策略,仅在 Agent 需要时才加载工具描述。

Nexus 的 OpenAI Client 在支持 Responses API 时,可利用 Tool Search 将工具发现延迟到运行时。对 ExtendedChatCompletion 的影响:需要支持 tool_search 类型的 output item,并在 Agent 循环中正确处理工具发现结果。

“Open Responses” 开源规范

OpenAI 发布的”Open Responses”开源规范支持多供应商互操作 LLM 接口,可能降低 Nexus 自建 Responses Proxy 的维护成本——如果其他供应商(Anthropic、Google)也采纳此规范,Nexus 的 ExtendedChatCompletion 只需适配一种格式。

时间线

2026.08.26:Assistants API 已停服(原条目写作”距停服仅剩约 9 天”,该倒计时早已失效,改为完成时)。官方废弃表条目:2026-08-26 | Assistants API | Responses API and Conversations API;Astra 端点表亦列 Assistants | v1/assistants 为 Not supported。

官方给出的 Recommended replacement 是 Responses API and Conversations API,配套迁移指南标题为 “Assistants to Conversations”。

⚠️ 2026-09-16 澄清:有二手来源称”Assistants 的概念对应 Responses 的 Prompts,而 Prompts 只能从 dashboard 创建”。按官方废弃页核对,官方推荐替代项是 Responses + Conversations,不是 Prompts;且 Reusable prompts(v1/prompts)本身也在 2026-11-30 关停(见下表)。不要把 Prompts 当作 Assistants 的迁移落点。

📌 以下两点来自二手报道(endoflife.ai、pondero.ai),官方页未直接确认,保留但标注:停服为无宽限期硬停,/v1/assistants、/v1/threads、/v1/threads/runs 全部返回错误,SDK 的 openai.beta.* 命名空间停止工作,无官方自动迁移工具,Thread 历史需手工导出重建;Azure OpenAI 同日停服,其迁移工具只改代码构造,明确不迁移状态数据(历史 runs / threads / messages)。

对 Nexus 的含义:§8 种内置 Client 里的 openai client 走 chat.completions.create,不受影响;真正受影响的是任何把 Nexus 接到 Assistants 语义(持久 Thread + Run 轮询)上的集成,需改为 Responses + previous_response_id 或 Conversations API。

官方废弃时间表

原时间线只有 08-26 与 11-30 两条,现按 platform.openai.com/docs/deprecations.md 官方条目补全(逐条回源核对):

日期事件官方备注
2026-08-26Assistants API 停服已发生;→ Responses + Conversations API
2026-09-24Videos API 与 sora-2 / sora-2-pro 及全部快照关停已发生;官方替代项栏为 ---,无替代项
2026-09-28gpt-3.5-turbo-instruct / babbage-002 / davinci-002 / gpt-3.5-turbo-1106 关停已发生;→ gpt-5.6-terra
2026-10-01gpt-5.4-cyber 从 API 移除已发生(2026-09-11 官方条目)。⚠️ 官方废弃表给的替代项是「The most capable cyber model available to you」,不是字面的 gpt-5.6-cyber;后者出自模型页,且需 Daybreak 计划审批
2026-10-23legacy GPT 快照移除(节选,官方该条目共 12 个模型行 + 5 个 fine-tuned 行)节选:gpt-3.5-turbo-0125 → gpt-5.6-terra;gpt-4-0613 / gpt-4-turbo / gpt-4o-2024-05-13 → gpt-5.6-sol;gpt-4.1-nano → gpt-5.6-luna。另有 gpt-4-1106-preview → sol、gpt-image-1 → gpt-image-2.5-sunburst/gpt-image-2.5-flare、o1 → sol、o1-pro → sol(reasoning.mode: pro)、o3-mini → sol、o4-mini → terra、ft-o4-mini-2025-04-16 → terra
2026-10-31Evals 平台现有 evals 转为只读比 11-30 关停早一个月,且先失去写能力
2026-11-30Reusable prompts(v1/prompts)关停官方建议”把 prompt 内容搬进应用代码”
2026-11-30Agent Builder 关停ChatKit 保留;→ Agents SDK / ChatGPT Workspace Agents
2026-11-30Evals dashboard 与 API 关停官方迁移建议 Promptfoo
2026-12-11GPT-5 / o3 老快照移除→ gpt-5.6-sol / terra / luna
2027-01-06tts-1 / tts-1-hd / gpt-4o-mini-tts-2025-03-20 / gpt-4o-mini-tts-2025-12-15 关停→ gpt-realtime-2.1-mini(官方条目日 2026-10-01)。本章此前 8 行里没有任何音频类条目
2027-02-26whisper-1 等转录模型移除→ gpt-live-transcribe / gpt-transcribe

fine-tuned 那 5 行要单独拎出来看,它们对 Nexus 不是旁观项。同一份官方表(2026-10-23 条目)还列了:ft-gpt-3.5-turbo → gpt-5.6-terra、ft-gpt-4 → gpt-5.6-sol、ft-gpt-4.1-nano-2025-04-14 → gpt-5.6-luna、ft-babbage-002 → gpt-5.6-terra、ft-davinci-002 → gpt-5.6-terra。含义是实的:HyTuner 链路若在 OpenAI 侧产出微调模型,这些 base 的 ft-* 版本会跟着 base 一起失效,而官方只给 base model 的替代项、不给微调模型的迁移路径——微调权重没有对等物,只能重训。

⚠️ 方法护栏:替代模型 ID 只认 platform.openai.com/docs/deprecations.md。

本节已经出现过两次”二手来源与官方不一致”,把它固化成一条规则比每次单独澄清划算:

  1. 第三方博客会写错替代项。2026-09-30 有第三方把 2026-10-23 那批的替代项写成 gpt-5.5 / gpt-5.4-mini / gpt-5.5-pro,官方表写的是 gpt-5.6-terra / gpt-5.6-sol / gpt-5.6-luna——两组完全不同,没有一个是重叠的。
  2. 官方自己的两份文档也会不同步。cyber 条目在废弃表里只写「你能用的最强 cyber 模型」,具体 ID 与准入条件(Daybreak 计划审批)在模型页上。把模型页的 ID 当成废弃表的替代项写进表里,就会把一个需要审批的迁移说成一次 ID 替换。

因此凡引用替代项,须注明取自哪一份官方文档的哪一段。

  • Chat Completions:不会停服,但推理模型功能将持续受限——Astra 上官方已写明”supports Chat Completions, but tool calling requires Responses”
  • 建议(已收紧):原表述为”Nexus 应在 2026.Q3 前完成 v2 设计、Q4 完成实现”。在 Astra 之后这不再只是排期问题:若要用新旗舰的工具能力,Responses 适配是前置条件而非可延后的优化项。改为——以 v2 设计完成为 Q3 硬目标、Q4 完成实现;在此之前不规划任何依赖 Astra 工具能力的特性。