-
Notifications
You must be signed in to change notification settings - Fork 2
LLM Adapter
AceGuru-mjh edited this page Oct 1, 2026
·
4 revisions
📑 本页目录
core:llm-adapter只做一件事:说 OpenAI 兼容方言。自研 SSE 解析,不引任何厂商 SDK。 BYO-LLM:端点、Key、模型全部由用户自带(含局域网 Ollama)。
com.apex.agent.core.llm
├── LlmClient / LlmClientFactory 客户端接口与工厂(含 NoOp 实现)
├── LlmConfig 连接 + 采样 + 上下文字段(含 4 个预设)
├── ModelProfile / ModelCapabilities 模型档案与能力声明
├── ModelsCatalog / ModelProfileDefaults 内置 Provider 与默认 Profile 种子
├── StreamingOpenAiClient 自研 SSE 流式客户端
└── runtime/
├── ModelRuntime / DefaultModelRuntime 运行时封装(Key 轮换、超时、诊断)
├── ModelRuntimeRegistry / Store 档案与运行时的注册表 + 持久化
├── ModelRoleRouter 按角色路由
├── CapabilityResolver 能力校验(缺失即抛错,不静默降级)
├── ModelProfileValidator 档案校验
├── ModelRuntimeErrors / ModelRuntimeDiagnostics 错误分类与诊断
└── UserQuestionGateway(app 侧实现) 人机闭环注入点
| 组 | 字段 | 默认 |
|---|---|---|
| 连接 |
baseUrl / apiKey / model
|
空(未配置时走 NoOpLlmClient) |
| 基础 |
temperature / maxTokens / streaming
|
0.7 / 4096 / true |
| 超时 |
connectTimeoutMs / readTimeoutMs / writeTimeoutMs / requestTimeoutMs
|
15s / 120s / 30s / 120s |
| 重试 | retryCount |
2 |
| 思考 |
reasoningEffort / thinkingBudget / showThinking
|
NONE / null(Auto) / true |
| 上下文 |
contextWindow / reservedOutputTokens
|
128000 / 4096 |
| 采样 |
topP / topK / minP / frequencyPenalty / presencePenalty / repetitionPenalty / seed / stopSequences
|
见默认值 |
| 其他 |
customHeaders / systemPromptPrefix
|
空 |
内置预设(工厂方法):
| 预设 | Base URL | 备注 |
|---|---|---|
| OpenAI | https://api.openai.com/v1 |
— |
| OpenRouter | https://openrouter.ai/api/v1 |
默认模型 anthropic/claude-3.5-sonnet(可在设置里改) |
| DeepSeek | https://api.deepseek.com/v1 |
默认 deepseek-chat
|
| Ollama | http://10.0.2.2:11434/v1 |
局域网/宿主机填 PC IP;Key 任意(如 ollama) |
| 自定义 | 用户填写 | 任何 /v1/chat/completions 兼容端点,含 vLLM / LM Studio / 中转站 |
Note
Key 轮换在 DefaultModelRuntime 层做(LlmConfig.apiKey 只取 Provider 的第一个 Key),
不要把多 Key 逻辑塞进单个 LlmConfig。
ModelRole(真实枚举):
| 角色 | label | 用途 |
|---|---|---|
PRIMARY |
Primary Agent | 默认主力模型 |
VISION |
Vision Model | 会话含图片时 |
REASONING |
Reasoning Model | 推理任务 / 高思考档位 |
FAST |
Fast Model | 轻量快速任务 |
SUMMARY |
Summary Model | 摘要/压缩任务 |
规则:未配置某角色 → 回退 PRIMARY;会话含附件图片时,自动要求 vision + imageInput 能力,
全链没有视觉模型则抛 ModelCapabilityMismatch —— 能力校验 + 诚实失败,而不是假装看见了图片。
ModelCapabilities(
text = true, vision = false, toolCalling = true, structuredOutput = false,
streaming = true, reasoning = false, jsonMode = false, imageInput = false, longContext = false
)summary() 产出给 UI 的能力徽章串:Text · Vision · Tools · JSON · Reason · LongCtx。
ModelRuntimeErrors + ModelRuntimeDiagnostics 把运行时错误分类(鉴权失败 / 配额 / 模型不存在 /
超时 / 协议错误 / 能力不匹配),供 编排器 的 FailureClassifier 决定重试还是终态。
| 主题 | 做法 |
|---|---|
| 协议 | 手写 SSE 解析(text/event-stream),对 /v1/chat/completions 增量 delta 累积 |
| 思维链 | 各家字段:delta.reasoning_content(o 系列 / DeepSeek-R1)、delta.reasoning(部分 Anthropic 代理)→ 统一落到 LlmStreamChunk.reasoningContent → AgentEvent.ThinkingChunk
|
| 并行工具调用的坑 | OpenAI 在并行工具调用时,首个片段携带 index 与 id,后续片段只有 index、id 为空。旧实现以 id 作累加器键 → 后续片段被误开新累加器、参数被裁断、工具调用永远拼不成。现在透传 ToolCall.index,累加侧在 id 为空时回退用 index 作键 |
| 用量 | Usage(promptTokens, completionTokens, totalTokens) |
| 工具声明 |
ToolDefinition(name, description, parameters /* JSON Schema string */),由 ToolSchema DSL 渲染 |
data class LlmStreamChunk(val text: String?, val reasoningContent: String?, …)
data class ToolCall(val id: String, val name: String, val arguments: String, val index: Int = -1)- 非流式响应
index = -1;流式时用 index 纠偏(见上表)。
Tip
没填任何端点时,工厂产出 NoOpLlmClient:界面给出"请先配置 LLM"的友好提示,
而不是崩溃或空指针。这是刻意设计 —— 首次安装体验不应被"必须先有 Key"挡住。
| 现象 | 排查 |
|---|---|
| 测试连接失败 | Base URL 是否以 /v1 结尾(多数端点需要);局域网 Ollama 是否开了 --host 0.0.0.0 且防火墙放行 |
| 有回复但没有工具调用 | 模型是否支持 tool calling(看能力徽章有无 Tools);某些中转站会剥工具协议 |
| 思维链不显示 | 端点是否透传 reasoning_content;UI showThinking 是否关闭 |
| 并行工具调用参数被截断 | 就是上面说的 index 累加问题(已修),确认是否用了旧分支/旧 APK |
| 图片附件被忽略 | 是否配置了 VISION 角色能力;会抛 ModelCapabilityMismatch 而不是静默忽略 |
| 频繁超时 | 读超时默认 120s;本地大模型建议单独调 readTimeoutMs 与 retryCount
|
-
Agent 引擎 ——
ThinkingLevelvsReasoningEffort - 上下文压缩 —— 窗口预算来源
-
工具系统 ——
ToolDefinition从 schema DSL 渲染 - 安全与隐私 —— Key 存放在哪
-
MCP 生态总览
新 - (沙箱 MCP · 官方 Hub · 逆向 Host · 门控语义)
- 终端运行时
- 终端 API 契约
- SDK 边界
- Termux 能力矩阵
- Ubuntu rootfs 供给
- Ubuntu 生命周期
- PRoot 二进制溯源
- VT100/ANSI 模拟器
- 终端性能
- 终端迁移
- 原生层 C++/JNI