转载--Hermes Agent 02 | 模型无关的秘密:200+ 模型的统一接入层

原文连接:

https://mp.weixin.qq.com/s?__biz=MzAwMTYwNzE2Mg==&mid=2651039758&idx=1&sn=dfcab689bd3adb6d5c680727076c423a&chksm=81201c9bb657958de6c7464c659f5a57b888ece84ddf9b9c26f60e62877eb4d2208c5502f727&cur_album_id=4469690989619855360&scene=189#wechat_redirect

真正的自由不是没有约束,而是可以随时更换约束的来源。


一个让你立刻想动手的数字

先说个数字,让你有感觉这一讲能给你带来什么。

我做过一次实验:同一个真实工作流(40 个文件的代码迁移 + 测试编写 + 文档更新),分别跑在三个配置下:

配置 模型策略 单次成本
A 全程 Claude Opus 4.6 $6.40
B 全程 GPT-5 $5.10
C Hermes Agent 多模型策略 $0.78

配置 C 的规则很简单:

  • 简单的对话轮次(短消息、非代码类提问)→ 用 Gemini Flash 等廉价模型

  • 复杂代码生成、架构决策、调试类任务 → 用 Claude Opus 4.6

  • 两者之间设置了 fallback,主路限速时自动切备用路

大约 1/8 的成本,主观体验差异并不大。 为什么可以这么便宜?因为真实 Agent 任务里,大量 Token 其实花在了"简单轮次"上------用户的短提问、确认类回复、简单查询,这些根本不需要旗舰模型。只是大多数 Agent 框架不给你分开路由的能力

Hermes Agent 给了。这一讲我们拆它是怎么给的。


四条接入路径:OpenRouter / Nous Portal / 直连 / 本地 Ollama

先把整个模型接入层的数据流画清楚:

复制代码
           ┌──────────────────────────────────────┐
           │       Agent 核心(run_agent.py)       │
           │  self._try_activate_fallback()       │
           └──────────┬───────────────────────────┘
                      │
         ┌────────────┼────────────────────┐
         │            │                    │
         ▼            ▼                    ▼
┌────────────────┐ ┌─────────┐ ┌───────────────────────┐
│ resolve_       │→│ Adapter │→│   远端(四条路径)      │
│ provider_      │ └─────────┘ │                       │
│ client()       │             │ 1. OpenRouter(200+) │
└────────────────┘             │ 2. Nous Portal(自家) │
                               │ 3. 直连厂商 API       │
                               │ 4. 本地 Ollama         │
                               └───────────────────────┘

这里的关键是:Agent 核心通过 resolve_provider_client() 这个统一入口解析 Provider (对应 agent/auxiliary_client.py)。这不是说运行时完全没有厂商差异,而是说 Hermes 把"client 怎么构造、协议怎么适配、凭证怎么解析"收敛到了一个中心入口,主循环不用在每个调用点都手搓一遍 Provider 分支。

Hermes Agent 给你提供了四种接入远端的路径,三种主流 + 一种补充:

路径一:OpenRouter(推荐默认)

OpenRouter 是一个模型聚合网关------一个 API Key 打通 200+ 模型。它帮你做了两件事:

  1. 鉴权归一:不用再维护十几个厂商的 Key。

  2. 协议归一:所有模型都走 OpenAI Chat Completion 兼容协议。

Hermes Agent 把 OpenRouter 当作默认路径。你通过 hermes setup 引导配置,或设置环境变量 OPENROUTER_API_KEY,它就会把 OpenRouter 当作候选路由。

它的实际价值不只是"模型多",更在于把多厂商接入的心智负担压成了一个 Key、一套协议、一种配置方式。

路径二:Nous Portal(Nous Research 自家)

Nous Portal 是 Nous Research 官方提供的模型服务门户。Hermes Agent 对 Nous Portal 使用 OAuth Device Code 认证方式(hermes_cli/providers.py 中定义 auth_type="oauth_device_code"),接口走标准 OpenAI Chat 协议,端点为 https://inference-api.nousresearch.com/v1\

注意: 虽然名字里有"Hermes",但 Nous Hermes 3/4 系列模型实际上不适合 Agent 任务。Hermes Agent 在启动时会检测到这些模型并发出明确警告(见后文"Non-Agentic 模型"一节)。Nous Portal 的价值更多在于提供其他合作伙伴模型的接入。

路径三:直连厂商 API

Hermes Agent 支持直连大量厂商的原生 API。在 hermes_cli/providers.pyHERMES_OVERLAYS 注册表中,可以看到已适配的厂商包括:Anthropic、OpenAI(含 Codex)、xAI、DeepSeek、阿里(DashScope)、Kimi、MiniMax、智谱(zai)、小米、Arcee、HuggingFace 等。

为什么还要直连? 两个场景:

  1. 企业合规:很多企业要求数据不能过第三方聚合商,必须走跟厂商签过 DPA 的直连通道。

  2. 功能尝鲜:聚合商的协议归一意味着一些厂商特有的新功能(比如 Anthropic 的 extended thinking、OpenAI 的 computer use)可能延迟支持。直连拿到的是最新能力。

路径四:本地 Ollama

本地 Ollama 是一个补充路径,解决的是两个场景:

  1. 离线开发:你在飞机上、网差的地方,仍然能让 Agent 跑起来。

  2. 数据隔离:敏感数据绝不能离开本机的场景(医疗、法律、金融内部)。

Hermes Agent 并不给 Ollama 单独开一条"本地专线",而是把它视作一个标准的 OpenAI 兼容端点(http://localhost:11434/v1\)。源码和官方文档里对应的配置姿势都是 provider: custom + base_url这才是这套设计真正优雅的地方:本地和远端的差异,被收敛成了端点差异。


统一接入层的工程设计:Adapter 模式

四条路径怎么在代码层统一?Hermes Agent 用的是协议适配器模式。

Adapter 的真实结构

不同厂商的 API 协议是不同的,Hermes Agent 在 agent/auxiliary_client.py 中实现了一组专用适配器和包装器,把不同协议收敛到统一的调用面上:

复制代码
# agent/auxiliary_client.py 中的核心适配器/包装器

class _CodexCompletionsAdapter:
    """把 chat.completions.create() 调用翻译为 Codex Responses API。"""
    ...

class CodexAuxiliaryClient:
    """对外暴露 OpenAI 风格接口,内部走 Codex 适配器。"""
    ...

class _AnthropicCompletionsAdapter:
    """OpenAI 兼容接口 → Anthropic Messages API 的适配器。"""
    ...

class AnthropicAuxiliaryClient:
    """对外暴露 OpenAI 风格接口,内部走 Anthropic 适配器。"""
    ...

class AsyncCodexAuxiliaryClient:
    ...

class AsyncAnthropicAuxiliaryClient:
    ...

而 Provider 的元数据注册在 hermes_cli/providers.pyHermesOverlay 数据类中,每个 Provider 标注了三个关键信息:

复制代码
@dataclass(frozen=True)
class HermesOverlay:
    transport: str = "openai_chat"        # openai_chat | anthropic_messages | codex_responses
    is_aggregator: bool = False
    auth_type: str = "api_key"            # api_key | oauth_device_code | oauth_external | external_process
    extra_env_vars: Tuple[str, ...] = ()
    base_url_override: str = ""
    base_url_env_var: str = ""

更准确地说,调用方大多数时候不必感知厂商差异 。它通过 resolve_provider_client(provider, model) 拿到统一 client;底下可能是 OpenAI SDK 原生 client,也可能是 Codex/Anthropic 包装器。但 run_agent.py 里仍保留了少量与 transport、header、fallback、api_mode 相关的 Provider 特判。这不是抽象失败,而是工程现实。

一个容易被忽视的细节:协议归一的"抽象泄漏"

这里有一个很值得聊的工程陷阱。

大多数 Agent 框架对模型的抽象停在"所有模型都走 OpenAI 协议"这一层。听起来完美,实际用起来坑无数------因为即使都说自己是"OpenAI 兼容",不同模型的实际行为是有漂移的:

  • 有的模型 tool_calls 必须在 content 之后(否则解析错)。

  • 有的模型在工具调用时会额外吐一段 <thinking> 块,不剥干净会污染后续轮。

  • 有的模型 finish_reason 永远返回 stop,根本不报 tool_calls

  • 有的模型对 tools 数组长度有硬限制(8 个、16 个、32 个都见过)。

Hermes Agent 在适配层和主循环中都有针对特定 Provider 的特判逻辑。比如在 _try_activate_fallback() 中可以看到,切换到不同 Provider 时需要根据 provider 名称和 base_url 判断走哪种 API 模式(chat_completions / codex_responses / anthropic_messages),还要处理 Kimi Coding 需要特定 User-Agent 头、Ollama Cloud 需要从环境变量拉 Key 等细节。

这种特判看起来丑,但它是真实工程里让模型无关能 work 的秘密。所有搞过多模型接入的同学都知道:协议归一的 80% 代码量在这种脏活累活里。

如果你要自己做多模型接入,记住一个教训:永远给适配层留一个"特判通道"。 不要追求代码的"整洁"而拒绝为个别模型打补丁------你压不住现实的漂移。


Non-Agentic 模型警告:把坑显式告诉你

聊完接入路径,我们聊一个更深的问题:模型之间的能力差异,不只是价格和延迟,而是功能能不能用。

Non-Agentic 模型这个概念

Hermes Agent 里有一个专门的概念:Non-Agentic Model------非 Agent 模型。

什么是 non-agentic?LLM 虽然号称支持 function calling,但实际跑 Agent 任务时,有三种典型的拉胯:

  1. 给了工具也不用。 你在 system prompt 里告诉它"请用 read_file 工具",它视而不见,自己瞎编文件内容。

  2. 调用一次就停。 第一轮工具调用结果返回后,它不会继续根据结果规划下一步,直接就 "finish_reason: stop"。

  3. 工具调用参数乱填。 Schema 里要求 {"path": "string"},它给你返回 {"filepath": "xxx"}

这三种行为,单独看都不是 bug------模型"能"用工具,只是"不擅长"用。但 Agent 任务是个多轮工具调用的场景,这些"不擅长"会在第一轮就让 Agent 彻底卡死。

Hermes Agent 的做法:静态检测 + 启动警告

Hermes Agent 目前的做法是静态检测 ------通过正则匹配模型名称来识别已知的 non-agentic 模型。具体实现在 hermes_cli/model_switch.py 中:

复制代码
_HERMES_MODEL_WARNING = (
    "Nous Research Hermes 3 & 4 models are NOT agentic and are not designed "
    "for use with Hermes Agent. They lack the tool-calling capabilities "
    "required for agent workflows. Consider using an agentic model instead "
    "(Claude, GPT, Gemini, DeepSeek, etc.)."
)

_NOUS_HERMES_NON_AGENTIC_RE = re.compile(
    r"(?:^|[/:])hermes[-_ ]?[34](?:[-_.:]|$)",
    re.IGNORECASE,
)

def is_nous_hermes_non_agentic(model_name: str) -> bool:
    """Return True if model_name is a real Nous Hermes 3/4 chat model."""
    if not model_name:
        return False
    return bool(_NOUS_HERMES_NON_AGENTIC_RE.search(model_name))

cli.py 的会话启动阶段,会调用这个检测函数,如果命中就显示醒目警告:

复制代码
⚠  Nous Research Hermes 3 & 4 models are NOT agentic and are not designed
   for use with Hermes Agent. They lack the tool-calling capabilities
   required for agent workflows. Consider using an agentic model instead
   (Claude, GPT, Gemini, DeepSeek, etc.).

你仍然可以用------Hermes Agent 不会替你做"拒绝加载"这种家长式决策。但它把坑显式告诉你

此外,agent/models_dev.py 中的 list_agentic_models() 函数会从 models.dev 模型目录中过滤出支持 tool_call=True 的模型,同时用正则排除噪声模型(TTS、embedding、过期预览版等)。这个列表用于模型选择界面,帮你在第一步就筛掉不适合 Agent 任务的模型。

这套机制看起来简单,但它给你省掉了大量"为什么这个模型死活不工作"的调试时间。


模型路由:把"简单轮次"和"复杂轮次"分开

OK,non-agentic 警告解决了"能用不能用"的问题。现在聊更有意思的部分:同一个会话里,不同轮次用不同模型。

这是本讲开头 1/8 成本的那个实验的核心。

任务分层的基本思路

Agent 主循环里的 Token 消耗,其实是极度不均衡的:

操作类别 Token 占比 对模型能力的要求
读文件 / grep / glob 30-40% 低(只要能按 Schema 输出工具调用)
Web 搜索 / 页面摘要 15-20% 中(需要信息综合能力)
代码生成 / patch 20-25% (真正的难点)
决策 / 规划 5-10% (多步推理)
错误恢复 5-10% (需要理解失败原因)
技能创建 / 记忆策展 2-5% 中高

"低"的那一档其实占了 30-40% 的 Token。但你用旗舰模型跑这部分,是完全的浪费------一个 8B 的开源模型都能稳定完成"读 /tmp/foo.py 然后告诉我它有几个函数"。

Smart Model Routing:Hermes Agent 的实现

Hermes Agent 的模型路由实现在 agent/smart_model_routing.py 中,叫做 Smart Model Routing 。它的核心思路是:按用户消息的复杂度分流------简单消息走廉价模型,复杂消息走主模型。

配置在 ~/.hermes/config.yaml 中:

复制代码
# ~/.hermes/config.yaml
smart_model_routing:
  enabled: true
  max_simple_chars: 160
  max_simple_words: 28
  cheap_model:
    provider: openrouter
    model: google/gemini-2.5-flash

路由决策的核心函数是 choose_cheap_model_route(),它的判断逻辑非常保守------宁可多花钱也不误判:

复制代码
def choose_cheap_model_route(user_message: str, routing_config) -> Optional[Dict]:
    # 以下任一条件命中,就走主模型(不路由到廉价模型):
    # 1. 消息超过 160 字符
    # 2. 消息超过 28 个单词
    # 3. 消息包含多行
    # 4. 消息包含代码块(```  或 `)
    # 5. 消息包含 URL
    # 6. 消息包含复杂关键词(debug, implement, refactor, patch,
    #    traceback, error, analyze, architecture, test, plan, delegate...)

    # 全部通过才路由到 cheap_model
    ...

注意:这是"轮次级"路由,不是"工具级"路由。 路由发生在用户发送消息后、Agent 开始推理前。它根据用户消息的复杂度来决定这一轮用哪个模型,而不是根据将要调用的工具。

resolve_turn_route() 函数把路由决策和 Provider 解析组合在一起,返回这一轮的完整 runtime 配置(model、api_key、base_url、provider 等),在 UI 层会显示类似 smart route → google/gemini-2.5-flash (openrouter) 的标签,让你知道路由生效了。

这套机制的含金量高在哪?它把"模型路由"这件事从架构师的直觉决策变成了可配置、可观测、可调优的东西。 你跑一周,看 /usage 里消耗多少钱,不满意就调配置。这是一种你能带走的能力。


故障转移:主模型限速时的无感切换

讲完"按轮次选模型",讲更苛刻的一个场景:主模型在关键时刻抽风了,怎么办?

这个问题在真实生产里非常普遍:

  • OpenAI 给某些 Tier 限速,到了某个时刻你的 API 开始返回 429。

  • Anthropic 某个区域在某个时刻 5xx 频繁。

  • OpenRouter 某个 upstream 暂时不可用。

如果 Agent 正在跑一个 30 轮的任务,跑到第 18 轮主模型挂了------整个任务凉掉,用户只看到一个红色错误。

Hermes Agent 对这个场景做了无感切换

故障转移的核心函数

run_agent.py 里有一个方法叫 _try_activate_fallback()(第 6316 行)。当主模型在重试后仍然失败时被调用,它做的事是就地替换当前的模型配置:

复制代码
def _try_activate_fallback(self) -> bool:
    """Switch to the next fallback model/provider in the chain.

    Called when the current model is failing after retries.  Swaps the
    OpenAI client, model slug, and provider in-place so the retry loop
    can continue with the new backend.  Advances through the chain on
    each call; returns False when exhausted.
    """
    if self._fallback_index >= len(self._fallback_chain):
        return False

    fb = self._fallback_chain[self._fallback_index]
    self._fallback_index += 1
    fb_provider = (fb.get("provider") or "").strip().lower()
    fb_model = (fb.get("model") or "").strip()
    if not fb_provider or not fb_model:
        return self._try_activate_fallback()  # skip invalid, try next

    # 通过 resolve_provider_client() 构建新的 client
    fb_client, _ = resolve_provider_client(fb_provider, model=fb_model, ...)
    if fb_client is None:
        return self._try_activate_fallback()  # provider 没配,跳过

    # 就地替换 model、provider、client、api_mode 等运行时状态
    self.model = fb_model
    self.provider = fb_provider
    self.client = fb_client
    self.api_mode = ...  # 根据 provider 自动判断
    self._fallback_activated = True
    return True

几个细节值得注意:

细节一:内部统一成 fallback chain。 run_agent.py 里真正推进的是 _fallback_chain 列表,每次调用 _try_activate_fallback() 都向前走一步(_fallback_index += 1)。不过这里要区分源码内部表示公开配置写法 :当前给用户暴露的主路径是 config.yaml 顶层的 fallback_model:,也就是一个常规备用模型;运行时再把它规范化成内部链表结构。

细节二:就地替换。 切换不是重建 Agent,而是原地替换 self.modelself.providerself.clientself.api_mode 等字段。这意味着 Agent 的会话状态(消息历史、工具状态等)完全保留,只是底层的模型通道换了。

细节三:API 模式自动适配。 切换到新 Provider 时,代码会根据 provider 名称和 base_url 自动判断走哪种 API 模式------如果是 Anthropic 就用 anthropic_messages,如果是 OpenAI 直连或 GPT-5 就用 codex_responses,其余走 chat_completions。甚至会为 Anthropic 构建原生的 Anthropic client 而非走 OpenAI 兼容层。

细节四:Provider 特殊处理。 源码中可以看到一些有趣的特判:Kimi Coding 需要 User-Agent: KimiCLI/1.30.0 头,Ollama Cloud 需要从 OLLAMA_API_KEY 环境变量拉 Key,这些都在 fallback 切换时自动处理。

凭证池轮换:同一模型多 Key 的负载均衡

还有一个和故障转移配套的机制:凭证池轮换

如果你有多个同一厂商的 Key(不同组织、不同 Tier),Hermes Agent 可以把它们加入一个凭证池:

复制代码
hermes auth add anthropic
# 通过交互式流程添加凭证,支持 API Key 和 OAuth 两种方式
# 重复执行可添加多个凭证到同一 provider 的池中

hermes auth list              # 查看所有凭证
hermes auth remove <p> <idx>  # 移除某个凭证
hermes auth reset <provider>  # 清除某个 provider 的限速标记

凭证池的实现在 agent/credential_pool.py 中,支持四种轮换策略:

  • fill_first:按顺序使用,当前 Key 耗尽才用下一个。

  • round_robin:轮询使用。

  • random:随机选取。

  • least_used:优先使用调用次数最少的 Key,做负载均衡。

某个 Key 被限速(429)或配额耗尽(402)时,mark_exhausted_and_rotate() 方法会将其标记为 exhausted 并自动跳到下一个可用 Key。被标记的 Key 有 1 小时的冷却期(EXHAUSTED_TTL_429_SECONDS = 3600),冷却后自动恢复。

这个机制跟故障转移是正交的:故障转移解决"同模型同 Key 失败时换模型";凭证池解决"同模型换 Key"。两者组合在一起,对生产环境的鲁棒性提升非常明显。


动手实战:配置一份"开发用免费、生产用旗舰"的策略

讲完原理,我们动手做一份真正可用的多模型策略。

场景

你是一个独立开发者或小团队技术负责人。平时开发原型、写小工具,希望模型便宜够用;客户 demo 或正式交付时需要质量过硬。同一台机器、同一份 Hermes Agent,通过修改配置文件切换策略。

第一步:准备 Key

运行 setup 引导程序,配置 OpenRouter(一个 Key 覆盖所有模型,最省心):

复制代码
hermes setup
# 按提示选择 OpenRouter,输入 API Key
# 或直接设置环境变量:
export OPENROUTER_API_KEY=sk-or-xxxxxxxxxxxxxxxxxx

第二步:配置 Smart Model Routing

编辑 ~/.hermes/config.yaml(或用 hermes config edit):

开发模式------全程用免费/低价模型:

复制代码
# ~/.hermes/config.yaml
model:
  provider: openrouter
  default: moonshotai/kimi-k2:free

# 简单轮次进一步降级到更小的模型
smart_model_routing:
  enabled: true
  max_simple_chars: 160
  max_simple_words: 28
  cheap_model:
    provider: openrouter
    model: qwen/qwen-2.5-72b-instruct:free

# 上下文压缩配置
compression:
  enabled: true
  threshold: 0.50

生产模式------旗舰模型 + 智能降级:

复制代码
# ~/.hermes/config.yaml
model:
  provider: anthropic
  default: claude-sonnet-4-6

# 简单轮次用便宜模型,复杂轮次保持旗舰
smart_model_routing:
  enabled: true
  max_simple_chars: 160
  max_simple_words: 28
  cheap_model:
    provider: openrouter
    model: google/gemini-2.5-flash

两个配置的区别在于主模型的选择和 cheap_model 的档位。开发时全线走免费通道;生产时只有简单轮次降级,关键决策仍在旗舰模型。

第三步:配置 Fallback

config.yaml 里配置 fallback_model:,当主模型不可用时自动切换:

复制代码
# 在 ~/.hermes/config.yaml 中添加
fallback_model:
  provider: openrouter
  model: anthropic/claude-sonnet-4

如果你顺着源码往下读,会看到 _fallback_chain 支持列表化推进;但对大多数用户来说,先把 fallback_model: 这一格配好,就已经覆盖了 90% 的生产场景。

第四步:观察真实成本

Hermes Agent 内置了 /usage 命令,在交互会话中随时可查看当前 session 的用量:

复制代码
> /usage

  📊 Session Token Usage
  ────────────────────────────────────────
  Model:                     anthropic/claude-sonnet-4-6
  Input tokens:                  52,300
  Cache read tokens:             38,100
  Cache write tokens:             2,400
  Output tokens:                 18,200
  Prompt tokens (total):         92,800
  Completion tokens:             18,200
  Total tokens:                 111,000
  Estimated cost:                 $1.84

如果你想看更长周期的用量洞察,可以用 /insights 命令。

第五步(可选):把本地 Ollama 作为离线兜底

如果你在笔记本上装了 Ollama,可以把备用模型直接指向本地端点:

复制代码
# 确保 Ollama 在跑,拉一个小模型
ollama pull qwen2.5:14b-instruct

然后把 fallback_model: 改成:

复制代码
fallback_model:
  provider: custom
  model: qwen2.5:14b-instruct
  base_url: http://localhost:11434/v1

现在就算整个外网都挂了,Hermes Agent 还能切到本地模型继续工作。这种韧性设计,是模型无关架构另一个不显眼但真实的价值。


一个容易踩坑的点:上下文压缩用哪个模型

聊一个生产环境才会遇到的坑------上下文压缩的模型选择

Hermes Agent 在上下文超过阈值时会做压缩(默认 compression.threshold = 0.50)。压缩的时候它需要一次额外的 LLM 调用来生成摘要。问题来了:这次压缩调用用哪个模型?

如果你用默认策略(压缩用主模型),但主模型恰好被限速了------压缩失败,整个会话卡住。如果随便找个免费模型压缩------摘要质量可能不够,影响后续所有轮次。

Hermes Agent 的做法是在 config.yaml 的 auxiliary 配置中单独给压缩指定模型

复制代码
# ~/.hermes/config.yaml
auxiliary:
  compression:
    provider: openrouter
    model: google/gemini-2.5-flash

context_compressor.py 中的 summary_model_override 参数支持覆盖压缩使用的模型。如果未显式配置,系统会按一个自动检测链寻找可用的辅助模型(优先级:OpenRouter → Nous Portal → Codex → Anthropic → 其他已配置的 Provider),默认选择快速/便宜的模型(如 Gemini Flash、Claude Haiku 等)。

压缩任务的特点是输入长、输出短、语义准确性要求中等 ------用一个上下文窗口大、价格便宜的模型非常合适。这个小细节在你跑长会话时能救命。

相关推荐
c++逐梦人6 小时前
多路转接epoll
linux·网络·epoll
天若有情6736 小时前
Deepseek-V4-Flash-20260423 深度评测与实战指南
java·大数据·网络·ai
艾莉丝努力练剑6 小时前
【Linux网络】Linux 网络编程:传输层UDP
linux·运维·服务器·网络·计算机网络·udp
ylscode6 小时前
微软Edge浏览器启动时停止将已保存的密码加载到内存中
网络·数据库·安全·安全威胁分析
草莓熊Lotso8 小时前
【Linux系统加餐】从原理到封装:基于建造者模式实现System V信号量工业级C++封装
android·linux·运维·服务器·网络·c++·建造者模式
齐齐大魔王14 小时前
Linux-网络编程实战
linux·运维·网络
智塑未来14 小时前
app应用怎么接入广告?标准流程与落地实操方案全解析
大数据·网络·人工智能
wanhengidc15 小时前
私有云的作用都有哪些?
运维·服务器·网络·游戏·智能手机
CTO Plus技术服务中16 小时前
71款企业级自研产品,线上演示环境
网络