OpenSRE 托管 LLM 运行时深度解析:Provider 路由、双传输架构与自定义厂商接入指南
【免费下载链接】opensreBuild your own AI SRE agents. The open source toolkit for the AI era.项目地址: https://gitcode.com/GitHub_Trending/op/opensre
OpenSRE(面向 AI 时代的开源 SRE Agent 工具包)将"调用哪个大模型厂商、走哪条传输通道、如何构建客户端"这套决策收敛在core/llm/包中,称为Hosted LLM Runtime。本文以 core/llm/AGENTS.md 为骨架,结合 factory.py、client_builders.py、transport_mode.py 等源码与 tests/core/runtime/llm 下的测试用例,完整讲清 provider 配置地图、原生 SDK 与 LiteLLM 双传输机制、单一路由决策链路、客户端缓存失效策略,并给出新增一个托管 API 厂商的分步操作手册,以及 Azure OpenAI、Google Vertex AI 两大强制走 LiteLLM 的特殊厂商接入细节。读完你可以独立回答"OpenSRE 的 LLM 请求到底由谁路由、如何切厂商、新厂商怎么接入"这三个问题。
包边界:Hosted LLM Runtime 负责什么
core/llm/是 agent 循环(ReAct loop)所使用的托管(hosted)LLM provider 客户端与运行时辅助的归属地。它的边界非常明确:
- 负责解析 provider 配置、决定传输方式(原生 SDK / LiteLLM)、构建并缓存各角色的 LLM 客户端;
- 不负责基于子进程的 CLI 厂商(Codex、Claude Code、Copilot、Pi 等)——这些由
integrations/llm_cli/单独管理。
换言之,凡是"通过 HTTP API 调用的云厂商模型",统一由core/llm/接管;凡是"启动一个命令行进程来对话"的厂商,走另一套 subprocess 适配器体系。两者在路由层通过cli_provider_registration汇合,这一点在下面的分发链路中会看到。
Provider 装配地图:每个文件管哪一段
原文档给出了 provider wiring 的权威对照表,这里完整保留并补充关键入口,方便你按图索骥:
| 文件 | 职责 |
|---|---|
| config/llm_models.py | 各 provider 的模型分层(reasoning / classification / toolcall)默认值、base URL,以及*_LLM_CONFIG形状;同时定义DEFAULT_MAX_TOKENS = 4096、DEFAULT_AZURE_OPENAI_API_VERSION = "2024-10-21"、DEFAULT_VERTEX_AI_LOCATION = "us-central1"、DEFAULT_OLLAMA_HOST = "http://localhost:11434"等常量 |
| config/llm_settings.py | 声明LLMProvider(provider 字符串字面量联合)、LLMSettings(Pydantic 严格校验模型)与基于环境变量的解析逻辑 |
| config/llm_auth/provider_catalog.py | 规范的ProviderSpec元数据:凭证种类(API key / CLI / ambient / local)、各类环境变量名,由向导、鉴权和运行时共同消费 |
| core/llm/factory.py | 唯一的路由入口:resolve_llm_route()、get_llm(role)、reset_llm_clients() |
| core/llm/client_builders.py | 为已解析的路由构建具体客户端:build_agent_client()、build_reasoning_client() |
| core/llm/providers/provider_registry.py | FIRST_PARTY_PROVIDERS表(models、max_tokens、LiteLLM 前缀、api-key 环境变量),SDK 与 LiteLLM 两侧的构建器都读这张表 |
| core/llm/transport_mode.py | OPENSRE_LLM_TRANSPORT(sdkvslitellm)与use_litellm_for_provider() |
| core/llm/internal/client_cache_key.py | 单例缓存失效键(transport, runtime_provider) |
| core/llm/providers/openai_compat_providers.py | OpenAI 兼容 provider 目录,以及模型 / base URL 的运行时解析 |
| core/llm/providers/azure_openai.py | Azure OpenAI 辅助:endpoint 归一化、deployment 选择、LiteLLM kwargs |
| core/llm/providers/vertex_ai.py | Vertex AI 辅助:project / location 解析、LiteLLM kwargs(走 ambient ADC 认证,无 API key) |
| core/llm/transports/litellm/routing.py | 按 provider 构建 LiteLLM 客户端(model 前缀、api_base、api_version) |
| core/llm/transports/litellm/clients.py | LiteLLMAgentClient/LiteLLMLLMClient,对litellm.completion的封装 |
| core/llm/transports/sdk/agent_clients.py | 原生 SDK 工具调用客户端(Anthropic、OpenAI、Bedrock、CLI-backed) |
| core/llm/transports/sdk/llm_clients.py | 原生 SDK 非 agent 客户端 |
| core/llm/shared/tool_schema_normalize.py | 严格工具调用适配器共享的 JSON Schema 归一化 |
| surfaces/shared/llm_setup/catalog.py | 上手指引(onboarding)元数据SUPPORTED_PROVIDERS与模型选项 |
| surfaces/shared/llm_setup/env_sync.py | provider / 模型选择变化时同步.env |
面向最终用户的完整配置与环境变量速查表见 docs/llm-providers.mdx,它同时覆盖 API key 型、云厂商与本地型、CLI 型三大类 provider 的LLM_PROVIDER取值、密钥环境变量与默认模型。
传输层:原生 SDK 与 LiteLLM 双通道
默认走原生厂商 SDK
传输方式由环境变量OPENSRE_LLM_TRANSPORT控制(定义在 transport_mode.py):
- 未设置或为
sdk(默认):走原生厂商 SDK 通道。Anthropic 用 Anthropic SDK、OpenAI 用 OpenAI SDK、Bedrock 用 boto3 / AnthropicBedrock / Converse,客户端类在core/llm/transports/sdk/下。 - 为
litellm:托管 API provider 统一路由到core/llm/transports/litellm/routing.py,由 LiteLLM 负责厂商适配。
use_litellm_for_provider()(transport_mode.py)决定"某个 provider 是否必须走 LiteLLM",其逻辑是:
return ( use_litellm_transport() # OPENSRE_LLM_TRANSPORT=litellm or is_azure_openai_provider(provider) # LLM_PROVIDER=azure-openai or is_vertex_ai_provider(provider) # LLM_PROVIDER=vertex-ai )两个永远走 LiteLLM 的例外
Azure OpenAI(LLM_PROVIDER=azure-openai)总是使用 LiteLLM——即使OPENSRE_LLM_TRANSPORT未设置。原因在于 Azure 用的是"资源 base URL + deployment 名称"模型,LiteLLM 的azure/<deployment>形式天然适合表达这种寻址。opensre onboard向导在选中 Azure 时会把OPENSRE_LLM_TRANSPORT=litellm写入.env;当切换到其他 provider 时,会删除该键,让其他厂商回到 SDK 路由(对应测试 test_factory.py 中的test_resolve_llm_route_azure_forces_litellm)。
Google Vertex AI(LLM_PROVIDER=vertex-ai)同样永远走 LiteLLM,模型串为vertex_ai/<model>,与 Azure 是同一套强制模式。测试 test_vertex_ai_routing.py 中的test_use_litellm_for_provider_is_always_true_for_vertex_ai直接断言了这一点。
此外,CLI-backed 厂商(codex、claude-code、copilot、pi、cursor、opencode、kimi等)无论该变量如何设置,都固定走各自的 subprocess 路径,LiteLLM 不适用于它们——这也是为什么resolve_llm_route()里 CLI 判断排在use_litellm判断之前。
custom-anthropic 的 SDK-only 限制
litellm/routing.py 中有一个_guard_sdk_only_provider()守卫:custom-anthropic使用 Anthropic SDK + base-URL 覆盖,不支持OPENSRE_LLM_TRANSPORT=litellm。若强制开启会直接抛错并提示:要么取消该变量(或设为sdk),要么改用custom-openai来代理 OpenAI 兼容端点。这是文档"custom-anthropic 忽略 LiteLLM"约束的源码落地。
单一路由决策:factory.py 的分发链路
原文档反复强调一个设计原则:所有路由决策只存在于一个地方。core/llm/factory.py的模块注释写得很直白:provider/transport 决策(CLI-backed vs LiteLLM vs 原生 SDK,以及具体厂商)在resolve_llm_route()中一次性解析,被所有角色复用——这样"一个 Azure/LiteLLM 路由修复"不可能在工具调用 agent 与 reasoning/classification/toolcall 客户端之间漂移。
四种角色(LLMRole)
factory.py 定义了与具体厂商无关的模型分层角色:
class LLMRole(StrEnum): AGENT = "agent" # 工具调用 ReAct(action, gather) REASONING = "reasoning" # 流式回答 / 复杂推理 CLASSIFICATION = "classification" # 中档分类器 TOOLCALL = "toolcall" # 轻量工具选择 / 行动规划角色只决定"构建哪个客户端家族":LLMRole.AGENT构建工具调用客户端(tool_schemas/invoke),其余角色按模型分层构建流式推理客户端(invoke/invoke_stream/with_structured_output)。非 agent 角色通过_MODEL_TYPE_BY_ROLE映射到ModelType.REASONING / CLASSIFICATION / TOOLCALL(factory.py),即 settings 中*_model属性的后缀。
完整分发流程
原文档给出了这一权威调用链,逐字保留并标注落点:
get_llm(role) # role ∈ {AGENT, REASONING, CLASSIFICATION, TOOLCALL} # factory.py → resolve_llm_route() # the single provider/transport decision # factory.py → client_builders.build_agent_client(route) / build_reasoning_client(route, model_type) cli_provider_registration? → CLI-backed subprocess client use_litellm_for_provider? → build_litellm_*_client(settings, provider) # transports/litellm/routing.py else → native SDK client in transports/sdk/agent_clients.py or transports/sdk/llm_clients.pyresolve_llm_route()(factory.py)的实际逻辑是:
- 先查
config.account.account_llm_route():若存在已登录的 OpenSRE 账号代理路由,则强制provider=openai、use_litellm=False,走 SDK 通道直连账号代理端点(此时本地LLM_PROVIDER配置被账号路由覆盖); - 否则取
settings.provider作为运行时 provider; - 通过
_cli_provider_registration(provider)判断是否有 CLI 注册; - 通过
use_litellm_for_provider(runtime_provider)决定是否走 LiteLLM。
client_builders.py只负责"构建"不负责"决策"(client_builders.py):build_agent_client()优先 CLI → LiteLLM → 原生 SDK 三选一;build_reasoning_client()同构,但额外接收model_type分层参数,并在 LiteLLM 路径注入usage_callback=emit_usage。所有 SDK 路径内的导入都是惰性(函数内 import)的,避免模块导入期拉起整个 provider 栈,也满足项目的importlinter契约。
唯一缓存与失效策略
工厂内有一个进程级缓存(LLMClientCache,见 internal/client_cache.py),缓存键由current_llm_client_cache_key()(internal/client_cache_key.py)计算为(transport, runtime_provider):
- 键变化时(例如
transport或runtime_provider任一变化)整个缓存清空,而不是只清对应角色——因为角色间共享同一路由配置,任何配置变化都应让所有角色重建客户端; - 缓存内部用
threading.Lock保护:get()中的"检查键并清空"必须是原子的;store()若发现构建期间配置键已变化,会丢弃该客户端而非缓存它,避免(transport, provider)竞态条件下把旧配置的客户端服务给新配置的调用方(对应测试 test_client_cache.py 的test_store_drops_a_client_whose_config_changed_during_build); - REPL 的
/model命令与 wizard 的 env sync 会直接调用reset_llm_clients()主动清缓存(factory.py); - 已登录账号路由使用独立的缓存键
("sdk", f"account:openai:{base_url}:{model}"),与本地配置缓存隔离。
需要说明的一点是:文档与代码注释都强调"键是(transport, runtime_provider)二元组,不是仅 transport 单独变化"——例如从 SDK 切到 LiteLLM 而 provider 不变时,键从("sdk", "anthropic")变为("litellm", "anthropic"),同样触发全量失效。
接入新厂商:五步扩展手册
原文档的 "Adding a Hosted API Provider" 是这份指南最具操作价值的部分,下面逐步展开并补充源码落点。
第 1 步:注册 provider 字面量与校验
在 config/llm_settings.py 的LLMProvider字面量联合中追加新 provider 字符串,并在LLMSettings中加入对应字段与校验。值得注意的设计:LLMSettings采用非回退(non-falling-back)解析——配置了哪个 provider 就用哪个,缺失凭证会以校验错误显式暴露,而不是静默切换后端。_normalize_provider校验器还通过difflib.get_close_matches对拼写错误给出 "Did you mean ...?" 提示。
第 2 步:添加模型分层默认值
在 config/llm_models.py 的PROVIDER_MODEL_DEFAULTS字典中追加一行ProviderModelDefaults(provider 值、settings_key、reasoning / classification / toolcall 三档默认模型、可选 base_url)。三档模型按能力/成本排序的语义定义在LLMModelConfig的 docstring 中:
reasoning_model——最高能力模型,用于根因诊断等深度推理步骤;classification_model——中档模型,用于需要比轻量 toolcall 更强推理、又不值得上 reasoning 成本的任务(如交互式 shell 的意图分类);toolcall_model——轻量、低延迟模型,用于简单工具选择与行动规划。
若厂商是三档共用一个模型(如 Ollama),则设置single_model_settings=True;若必须显式指定模型(如 custom-openai / custom-anthropic),则设置requires_explicit_models=True(对应校验:缺少模型会直接报错,见 llm_settings.py)。
第 3 步:添加 ProviderSpec 与向导选项
在 config/llm_auth/provider_catalog.py 中追加ProviderSpec(value、label、credential_kind、api_key_env、model_env、toolcall_model_env、classification_model_env,以及可选的endpoint_env/api_version_env/project_env/location_env),并在 surfaces/shared/llm_setup/catalog.py 的SUPPORTED_PROVIDERS中补充对应的ProviderOption。
ProviderSpec.credential_kind有四种取值(provider_catalog.py),理解它就能预判向导与运行时的行为:
| CredentialKind | 含义 | 代表厂商 |
|---|---|---|
api_key | 用户提供 API key,由 OpenSRE 存储(凭证文件 / env) | Anthropic、OpenAI、DeepSeek…… |
cli | 厂商 CLI 自管鉴权,.env无需 key | Codex、Claude Code、Copilot、Pi…… |
ambient | 运行时从环境读取凭证(Bedrock IAM、Vertex ADC) | Bedrock、Vertex AI |
local | 本地宿主端点,看可达性而非密钥 | Ollama |
向导侧有另一套WizardCredentialKind(api_key/host/cli/none),通过WIZARD_TO_CATALOG_KIND映射表翻译到上述运行时枚举——注意两者刻意不合并,否则会把 Ollama 这种"本地宿主"误标为 ambient 环境凭证。
第 4 步:添加运行时构建逻辑
路由本身始终留在 factory.py,客户端构建在 client_builders.py,按厂商形态分四种情况:
- First-party provider(自带 SDK 模型 + LiteLLM 前缀):只需在
FIRST_PARTY_PROVIDERS(provider_registry.py)中加一行。SDK 与 LiteLLM 两侧的构建器都读这张表(env_prefix、max_tokens、litellm_prefix、api_key_env),因此无需新增 per-provider 分支——除非引入了全新的客户端类。当前表中已有三行:anthropic、openai、bedrock,测试 test_client_builders.py 的test_registry_lists_the_three_first_party_providers锁定这一集合。 - SDK 路径:在 core/llm/transports/sdk/llm_clients.py 和/或 core/llm/transports/sdk/agent_clients.py 中添加客户端类,由
client_builders.py中的构建器选择。 - LiteLLM 路径(可选或必需):registry 行已覆盖常规情况;只有非标准场景才需要在 core/llm/transports/litellm/routing.py 中加分支(例如 Azure 需要
api_base+api_version、Vertex 需要vertex_project/vertex_location)。 - OpenAI 兼容:在 providers/openai_compat_providers.py 的
OPENAI_COMPATIBLE_PROVIDERS目录注册(SDK 兼容路径),必要时同时在transports/litellm/routing.py注册(LiteLLM 路径)。该目录目前覆盖 openrouter、trustedrouter、deepseek、gemini、nvidia、minimax、groq、ollama、custom-openai,其中 MiniMax 固定temperature=1.0、Ollama 的 base URL 动态拼接为${OLLAMA_HOST}/v1。
第 5 步:同步 .env 与补测试
若引入新的非密钥环境变量,需要更新 surfaces/shared/llm_setup/env_sync.py:_provider_specific_keys()会收集一个 provider 拥有的全部 env 键(api key + 各类 model 键 + endpoint / api_version 键),切换 provider 时剥离旧 provider 的键;当 provider 需要持久化 URL / 版本设置时,把 endpoint 键保留在active_non_secret集合中。sync_reasoning_model_env()负责把 reasoning 模型写回.env并同步 runtime env 与 setup store。
测试统一放在tests/core/runtime/llm/下(test_factory.py、test_client_builders.py、test_azure_openai_routing.py、test_vertex_ai_routing.py、test_litellm_compat.py 等),若 onboarding 流程有变还需补 wizard 测试。
专题一:Azure OpenAI(azure-openai)
Azure 与公共 OpenAI 的关键差异在于:它使用deployment 名称(而非公共 OpenAI 模型 ID)和资源base URL。相关环境变量与语义如下:
| 变量 | 说明 |
|---|---|
AZURE_OPENAI_BASE_URL | 资源 URL,例如https://your-resource.openai.azure.com;校验时必填(缺失直接报错,见 llm_settings.py) |
AZURE_OPENAI_API_KEY | 资源密钥 |
AZURE_OPENAI_API_VERSION | API 版本,未设置时默认2024-10-21(DEFAULT_AZURE_OPENAI_API_VERSION) |
AZURE_OPENAI_*_MODEL | 存放用户在 Azure 资源中的deployment 名称,不是/openai/models里的模型 ID |
LiteLLM 模型串由azure_openai_litellm_model()生成,形如azure/<deployment>(azure_openai.py);resolve_azure_openai_request_kwargs()进一步返回litellm_model、api_base、api_version、api_key_env四个字段,由 litellm/routing.py 组装成LiteLLMAgentClient/LiteLLMLLMClient。测试 test_azure_openai_routing.py 断言了azure/gpt-5.4-mini与2024-10-21的完整装配。
完整配置示例(对应 docs/llm-providers.mdx 的 Azure 小节):
export LLM_PROVIDER=azure-openai export OPENSRE_LLM_TRANSPORT=litellm # opensre onboard 会自动写入 .env export AZURE_OPENAI_BASE_URL=https://your-resource.openai.azure.com export AZURE_OPENAI_API_KEY=... # 可选覆盖;缺省为 2024-10-21: # export AZURE_OPENAI_API_VERSION=2024-10-21 # deployment 名称(必须存在于你的 Azure 资源中): export AZURE_OPENAI_REASONING_MODEL=gpt-5.4-mini export AZURE_OPENAI_TOOLCALL_MODEL=gpt-5.4-mini export AZURE_OPENAI_CLASSIFICATION_MODEL=gpt-5.4-mini快速上手直接运行opensre onboard选择 Azure OpenAI,粘贴资源 URL、API key 后,向导会列出资源中的 deployments供你挑选;若部署发现失败,也可以手工输入 deployment 名称。REPL 内可用:
/model set azure-openai gpt-5.4-mini /model set azure-openai gpt-5.4-mini --toolcall-model gpt-5.4-nano排障方面,azure_openai.py 提供了两条实用辅助:azure_deployments_list_curl_command()生成一条列出当前资源所有部署的 curl 命令(curl -H "api-key: $AZURE_OPENAI_API_KEY" "$AZURE_OPENAI_BASE_URL/openai/deployments?api-version=...");当出现 deployment 404 时,format_azure_deployment_not_found_message()会提示"把AZURE_OPENAI_*_MODEL设为 Azure 门户中的 deployment 名称,而非/openai/models的模型 ID",并给出列出部署与在 Azure AI Foundry 中创建/重命名的修复步骤。list_azure_openai_deployments()则为 onboarding 提供程序化发现能力。
专题二:Google Vertex AI(vertex-ai)
Vertex AI 的认证走 GoogleApplication Default Credentials (ADC),不需要 API key。可用方式包括gcloud auth application-default login、将GOOGLE_APPLICATION_CREDENTIALS指向服务账号 key 文件,或使用 GCE/GKE metadata server。
| 变量 | 说明 |
|---|---|
VERTEX_AI_PROJECT | GCP 项目 ID(可选,见下方 ambient 说明) |
VERTEX_AI_LOCATION | 区域,默认us-central1(DEFAULT_VERTEX_AI_LOCATION) |
VERTEX_AI_*_MODEL | 经 Vertex 提供的 Gemini 模型 ID(如gemini-2.5-pro) |
LiteLLM 模型串为vertex_ai/<model>,由resolve_vertex_ai_request_kwargs()(vertex_ai.py)生成。测试 test_vertex_ai_routing.py 验证了vertex_ai/gemini-2.5-pro、默认 locationus-central1、api_key_env=None以及 toolcall 回退vertex_ai/gemini-2.5-flash-lite的完整装配。
配置示例:
export LLM_PROVIDER=vertex-ai export VERTEX_AI_PROJECT=my-gcp-project # 可选(缺省 us-central1): export VERTEX_AI_LOCATION=us-central1 # 可选覆盖: export VERTEX_AI_REASONING_MODEL=gemini-2.5-pro export VERTEX_AI_TOOLCALL_MODEL=gemini-2.5-flash-lite与 Bedrock 一样,Vertex 的credential_kind="ambient":OpenSRE 从不存储 Vertex 密钥,也不强制必填字段前置校验——vertex_project未设置时在请求 kwargs 中直接省略(而不是抛错),缺失项目会以 LiteLLM / google-auth 的请求期错误自然暴露。这是文档明确记录的、与 Bedrock 对齐的 ambient 凭证先例。构建 agent 客户端时api_key_env=None,LiteLLM 客户端只携带vertex_project/vertex_location非敏感字段。
并发与缓存细节:/model 切换的竞态防护
前面提到缓存按(role, transport, runtime_provider)键控、整表失效,这里补一个容易被忽略的并发细节。LLMClientCache的get()采用"先检查键、键变则清空、再取缓存"的原子序列,store()在配置键已变时选择丢弃而非覆盖。这意味着:一个正在构建中的客户端如果恰好撞上并发的/model切换,构建产物不会进入新配置的缓存,下一次调用会按新键重建(internal/client_cache.py)。测试 test_client_cache.py 的场景化用例完整覆盖了"empty / hit / 角色独立 / 键变化整表失效 / 构建期配置变化丢弃"五类行为。
由于所有角色共享同一缓存实例与路由键,/model切换或环境变量变更后,工具调用 agent、推理、分类、工具选择四个角色会同时按新配置重建,不存在"agent 用了新模型而分类器还在用旧模型"的窗口期。
测试与验证路径
tests/core/runtime/llm/下的测试是理解这套运行时的最佳第二手资料,建议按主题对照阅读:
- 路由决策:
test_factory.py(默认 SDK、Azure 强制 LiteLLM、账号路由覆盖本地配置、独立缓存键); - 客户端构建:
test_client_builders.py(registry 驱动,anthropic / openai / bedrock 在 SDK 与 LiteLLM 两侧的类名断言,Bedrock 按模型 ID 在 Anthropic 与 Converse 客户端间选择); - 特殊厂商:
test_azure_openai_routing.py(azure/<deployment>、api_base、api_version、缺 base URL 报错)、test_vertex_ai_routing.py(强制 LiteLLM、默认 location、无 api key); - 缓存:
test_client_cache.py(键控失效与并发丢弃); - LiteLLM 通道:
test_litellm_compat.py(litellm.completion的 OpenAI 兼容调用与工具消息回放)。
LiteLLM 路径还有一个值得注意的行为:LiteLLMAgentClient构建工具调用请求时使用tool_choice="auto"、parallel_tool_calls=False(单轮单动作,配合core.tool.execution)与drop_params=True(LiteLLM 按厂商翻译或丢弃不支持的参数,而不是失败),并复用与 SDK 路径相同的工具 schema 归一化逻辑(tool_schema_normalize.py 会剥离title/$schema/$defs/$ref/not/nullable等严格接口不接受的键,Bedrock Converse 还额外剔除additionalProperties)。
小结
OpenSRE 的托管 LLM 运行时把"厂商选择"与"传输通道"两个问题收敛为一次resolve_llm_route()决策:默认原生 SDK,OPENSRE_LLM_TRANSPORT=litellm或 Azure / Vertex 强制走 LiteLLM,CLI 厂商固定走子进程;客户端构建由FIRST_PARTY_PROVIDERS与 OpenAI 兼容目录数据驱动,新增 first-party 厂商只需一行 registry 记录;进程级缓存按(transport, runtime_provider)键控、整体失效,配合线程锁与"过期即丢弃"策略保证/model热切换无竞态。若你要为 OpenSRE 接入新的托管 API 厂商,按"字面量 → 模型默认值 → ProviderSpec → 构建分支 → env 同步与测试"五步走即可,路由决策始终只需改 factory.py 一处。
【免费下载链接】opensreBuild your own AI SRE agents. The open source toolkit for the AI era.项目地址: https://gitcode.com/GitHub_Trending/op/opensre
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考