跳到主要内容

提供商

提供商把你的应用连接到模型后端。它把 GDK 的消息和工具定义转换成后端的请求格式,再把响应转换回共享的消息和用量类型。智能体的其余部分不需要了解每个服务的传输协议。

提供商和模型是两个独立的选择。提供商知道如何访问某个服务;ModelConfig 则选择模型和请求设置。你可以直接用提供商完成一次补全,也可以把它交给状态机中的 InferenceRunner。

One provider interface, different model backendsAn application or InferenceRunner sends GDK requests through the Provider interface and receives a MessageStream. An HTTP provider connects to a hosted API or local model server. LocalInferenceProvider runs a model inside the application process.Your applicationor InferenceRunnerProviderOne contract for model callsHTTP providerOpenAI, Ollama, etc.Local inferenceLocalInferenceProviderHosted API orlocal model serverModel in yourapplication processGDK requestMessageStreamChoose an implementation

提供商契约​

Provider trait 位于 goose-provider-types 中。它的核心方法是 stream:给定模型配置、系统提示词、对话消息和工具 schema,它返回一个 MessageStream。文本可以分成小块到达;工具调用在其参数组装完成后才发出。这个流还可以携带用量信息和错误。

默认的 complete 方法会把流收集成一条消息和一份用量记录。提供商还可以报告模型清单、上下文限制、推理能力,以及它们是否自己管理上下文。统一的接口并不意味着每个模型都支持相同的内容或工具:请选择支持你的应用所需能力的模型。

例如,在一个返回 anyhow::Result 的异步 Rust 函数中,直接补全可以写成下面这样。请在 goose-providers 上启用某个 TLS 特性,以便建立 HTTPS 连接:

use goose_provider_types::{
base::Provider,
conversation::message::Message,
model::ModelConfig,
};
use goose_providers::{
api_client::{ApiClient, AuthMethod},
openai::OpenAiProvider,
};

let client = ApiClient::new_with_tls(
"https://api.openai.com".into(),
AuthMethod::BearerToken(std::env::var("OPENAI_API_KEY")?),
None,
)?;
let provider = OpenAiProvider::new(client);
let model = ModelConfig::new(std::env::var("OPENAI_MODEL")?);
let messages = [Message::user().with_text("Say hello in one sentence.")];

let (reply, usage) = provider
.complete(&model, "Answer concisely.", &messages, &[])
.await?;

这是一次模型调用,不是一次智能体运行。提供工具 schema 可以让模型请求工具,但并不会执行它们。工具的执行属于你的应用或某个操作。

GDK 自带的实现​

goose-providers 包含 OpenAI、Anthropic、Google Gemini、Azure AI Foundry、Databricks、Snowflake、OpenRouter、Ollama 以及兼容 OpenAI 的端点的实现。它重新导出了共享的提供商类型,因此使用这些实现的应用可以从同一个 crate 导入公共类型。

许多其他服务使用内置的声明式定义,包括 Groq、Mistral、Together、Cerebras、DeepSeek 和 LM Studio。这个 crate 还为实时会话和语音、以及带类型的决策请求提供了单独的接口。它们对应不同的交互模式,并不都能与文本补全的 Provider trait 互换调用。

提供商参考列出了可用的模块和特性开关。凭据和 HTTP 身份验证见身份验证。

声明式提供商​

如果某个服务已经使用受支持的协议,一份端点定义可能就够了。声明式提供商选择 OpenAI、Anthropic 或 Ollama 引擎,然后提供端点、配置键、模型元数据,以及可选的请求头或行为开关。这样就不必为每个使用相同协议的服务编写 Rust 实现。

定义可以随应用一起打包,也可以在运行时加载。例如,下面这份定义描述了一个由应用控制的、兼容 OpenAI 的端点。请把示例 URL 和模型元数据替换为真实的值:

{
"name": "my-service",
"display_name": "My model service",
"engine": "openai",
"base_url": "https://models.example/v1/chat/completions",
"api_key_env": "MY_SERVICE_API_KEY",
"models": [
{
"name": "my-model",
"context_limit": 32768
}
],
"dynamic_models": false
}

用 declarative::from_json 创建提供商,或用 deserialize_provider_config 检查定义。EnvKeyResolver 从环境变量读取凭据;你的应用也可以为自己的凭据存储提供另一个 KeyResolver。load_custom_providers 从目录中读取定义。请把这些定义视为可信配置:它们决定请求和凭据发往何处,还可以包含获取凭据的命令。

本地模型与本地提供商​

使用运行在同一台机器上的模型有两种方式:

方式你的应用连接到什么
本地模型服务器Ollama 或兼容 OpenAI 的 HTTP 端点,例如由 LM Studio 提供的端点。模型加载和推理由服务器负责。
进程内本地推理来自 goose-local-inference 的 LocalInferenceProvider,可通过 goose-providers 的 local-inference 特性使用。由你的进程加载并运行模型。

进程内推理使用 llama.cpp 运行 GGUF 模型,在 Apple 芯片上可选支持 MLX。模型可以通过本地文件路径选择;可选的 Hugging Face 支持增加了模型发现、下载和已缓存模型清单。CUDA、Vulkan 和 MLX 特性用于选择相应的后端,并有原生构建要求。

启用本地推理后,提供商仍然实现同一份契约:

use goose_providers::local_inference::LocalInferenceProvider;

let provider = LocalInferenceProvider::from_env().await?;
let model = ModelConfig::new("/absolute/path/to/model.gguf");

你可以调用 stream 或 complete,也可以像上文那样把它用于智能体推理。模型在本地运行,并不保证内存放得下,也不保证工具调用可靠。local-inference crate 负责聊天模板、解析、模型驻留和淘汰;选择哪个模型以及何时使用它,仍由你的应用决定。lifewiki 是一个带离线路径的示例。

引擎、特性和模型管理 API 见 local-inference 参考。

实现你自己的提供商​

当后端的协议或行为无法用现有实现或声明式定义表示时,就编写提供商。需要实现 get_name 和 stream;complete 和若干发现类方法有默认实现。如果只需要这份契约,就依赖 goose-provider-types,并在合适的地方使用 goose-providers 中的请求和格式化辅助函数。

把后端的输出规范化为 GDK 消息,在发出之前先组装好工具调用,保留用量信息,并把失败映射为 ProviderError。请如实报告能力和上下文限制,不要因为文本响应成功就假定它支持工具、图像或推理。特定于提供商的身份验证可以通过 ApiClient 和 AuthProvider 单独处理。

完整的 trait 见 goose-provider-types::base。如需阅读现有实现,可以从提供商源码开始。