
Nightingale AI LLM 配置管理 API 实战指南模型接入、连通性探测与安全细节【免费下载链接】nightingaleNightingale is to monitoring and alerting what Grafana is to visualization.项目地址: https://gitcode.com/GitHub_Trending/ni/nightingaleNightingale 在告警与可观测能力之外内置了一套面向 AI Agent/Assistant 的 LLM 配置管理中心通过/api/n9e/ai-llm-configs系列接口统一管理 OpenAI、Claude、Gemini 三类大模型接入。本文基于 doc/api/ai-llm-config.md 展开结合 router_ai_llm_config.go、ai_llm_config.go 与 probe.go 等源码实现完整覆盖数据模型、增删改查 API、API Key 掩码保护、以及连通性测试探针的底层原理帮助你在自己的 Nightingale 部署中安全、正确地接入任意兼容 OpenAI/Claude/Gemini 协议的 LLM 服务。数据模型AILLMConfig 与 LLMExtraConfigLLM 配置在存储层对应ai_llm_config表模型定义位于 models/ai_llm_config.go建表 SQL 见 docker/migratesql/migrate.sql。AILLMConfig 核心字段字段类型必填说明idint64-主键自增namestring是配置名称全局唯一创建/改名时校验descriptionstring否描述api_typestring是提供商类型openai、claude、geminiapi_urlstring是API 地址Base URLapi_keystring是API 密钥modelstring是模型名称extra_configobject否高级设置详见 LLMExtraConfigenabledbool否是否启用需显式传true或falseis_defaultbool否是否作为默认配置首个创建或显式指定时生效created_at / created_byint64 / string-创建时间Unix 时间戳/ 创建人updated_at / updated_byint64 / string-更新时间 / 最后更新人从源码结构看Verify()方法models/ai_llm_config.go#L49-L67会在保存前对name、api_type、api_url、api_key、model五个字段做非空校验name会先TrimSpace任一缺失即返回错误这与文档中五字段均必填的校验规则一一对应。值得注意的数据库细节extra_config以 JSON 序列化serializer:json存储在text列中description列在 v9 迁移中由varchar(1024)收窄为textmigrate.sql#L492-L497以避免超长描述在 MySQL 上触发 1406 错误或被静默截断——这是历史演进留下的兼容性处理。LLMExtraConfig 高级配置字段类型说明timeout_secondsint请求超时秒默认 30skip_tls_verifybool是否跳过 TLS 证书校验proxystringHTTP 代理地址custom_headersmap[string]string自定义请求头custom_paramsmap[string]any自定义请求参数按提供商语义透传如 OpenAI 兼容接口的顶层字段temperaturefloat64采样温度可选max_tokensint最大输出 token 数可选context_lengthint上下文窗口大小可选其中timeout_seconds的默认值 30 在 probe.go#L123-L129 的ProbeTimeout中得到确认仅当显式配置大于 0 时才覆盖默认值。custom_params会被BuildLLMConfigprobe.go#L105-L119原样映射为请求体的ExtraBody在 OpenAI 兼容接口中平铺到请求顶层例如阿里百炼的enable_thinking在 Claude 接口中平铺到 Messages 请求顶层在 Gemini 接口中则仅消费thinking_config/thinkingConfig键并桥接进generationConfig.thinkingConfig见 aiagent/llm/llm.go#L190-L199。配置管理 API 全览所有端点均挂在/api/n9e前缀下并且要求登录认证。路由注册见 center/router/router.go#L693-L698方法路径功能GET/api/n9e/ai-llm-configs列出全部 LLM 配置GET/api/n9e/ai-llm-config/:id查询单个配置详情POST/api/n9e/ai-llm-configs新建配置PUT/api/n9e/ai-llm-config/:id更新配置DELETE/api/n9e/ai-llm-config/:id删除配置POST/api/n9e/ai-llm-config/test测试 LLM 连通性与文档中需要管理员权限略有不同的是当前路由实际使用rt.auth()rt.user()rt.perm(/ai-config/llm-configs)的组合即需要登录、并且拥有/ai-config/llm-configs操作权限的用户通常由管理员分配这一点以仓库当前实现为准。此外路由还注册了一组service前缀的内部接口router.go#L948-L951供外部服务以system身份代建/代改配置aiLLMConfigAddByService/aiLLMConfigPutByService创建人固定记为system。1. 列出配置GET /api/n9e/ai-llm-configs响应示例{ dat: [ { id: 1, name: gpt-4o, description: OpenAI GPT-4o, api_type: openai, api_url: https://api.openai.com, api_key: sk-a****wxyz, model: gpt-4o, extra_config: { temperature: 0.7, max_tokens: 4096 }, enabled: true, created_at: 1710000000, created_by: admin, updated_at: 1710000000, updated_by: admin } ], err: }底层实现aiLLMConfigGetsrouter_ai_llm_config.go#L21-L29直接读取全表并按id排序返回。注意API Key 在返回前会被掩码处理详见下文API Key 掩码与回填机制因此响应中的api_key不会以明文出现而是类似sk-a****wxyz的形态。2. 查询单个配置GET /api/n9e/ai-llm-config/:id参数类型说明idint64LLM 配置 ID响应结构与列表一致同样对api_key掩码。若配置不存在返回404实现中通过ginx.Bomb(http.StatusNotFound, ai llm config not found)触发见 router_ai_llm_config.go#L31-L42。3. 新建配置POST /api/n9e/ai-llm-configs请求体示例{ name: gpt-4o, description: OpenAI GPT-4o, api_type: openai, api_url: https://api.openai.com, api_key: sk-xxx, model: gpt-4o, extra_config: { timeout_seconds: 60, temperature: 0.7, max_tokens: 4096, custom_headers: { X-Custom: value } }, enabled: true }校验规则name、api_type、api_url、api_key、model全部必填name不得与已有配置重名。成功响应返回新配置的 ID{ dat: 1, err: }实现细节models/ai_llm_config.go#L153-L182在事务中完成三件事校验名称唯一 → 若这是全表第一条配置则自动标记is_defaulttrue→ 若本次显式指定is_defaulttrue则先把其他配置的默认标记清空再插入。这种首个自动默认的设计让零配置起步变得顺手。4. 更新配置PUT /api/n9e/ai-llm-config/:id请求体与新建接口一致。关键行为如果api_key为空则保留数据库中已有的密钥而不是覆盖为空。校验规则与新建相同。配置不存在时返回404。在实现层面更新逻辑router_ai_llm_config.go#L55-L76对密钥的处理比文档描述更细致除了空值如果前端把 GET 拿到的掩码值如sk-a****wxyz原样回传也会被识别出来并替换为真实密钥避免误把掩码写回数据库。5. 删除配置DELETE /api/n9e/ai-llm-config/:id配置不存在时返回404成功时返回空dat{ dat: , err: }API Key 掩码与安全回填机制列表与详情接口之所以返回掩码密钥是因为每次读取后都会调用MaskAPIKey()。其规则定义在 models/ai_llm_config.go#L75-L101密钥长度 ≤ 8 时完全掩码为****否则保留前 4 位与后 4 位中间以****填充例如sk-a****wxyz。配套的IsMaskedAPIKey(raw, stored)用于判断回传的 raw 是否为 stored 的掩码形态从而实现三条安全回填路径更新接口aiLLMConfigPutapi_key为空或为掩码值时以库中真实密钥覆盖之router_ai_llm_config.go#L66-L70服务化更新接口aiLLMConfigPutByService同样的保护逻辑连通性测试接口aiLLMConfigTest当测试请求携带name且api_key为掩码值时按名称查出真实密钥用于探测router_ai_llm_config.go#L130-L139。这一整套设计保证前端页面从编辑回显 → 修改 → 保存/测试的完整往返中明文密钥始终只进不出不会被掩码值污染。连通性测试探针式探测的底层原理POST /api/n9e/ai-llm-config/test的核心价值在于可以直接用请求中携带的连接参数发起真实请求无需事先创建配置适合在配置页面上边填边测。请求与校验请求体示例{ api_type: openai, api_url: https://api.openai.com, api_key: sk-xxx, model: gpt-4o, extra_config: { timeout_seconds: 30, skip_tls_verify: false, proxy: , custom_headers: {} } }api_type、api_url、api_key、model四个字段必填缺失时返回 400router_ai_llm_config.go#L126-L128。注意测试接口不要求name但携带时可用于上文提到的掩码密钥回填。三类提供商的探测请求形态api_type请求 URL鉴权方式openai{api_url}/chat/completionsAuthorization: Bearer {api_key}claude{api_url}/v1/messagesx-api-key: {api_key}gemini{api_url}/v1beta/models/{model}:generateContent?key{api_key}URL 参数从实现看探测请求统一走aiagent/llm的Generate接口probe.go#L63-L97发送内容为Hi、最大输出 512 tokens并用ProbeTimeout控制的超时默认 30 秒包裹整个调用。token 上限字段的路由与自动兜底对于 OpenAI 兼容接口token 上限字段名按模型家族路由gpt-5*家族含gpt-5.1与o1/o3/o4系列使用max_completion_tokens其他模型使用max_tokens。模型名匹配逻辑位于 aiagent/llm/openai.gousesMaxCompletionTokens其中gpt-5采用宽前缀匹配避免漏掉gpt-5-mini、gpt-5.1这类点号/横杠变体而o系列精确匹配o1/o3/o4及带横杠前缀防止o1x之类的名称被误伤。对应测试用例见 aiagent/llm/openai_test.go#L222-L243。运行时兜底如果模型名匹配不上任何已知家族典型场景是 Azure 自定义部署名如my-gpt5且服务端返回 400 提示Use max_completion_tokens instead请求会自动把字段改名后重试一次swapToMaxCompletionTokensopenai.go#L157-L171。此时若用户在custom_params里手填过max_tokens其值也会一并迁移到max_completion_tokens保证用户配置的上限不丢失该重试具备幂等性不会无限循环。端到端测试TestGenerate_RetriesWithMaxCompletionTokensopenai_test.go#L514验证了这一先拒后收流程。为什么探测预算给到 512 而非更小这是文档专门解释过的一个反直觉设计推理模型如o1系列、gpt-5、deepseek-r1、gemini-2.5-pro会先把 token 花在思考上预算过小会导致content为空从而误报无内容而普通模型对Hi会finish_reasonstop提前收尾抬高上限并不会增加实际消耗probe.go#L72-L76。因此不按模型分档统一给足预算。截断即健康如果推理模型把 512 个 token 全部烧在思考上finish_reasonlength且正文为空本轮请求仍然算成功——因为端点、凭证、模型都已被验证这正是探测的目的。只有finish_reasonstop正常收尾却完全没有内容时才报告无内容错误。两个对应的测试用例TestProbeTruncatedResponseIsSuccess与TestProbeEmptyContentWithoutTruncationFailsprobe_test.go#L24-L44精确刻画了这一边界。探测前的思考参数归一化为了让探测更稳定快速探针在发送请求前会经NormalizeThinkingParamsaiagent/llm/thinking.go#L22自动叠加关闭深度思考的厂商特定字段路由优先级为用户已显式配置思考控制字段 → 纯思考模型关不掉→ BaseURL 命中托管平台阿里百炼/火山方舟/硅基流动用平台统一参数→ Provider 命中 gemini / openai-o 系列 → 模型名前缀匹配 → 兜底不注入。探测只问一句Hi让思考模型把 token 全烧在 reasoning 上既慢又容易误判空内容所以探测路径做此归一化而正常 chat 路径不再注入思考是一等公民。结构化错误分类探测失败时不会只返回一串裸错误文本而是分类为结构化的ProbeErrorprobe.go#L17-L55再由路由层按X-Language请求头做 i18n 翻译router_ai_llm_config.go#L170-L188。错误分类如下错误类型触发条件authHTTP 401/403API Key 错误endpoint_not_foundHTTP 404API URL 指向错误的端点rate_limitedHTTP 429配额耗尽或请求过频request_failed其他 HTTP 错误状态unexpected_response响应格式无法解析URL 可能指错端点model服务端返回了针对模型名的错误如模型不存在no_content正常收尾却无任何内容成功与失败响应示例{ dat: { success: true, duration_ms: 856 }, err: }{ dat: { success: false, duration_ms: 5000 }, err: HTTP 401: {\error\: \invalid api key\} }错误文案的翻译逻辑由translateProbeError承担例如auth类错误会提示请检查 API Key 是否正确endpoint_not_found类错误会提示OpenAI 兼容接口的 URL 应以/v1结尾如https://api.openai.com/v1。对应测试见 router_ai_llm_config_test.go。配置的实际消费方式LLM 配置并非孤立存在而是被 AI Agent 体系消费按 ID 绑定AI Agentai_agent表通过llm_config_id字段显式绑定某个 LLM 配置建表见 migrate.sql#L401-L407默认配置兜底未绑定任何LLMConfigId的默认 chat Agent会通过AILLMConfigPickDefault自动选用is_defaulttrue 且 enabledtrue的配置models/ai_llm_config.go#L141-L151启用态过滤AILLMConfigGetEnabled可取出所有启用中的配置供调用方使用models/ai_llm_config.go#L132-L136。因此在实际部署中建议在管理页面上先创建并测试好 LLM 配置、确认enabled与is_default标记符合预期再创建 Agent 进行绑定即可让聊天 Agent 平滑接入大模型能力。小结与最佳实践测试先行接入任何新模型前先调用POST /api/n9e/ai-llm-config/test用待填参数实测利用结构化错误auth / endpoint_not_found / rate_limited 等快速定位是密钥、地址还是模型名的问题OpenAI 兼容接口的api_url应包含/v1路径。密钥保护充分利用掩码机制——GET 返回的api_key是掩码形态更新与测试接口都能识别掩码回传并自动使用真实密钥前端无需也无法回写明文。推理模型适配gpt-5/o1/o3/o4系列与 Azure 自定义部署名场景下token 上限字段会自动路由/兜底切换为max_completion_tokens无需手工干预探测时截断即健康不必因空正文误判失败。默认配置策略首条配置自动成为默认后续可通过is_default调整默认配置会兜底给未绑定模型的 Agent请保持其enabledtrue。通过本文的接口清单与源码级解析你可以安全地将任意 OpenAI、Claude 或 Gemini 兼容的大模型服务接入 Nightingale并在接入全流程中获得明确的错误定位能力。【免费下载链接】nightingaleNightingale is to monitoring and alerting what Grafana is to visualization.项目地址: https://gitcode.com/GitHub_Trending/ni/nightingale创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考