we0agent

Guides

We0Model

用模型卡片与 provider 配置封装 LangChain chat model 的运行时模型对象。

概览

We0Model 是 SDK 在运行时真正使用的模型对象。它把两层信息绑在一起:

  • ModelCard:声明式的模型卡片,描述模型 id、能力上限、默认采样参数与 SDK 选项。
  • chat_model:由 LlmFactory 根据卡片实例化出的 LangChain BaseChatModel

模型不直接构造。常规链路是先用 ProviderCard 描述一个 provider 及其下挂模型,再通过 provider.find_model(...) 取到 ModelCard,最后交给 LlmFactory.create_model(...) 得到 We0Model,传入 We0Agent

最小定义顺序

第一步定义 provider 和模型卡片:

import os

from we0agent.domain.models.model import We0Model, ModelCard, ProviderCard
from we0agent.sdk.langchain.llm.llm_factory import LlmFactory

provider = ProviderCard(
    id="openai",
    name="OpenAI",
    family="openai",
    api_key=os.environ["OPENAI_API_KEY"],
    models=[
        ModelCard(
            id="gpt-5.4-mini",
            name="GPT-5.4 Mini",
            context=400_000,
            max_tokens=128_000,
            temperature=1.0,
        ),
    ],
)

第二步取出模型卡片并构造运行时 We0Model

card = provider.find_model("gpt-5.4-mini")
model: We0Model = LlmFactory.create_model(card)

得到的 model 即可直接传给 We0Agent(参见 We0Agent)。

agent = We0Agent(
    name="assistant",
    model=model,
    system_prompt=system_prompt,
)
Mermaid
Rendering diagram...

ModelCard

ModelCard 是一张声明式模型卡片,描述单个模型的标识、能力与默认参数。它本身不持有 provider 配置,而是通过 provider 属性回指所属的 ProviderCard(由 ProviderCard 在初始化时自动绑定)。

字段类型必填默认说明
idstr模型标识,会作为底层 SDK 的 model 参数下发。
namestr模型展示名称。
max_tokensint | NoneNone模型默认最大输出 token 数。
contextint | NoneNone模型上下文窗口大小。
temperaturefloat | NoneNone模型默认温度参数。
enabledboolTrue模型是否启用。
headersdict[str, str]{}模型默认请求头。
optionsJsonObject{}透传给底层 SDK 的默认选项,会以 **options 展开进 chat model 构造。

provider 是只读属性,返回绑定的 ProviderCard(未绑定时为 None)。一般不需要手动设置——把 ModelCard 放进 ProviderCard.models 后会自动回填。

options 是 provider 专属的逃生口。它直接展开进对应 LangChain chat model 的构造参数,因此具体可用键取决于 provider family(如 OpenAI 的 reasoning、Anthropic 的 thinking、Google 的 thinking_budget、DeepSeek 的 reasoning_effort)。

ModelCard(
    id="claude-sonnet-4-6",
    name="Claude Sonnet 4.6",
    context=1_000_000,
    max_tokens=64_000,
    temperature=1.0,
    options={
        "effort": "high",
        "thinking": {"type": "enabled", "budget_tokens": 56_000},
    },
)

ProviderCard

ProviderCard 描述一个模型 provider 及其下挂的模型列表。它持有连接信息(base_url / api_key)与 family 归属,并负责把自身回填到每个 ModelCard.provider

字段类型必填默认说明
idstrprovider 标识。
namestrprovider 展示名称。
familystrprovider 家族标识,决定底层 chat model 类型,取值见下表。
base_urlstr | NoneNoneprovider 基础地址,可指向自建网关或兼容端点。
api_keystr | NoneNoneprovider API 密钥。
enabledboolTrueprovider 是否启用。
modelslist[ModelCard][]provider 下挂的模型列表。

初始化行为与约束

  • family 必须是受支持的模型家族,否则在构造时直接抛出 KeyError。支持的 family 取值来自 LangChain 内置 provider 列表,本 SDK 当前实现了下表四种。
  • 构造完成后,列表里的每个 ModelCard 都会被自动绑定到该 provider(model.provider 回指 self),无需手动设置。
family底层 chat model依赖包
openaiChatOpenAIlangchain_openai
anthropicChatAnthropiclangchain_anthropic
google_genaiChatGoogleGenerativeAIlangchain_google_genai
deepseekEnhancedChatDeepSeeklangchain_deepseek

注意:family 是家族标识,与 id 是两个概念。id 可以自定义(例如 "my-openai-gateway"),但 family 必须落在受支持取值上。Google provider 的 family 是 google_genai,不是 google

find_model

find_model(model_id)ModelCard.idmodels 中查找模型卡片,命中即返回;未命中抛出 KeyError

card = provider.find_model("gpt-5.4-mini")  # 命中返回 ModelCard
provider.find_model("does-not-exist")        # 抛出 KeyError

We0Model

We0Model 是运行时模型对象,由 LlmFactory.create_model(...) 产出,包含两个字段:

字段类型必填说明
cardModelCard当前运行时模型对应的模型卡片。
chat_modelBaseChatModel当前运行时实际使用的 LangChain chat model 实例。

它在卡片之上提供了一组便捷属性:

属性类型说明
idstr等价于 card.id
namestr等价于 card.name
providerProviderCard | None等价于 card.provider
profileModelProfile | None底层 chat model 的能力画像。
context_windowint解析后的上下文窗口大小,见下方解析规则。
max_output_tokensint解析后的最大输出 token 数,见下方解析规则。

能力解析规则

context_windowmax_output_tokens 不是简单读字段,而是带回退逻辑:

  • context_window:优先取 card.context(需 > 0);否则回退到 profile["max_input_tokens"](需为正整数);两者都缺失时抛出 ValueError
  • max_output_tokens:优先取 card.max_tokens(需 > 0);否则回退到 profile["max_output_tokens"](需为正整数);两者都缺失时抛出 ValueError

易错点:如果模型卡片没有显式填写 context / max_tokens,且底层 profile 也未声明对应能力,访问这两个属性会直接抛 ValueError。建议在 ModelCard 上显式声明能力上限,避免运行期才暴露问题。

LlmFactory

LlmFactory 负责把 ModelCard 实例化为可调用的模型。两个静态方法:

方法返回说明
create_chat_model(model_card)BaseChatModel按 provider family 构造底层 LangChain chat model。
create_model(model_card)We0Modelcreate_chat_model 之上封装出运行时 We0Model

create_chat_model

create_chat_model 读取 model_card.provider,按 family 分派到对应的 LangChain chat model:

  • provider 为 None 时抛出 ValueError(卡片未绑定 provider)。
  • family 不在受支持取值内时抛出 ValueError(不受支持的 family)。

构造各 chat model 时统一应用以下约定:

  • max_retries=0:工厂层不做重试,重试与错误恢复交由上层引擎处理。
  • model_card.options**options 展开进构造参数,作为 provider 专属能力的逃生口。
  • OpenAI / Anthropic / DeepSeek 设置 stream_usage=True,以便在流式过程中拿到 usage 统计。

各 family 的参数映射如下:

familymodel 参数输出上限参数api_key 处理base_url
openaimodelmax_completion_tokensapi_keybase_url
anthropicmodel_namemax_tokens_to_sampleapi_key(转为 SecretStrbase_url
google_genaimodelmax_output_tokensgoogle_api_key
deepseekmodelmax_tokensapi_key

注意:google_genaideepseek 的工厂实现不接收 base_url,即便 ProviderCard.base_url 有值也不会被传入。temperature 在四种 family 下都会从 model_card.temperature 透传。

create_model

create_model 是常规入口。它先调用 create_chat_model 得到底层模型,再封装为 We0Model

from we0agent.sdk.langchain.llm.llm_factory import LlmFactory

model = LlmFactory.create_model(card)
# 等价于:
# We0Model(card=card, chat_model=LlmFactory.create_chat_model(card))

端到端示例

下面把 provider 声明、模型构造、agent 装配串起来:

import os

from we0agent.domain.models.model import We0Model, ModelCard, ProviderCard
from we0agent.sdk.langchain.llm.llm_factory import LlmFactory


def create_anthropic_model(model_id: str = "claude-sonnet-4-6") -> We0Model:
    provider = ProviderCard(
        id="anthropic",
        name="Anthropic",
        family="anthropic",
        api_key=os.environ["ANTHROPIC_API_KEY"],
        models=[
            ModelCard(
                id="claude-sonnet-4-6",
                name="Claude Sonnet 4.6",
                context=1_000_000,
                max_tokens=64_000,
                temperature=1.0,
                options={
                    "effort": "high",
                    "thinking": {"type": "enabled", "budget_tokens": 56_000},
                },
            ),
        ],
    )
    # find_model 命中后交给工厂;未命中会抛 KeyError
    return LlmFactory.create_model(provider.find_model(model_id))


model = create_anthropic_model()
print(model.id, model.context_window, model.max_output_tokens)

构造好的 We0Model 即可作为 We0Agent(model=...) 的入参。模型如何参与流式调用、prompt caching 与结构化输出,参见 StreamingSystemPrompt

On this page