news 2026/9/8 22:48:21

goose 接入 Azure AI Foundry:三种端点类型、协议路由与部署元数据解析实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
goose 接入 Azure AI Foundry:三种端点类型、协议路由与部署元数据解析实战

goose 接入 Azure AI Foundry:三种端点类型、协议路由与部署元数据解析实战

【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose

本文以 goose 的azure_foundry提供商为核心,完整讲解如何把 goose 会话接入 Azure AI Foundry 的 Project / Resource / MaaS 三类端点:包括全部配置环境变量与取值前提、认证优先级(Entra 令牌 → API Key → Azure CLI)、基于modelPublisher的协议路由机制、部署元数据对上下文窗口的解析,以及常见 401/403 与"列不出部署"问题的排查方法。读完后,你可以直接在自己的 Foundry 项目中配置 goose 会话,并理解每次请求在底层被路由到哪条推理协议、能力参数从哪里来。

一、三种端点类型与对应的推理接口

azure_foundry提供商把 goose 连接到 Azure AI Foundry 的模型部署。它区分三种端点形态,每种形态的推理接口(inference surface)不同:

端点类型端点形态推理接口
Foundry 项目(Project)https://<resource>.services.ai.azure.com/api/projects/<project>通过部署发现 + 按发布者(publisher)感知路由
Foundry 资源(Resource)https://<resource>.services.ai.azure.comOpenAI 模型走 Responses,Claude 走 Anthropic Messages,伙伴模型走 Chat Completions
MaaS / Serverlesshttps://<deployment>.<region>.models.ai.azure.com对该端点绑定的模型使用 Chat Completions

端点类型的识别并不依赖任何额外配置,而是由 goose 在解析AZURE_FOUNDRY_ENDPOINT时自动完成。实现位于 endpoint_kind:

  • URL 中包含/api/projects/子串 →Project端点;
  • 否则主机名以.services.ai.azure.com结尾 →Resource端点;
  • 其余情况 →MaaS端点。

这一点在测试endpoint_type_is_detected中有直接验证(crates/goose-providers/src/azure_foundry.rs#L791-L809),三类 URL 各归其位。

对 Project 端点,goose 会用GET /deployments发现项目内的全部模型部署;部署名可以被自定义,goose 依据返回的modelPublisher字段选择协议,并依据modelName解析上下文窗口等模型元数据。Resource 端点不提供项目级部署发现接口,goose 只能按模型名/部署名前缀识别模型族:gpt-5*和支持的 o 系列走 Responses、claude-*走 Anthropic Messages、其余走 Chat Completions。如果你的部署是自定义别名且无法从名字判断模型族,建议使用 Project 端点。

二、配置:环境变量与 goose configure

变量是否必填说明
AZURE_FOUNDRY_ENDPOINT完整的 Foundry 项目或 MaaS 端点
AZURE_FOUNDRY_API_KEYAPI Key;省略时使用 Azure CLI 凭证
AZURE_FOUNDRY_MODEL仅 MaaS 必填绑定到所配置 MaaS 端点的模型名
AZURE_FOUNDRY_AD_TOKEN预取的 Microsoft Entra 访问令牌;优先级高于 API Key
AZURE_FOUNDRY_API_VERSION部署发现 API 版本;Project 端点默认v1

运行goose configure,选择Configure Providers,再选择Azure AI Foundry,即可交互式配置;也可以在启动 goose 之前直接设置环境变量:

export AZURE_FOUNDRY_ENDPOINT="https://my-resource.services.ai.azure.com/api/projects/my-project" export AZURE_FOUNDRY_API_KEY="<key>" goose session

对于 MaaS 端点:

export AZURE_FOUNDRY_ENDPOINT="https://my-deployment.eastus.models.ai.azure.com" export AZURE_FOUNDRY_API_KEY="<key>" export AZURE_FOUNDRY_MODEL="<model-bound-to-this-endpoint>" goose session

MaaS 端点只暴露一个已部署模型,因此AZURE_FOUNDRY_MODEL对这类端点是硬性要求。这一点在构造阶段就会强制校验:AzureFoundryProvider::create 中,当端点被识别为 MaaS 而maas_model为空时,直接返回错误AZURE_FOUNDRY_MODEL is required for MaaS endpoints

配置项在源码中的定义

这些变量在 ProviderDescriptor::metadata 中注册为ConfigKey,默认模型为Phi-4,并内置一份AZURE_FOUNDRY_KNOWN_MODELS已知模型清单(Phi-4、Meta-Llama-3.3-70B-Instruct、Mistral-large-2411、Cohere-command-r-plus、DeepSeek-R1/V3、glm-4.7、Kimi-K2-Instruct、claude-sonnet-4-6、gpt-5、o3 等)。当端点不是 Project 端点时(即 Resource 或 MaaS 未显式配置模型),fetch_supported_models返回的正是这份清单(crates/goose-providers/src/azure_foundry.rs#L458-L478)。

"已配置"的判定逻辑在 azure_foundry_configured_values:端点非空,且(非 MaaS 端点,或 MaaS 端点同时提供了模型名)才视为该提供商可用。

三、认证优先级与资源标识

认证按如下顺序选择:

  1. AZURE_FOUNDRY_AD_TOKEN(预取的 Entra 令牌)
  2. AZURE_FOUNDRY_API_KEY
  3. Azure CLI 默认凭证链

当两者都未配置时,先执行az login再启动 goose 即可:

az login

这条优先级链直接对应 AzureAuth::new_with_resource 中的模式匹配:(Some(token), _) => BearerToken(None, Some(key)) => ApiKey(None, None) => DefaultCredential

Project 与 Resource 端点为https://ai.azure.com申请令牌,MaaS 端点则申请https://ml.azure.com的令牌。两个资源标识符定义在 azure_foundry_def.rs(AZURE_PROJECT_ENTRA_RESOURCE/AZURE_MAAS_ENTRA_RESOURCE),并在from_env中按端点类型选择。

认证头的实现细节

不同端点/凭证组合使用不同的请求头策略,见 from_env:

  • API Key 用于 Project/Resource:以api-key头发送,并启用"同源重定向"限制;
  • API Key 用于 MaaS:改用标准Authorization: Bearer头;
  • API Key 用于 Anthropic 面(/anthropic:使用x-api-key头;
  • Entra 令牌:以Authorization: Bearer <token>发送。

关于重定向限制,值得单独说明:当认证方式是 API Key 时,客户端会限制重定向只在同源内跟随(configured_client 中的with_same_origin_redirects)。测试 foundry_api_keys_do_not_follow_cross_origin_redirects 验证了这一点:若源服务器把带api-key/x-api-key头的请求 307 重定向到其他域,客户端会直接报错,且目标域不会收到任何请求——这是为了防止 API Key 通过跨域重定向泄漏。同域重定向则正常跟随(foundry_api_keys_follow_same_origin_redirects测试)。

四、协议路由:publisher 感知与降级策略

Project 端点的三路分发

对 Project 端点,goose 依据 Azure 返回的部署元数据为每个部署选择协议:

  • 发布者OpenAI且为 Responses 兼容模型(gpt-5*与支持的 o 系列)→POST /openai/v1/responses
  • 发布者AnthropicPOST /anthropic/v1/messages
  • 更老的 OpenAI 模型与其他所有发布者 →POST /openai/v1/chat/completions

核心路由函数是 inference_route。测试 routing_matrix_uses_endpoint_publisher_and_underlying_model 给出了完整的判定矩阵:

端点发布者底层模型路由结果
MaaSOpenAIgpt-5MaasChatCompletions
MaaSAnthropicclaude-sonnet-4-6MaasChatCompletions
ProjectOpenAIgpt-5ProjectResponses
ProjectOpenAIo3-miniProjectResponses
ProjectOpenAIgpt-4oProjectChatCompletions
ProjectPartnergpt-5ProjectChatCompletions
ProjectAnthropic任意AnthropicMessages

其中"Responses 兼容模型"的判定来自 is_openai_responses_model,正则(?i)(?:^|[-/])(?:o\d+(?:$|-)|gpt-5(?:$|[-.]))同时匹配gpt-5gpt-5.x(如gpt-5.6-sol)以及o1/o3-mini这类 o 系列命名。

注意路由的语义:路由由发布者和底层模型共同决定,与部署的显示名无关。比如 Partner 发布者的gpt-5部署仍然走 Chat Completions(因为协议选择以 publisher 为准),而 Anthropic 发布者下的任何部署都走 Messages 面。

三个推理客户端的构建

Provider 构造时会同时准备最多四个 HTTP 客户端(AzureFoundryProvider::create):

  1. Chat 客户端:OpenAI 兼容协议。Project/Resource 端点的路径前缀是openai/v1/,MaaS 端点是v1/——这与文档中"MaaS 端点始终走/v1/chat/completions"一致;
  2. Responses 客户端:仅非 MaaS 端点构建,base path 为openai/v1/responses,并跳过规范化过滤(skip_canonical_filtering);
  3. Anthropic 客户端:仅非 MaaS 端点构建,请求发往https://<resource>.services.ai.azure.com/anthropic(代码中取端点的/api/projects/之前的部分作为 hub),并附加anthropic-version头;
  4. Deployments 客户端:用于调用GET /deployments做部署发现。

部署发现不可用时的降级

当部署发现暂时不可用时,gpt-5*/o 系列这类可识别的 Responses 兼容名与claude-*名仍会落到各自的 native 协议,其余名字走 Chat Completions。

从源码结构看,这套降级由两层缓存机制支撑(DeploymentCache 与 deployment_for):

  • 部署元数据带 60 秒 TTL(DEPLOYMENT_METADATA_TTL_SECS),单次拉取有 5 秒超时(DEPLOYMENT_METADATA_TIMEOUT_SECS),避免元数据接口抖动阻塞推理请求;
  • 缓存区分两种用途:上下文发现ContextDiscovery)和推理路由InferenceRouting)。即使上次拉取失败,空缓存也允许用于上下文发现(避免每次推理都重试拖慢响应),但推理路由会在 TTL 内重试拉取;
  • 测试 routing_retries_cached_deployment_failures 精确验证了这个不对称行为。

部署列表拉取:分页与 api-version

fetch_deployments 实现了一个标准的 OData 风格分页循环:

  • 首次请求deployments?api-version=<version>,其中 version 取AZURE_FOUNDRY_API_VERSION,Project 端点缺省为v1
  • 响应体的value数组中每项含name(部署名)、modelName(底层模型)、modelPublisher(发布者),缺失modelName时回退为部署名,缺失modelPublisher时用模型名前缀推断(ModelPublisher::from_model_name);
  • 跟随nextLink翻页,并用 with_api_version 保证分页链接上携带同一api-version(若链接已带该参数则不覆盖)。测试pagination_link_keeps_api_version覆盖了两种情形。

测试 deployment_discovery_is_paginated_and_preserves_underlying_model 用 wiremock 模拟了两页部署数据,验证翻页与name → modelName/publisher映射的完整性。

五、模型元数据:上下文窗口、能力与定价

部署 API 返回namemodelNamemodelVersionmodelPublisher。goose 用底层模型名modelName)在内置模型目录中查找上下文窗口,部署显示名只作为ModelInfo.name保留。核心逻辑在 model_info_for_deployment:

  • 先按原始名、小写名、以及剥离-high/-low等推理强度后缀后的基名,三次尝试在 canonical 目录中查找(配合extract_reasoning_effort解析 effort 后缀);
  • 查到后取其limit.context作为context_limitreasoning取目录值、否则按模型名启发式判定;
  • 显式的GOOSE_CONTEXT_LIMIT或会话级覆盖始终优先。

测试给出的具体数值可以作为验证依据:

  • deployment_metadata_enriches_context_without_pricing:部署名production-chat、底层gpt-5,解析出上下文窗口400_000,且input_token_cost/output_token_cost均为None
  • gpt_5_6_sol_uses_its_full_context_window:gpt-5.6-sol的上下文窗口为1_050_000且标记为推理模型;
  • custom_deployment_context_uses_underlying_model:通过get_context_limit("production-chat")得到的 400K 窗口完全来自底层modelName的目录查表;
  • caller_override_precedes_deployment_metadata:调用方显式传入Some(64_000)时直接返回 64K,且完全不会发起部署发现请求——即覆盖值优先于元数据。

关于定价:Azure 的计费取决于区域、SKU、合同与部署类型,deployments API 不提供可靠的每 token 价格,因此该提供商不会为发现的部署附加任何价格信息(对应上面input_token_cost: None等字段)。

六、关键实战细节:自定义部署名的"别名保留"

这是该提供商最有价值的行为之一:你在会话中使用的模型名始终是你的部署名(别名),goose 不会把它重写成底层模型名;底层模型名仅用于内部的能力判断(上下文窗口、max_tokens、是否推理模型等)。

以 Project 端点的stream实现为例(crates/goose-providers/src/azure_foundry.rs#L534-L609):

  • wire_model:发往 Azure 的请求体中的model字段,即部署别名;
  • capability_model:取自部署元数据的modelName,用于套用 canonical 能力上限;
  • 三个路由分支都同时携带两者:stream_for_model(&capability_config, &wire_model, capability_model, ...)

测试 custom_openai_deployment_uses_alias_and_underlying_capabilities 验证了部署名production-chat(底层gpt-5):请求确实命中/openai/v1/responses,且请求体model == "production-chat"。suffixed_deployment_without_metadata_is_preserved_on_the_wire 则验证了另一种边缘场景:部署发现返回空列表时,名为gpt-5-high的别名既保留在线上报文中,又通过名字前缀解析出 400K 上下文——即"无元数据时按可识别名字前缀降级"的完整闭环。

对 Anthropic 面,anthropic_alias_uses_underlying_output_limit_and_preserves_override 展示了 max_tokens 的解析:部署claude-prod(底层claude-sonnet-4-6)默认输出上限取底层模型的 canonical 值128_000,而用户显式设置max_tokens: 12_345时则原样透传。

此外,在会话恢复(session resume)路径上,deserialize_session_model_config 对azure_foundry做了特殊处理:恢复model_namerequest_params(例如thinking_effort),确保带后缀的部署别名(如gpt-5-high)在跨会话恢复后不被规范化改写;crates/goose/src/model_config.rs#L42-L48 也对该提供商跳过了常规的 canonical 上限套用以保持部署别名原样。

七、排障手册

401 / 403

  • 确认 API Key 属于你所配置的端点;
  • 使用 Entra 认证时,重新执行az login,并确认你的身份对该 Foundry 项目有访问权限;
  • 不要混用:Project 端点的 Key 不能用于 MaaS 端点,反之亦然(两者的资源标识与认证头策略都不同,见上文第三节的api-key/Bearer差异)。

另外,401 也可能出在部署发现接口上:fetch_supported_models对 Project 端点会把发现接口的认证失败原样向上抛出(测试 project_inventory_failure_is_propagated),表现为模型列表拉取直接失败——此时先检查端点 Key 是否有效。

列不出部署

  • 确认端点 URL 中包含/api/projects/<project>后缀(缺少它会让你落到 Resource 端点分支,从而返回内置的已知模型清单而非项目部署列表);
  • 确认项目中确实存在模型部署;
  • 如果项目使用了非默认部署发现 API 版本,设置AZURE_FOUNDRY_API_VERSION(注意该参数只影响GET /deployments的查询,不影响推理请求)。

自定义部署名路由到了错误的协议

刷新提供商的模型列表,让 goose 重新拉取部署元数据(元数据缓存 60 秒过期,且推理路由用途在拉取失败后 TTL 内会重试)。没有部署元数据时,路由只能依据可识别的模型名前缀——所以给部署起gpt-5*/o\d+/claude-*之外的自定义名字时,务必确保发现接口可用。

八、小结:一张表看清请求走向

把上面各节的规则合并,任一goose session请求的实际走向如下:

场景请求路径(相对端点)请求体model字段协议选择依据
Project + OpenAI 发布者 +gpt-5*/o 系列<endpoint>/openai/v1/responses部署别名modelPublisher+ 底层模型名
Project + Anthropic 发布者<hub>/anthropic/v1/messages部署别名modelPublisher
Project + 其他(含老版 OpenAI、伙伴模型)<endpoint>/openai/v1/chat/completions部署别名modelPublisher
Resource(无部署发现)与 Project 相同的三个接口模型/部署名仅模型名前缀
MaaS<endpoint>/v1/chat/completionsAZURE_FOUNDRY_MODEL绑定的模型固定 Chat Completions

理解这套"别名保留、能力按底层模型解析、协议按发布者路由"的设计后,你可以在 Foundry 中随意重命名部署(例如按环境区分的production-chatgpt-5-high),而不必改动 goose 侧的任何模型声明;上下文窗口、输出上限等能力仍会正确解析。相关实现集中在 crates/goose-providers/src/azure_foundry.rs(端点识别、路由、部署缓存与全套测试)、crates/goose/src/providers/azure_foundry_def.rs(环境变量装配与认证头策略)和 crates/goose/src/providers/azureauth.rs(凭证优先级与令牌获取)。

【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 22:46:56

计算机毕业设计之jsp图书座位预约系统

“互联网”的战略实施后&#xff0c;很多行业的信息化水平都有了很大的提升。但是目前很多图书馆日常业务仍是通过人工管理的方式进行&#xff0c;需要在图书座位预约投入大量的人力进行很多重复性工作&#xff0c;这样就浪费了许多的人力物力&#xff0c;工作效率较低&#xf…

作者头像 李华
网站建设 2026/9/8 22:46:24

OpenCode安装配置实战:如何用它接管老项目并替代Claude Code

OpenCode 让我把 Claude Code 彻底扔进了垃圾桶先说结论&#xff1a;OpenCode 是我目前用过的所有 AI 编程终端工具里&#xff0c;最接近"测试驱动开发"直觉的一个。它不像 Claude Code 那样动不动就自作主张改文件&#xff0c;也去掉了一堆华而不实的交互特效&#…

作者头像 李华
网站建设 2026/9/8 22:46:18

毫米波雷达点云聚类实战:DBSCAN调参与数据集选择指南

简介&#xff1a;面向毫米波雷达数据处理应用场景&#xff0c;提供聚类算法系列博文配套的代码和数据集&#xff0c;适合正在学习机器学习、雷达目标检测的开发者或研究人员。资源压缩包共40个文件&#xff0c;以8个脚本和32个文本数据集构成&#xff0c;总计848KB。脚本覆盖K均…

作者头像 李华
网站建设 2026/9/8 22:46:09

YOLOv5头盔佩戴检测系统:从数据集到部署的完整实战指南

简介&#xff1a;面向深度学习入门者与毕业设计学生&#xff0c;这是一套基于YOLOv5的头盔佩戴检测识别完整项目&#xff0c;覆盖数据标注、模型训练、推理部署与结果展示全流程&#xff0c;可直接用于工地安全帽佩戴检测场景。资源共77个文件、约23.72MB&#xff0c;包含13个P…

作者头像 李华
网站建设 2026/9/8 22:45:51

纯C语言实现LPC共振峰提取:完整流程与代码解析

简介&#xff1a;这是一份基于线性预测编码&#xff08;LPC&#xff09;的语音共振峰提取C语言实现&#xff0c;面向语音处理初学者、算法研究人员及嵌入式开发者&#xff0c;解决从语音信号中估计声道共振峰参数的问题。工程围绕杜宾递推、牛顿迭代、汉明窗分帧与端点检测展开…

作者头像 李华