Model Access 总览
Model Access 这一章讲的不是“AI4J 支持哪些模型名字”,而是 模型请求在 AI4J 基座里如何被建模、投影、发送、流式消费和回读。
这一层的关键源码锚点主要是:
platform/openai/chat/entity/ChatCompletion.javaplatform/openai/response/entity/ResponseRequest.javaplatform/openai/chat/OpenAiChatService.javaplatform/openai/response/OpenAiResponsesService.javalistener/SseListener.javalistener/ResponseSseListener.javaservice/factory/AiService.java
1. 这一章在 Core SDK 里的位置
如果 service-entry-and-registry 讲的是“从哪个 service 入口拿能力”,那 model-access 讲的就是:
- 请求对象长什么样
- provider 适配层在发送前做了什么
- 流式返回如何被聚合
Chat和Responses分别适合什么运行时
它仍然是 ai4j/ 基座层的问题,不是 Agent 或 Coding Agent 的上层专属话题。
2. 这一章真正覆盖什么
这一章主要覆盖五个问题:
- 为什么 AI4J 同时保留
Chat与Responses - 请求对象里哪些字段是主语义,哪些只是辅助注册信息
- 流式结果在本地如何被监听器聚合
- 多模态输入如何投影到两条主线
- provider 差异在基座层被保留到了什么程度
它不负责讲:
- tool 执行细节
- MCP 协议接入细节
- agent loop
- coding runtime
这些要切去 tools、mcp 或上层模块文档。
3. 这章最先要分清的边界
第一次进入这一章,最重要的不是先看某个 provider,而是先分清 AI4J 内部有两条不同的模型访问主线:
Chat
- 以
messages为中心 - 更贴近传统 chat completions 心智
- provider 覆盖最广
- 内建了自动 tool loop 与流式 tool call 聚合
Responses
- 以
input和事件序列为中心 - 更贴近结构化 response item / event 心智
- provider 覆盖更聚焦
- 更适合 runtime 侧状态消费
很多后续差异,包括 streaming、多模态、工具解析方式,本质上都从这里分叉。
4. 当前 provider 覆盖并不完全对称
AiService.createChatService(...) 当前能创建的 Chat provider 包括:
- OpenAI
- Zhipu
- DeepSeek
- Moonshot
- Hunyuan
- Lingyi
- Ollama
- Minimax
- Baichuan
- DashScope
- Doubao
而 AiService.createResponsesService(...) 当前只覆盖:
- OpenAI
- Doubao
- DashScope
这意味着在 AI4J 里:
Chat是更广覆盖的默认主线Responses是更结构化、但 provider 覆盖更聚焦的主线
这不是文档叙述偏好,而是当前工厂实现给出的事实。
5. AI4J 如何处理“统一请求”与“provider 差异”
AI4J 的请求对象策略不是简单追求字段最少,而是把主语义固定下来,再把差异留给适配层。
例如:
ChatCompletion有model / messages / stream / tools / toolChoice / responseFormatResponseRequest有model / input / stream / tools / toolChoice / reasoning / truncation- 两者都有
functions与mcpServices这类本地注册辅助字段 - 两者都有
extraBody承接额外 payload
关键点在于:
functions和mcpServices不会原样发给 providertools才是最终真正进入 provider payload 的字段
所以读这一章时,要把“本地注册字段”和“最终 provider 字段”分开理解。
6. 两条主线都不是单纯文本接口
Chat 不是“只会返回一条字符串”:
- 同步调用里可以自动执行 tool calls
- 流式调用里
SseListener会聚合 reasoning、tool calls、usage、finish reason
Responses 也不是“只会返回一堆事件”:
- 非流式会返回完整
Response - 流式时
ResponseSseListener会同时聚合events、outputText、reasoningSummary、functionArguments和最终response
这意味着两条主线都已经足以支撑中等复杂度运行时,只是适合的消费方式不同。
7. 多模态也属于这一层,而不是 Tool 或 MCP
AI4J 把图文输入纳入了统一会话抽象:
ChatMemory.addUser(String text, String... imageUrls)ChatMemoryItem.toChatMessage()ChatMemoryItem.toResponsesInput()
同一份会话事实可以:
- 投影成
ChatMessage + Content.MultiModal - 或投影成
Responses的input_text / input_image
这说明多模态在 AI4J 里是请求协议问题,不是外部能力接入问题。
8. 推荐阅读顺序
建议按下面顺序读:
9. 这一页的结论
Model Access在 AI4J 里讲的是“请求如何被建模并送进 provider”,不是“模型能做什么”。当前基座保留了两条清晰主线:Chat负责更广覆盖的消息式访问,Responses负责更结构化的事件式访问;二者共享统一工具与多模态基座,但并不应被看成同一接口的两种皮肤。