最近在构建LLM应用时很多团队都热衷于引入一个专门的“路由层”Router来管理和分发请求。然而经过一段时间的实践和深度思考我们团队做出了一个反直觉的决定我们废弃了自己构建的LLM路由层。这并不是因为路由概念本身有问题而是我们发现在当前的架构演进和LLM生态下一个独立的、复杂的路由组件往往弊大于利它可能引入了不必要的复杂性、延迟和运维负担而核心价值却可以通过更轻量、更内聚的方式实现。本文将深入探讨LLM路由器的兴起背景、我们为何选择废弃它以及我们转向的替代架构方案。无论你是正在设计LLM应用架构的后端工程师还是负责AI产品落地的技术负责人本文都将为你提供一个从“跟风造轮子”到“理性做减法”的完整思考路径和实战参考。1. LLM路由器的兴起解决什么问题在深入讨论“废弃”之前我们首先要理解为什么“每个人都在构建LLM路由器”。这背后反映了LLM应用开发中几个真实的痛点。1.1 核心痛点模型选择的复杂性早期的LLM应用可能只对接一个API比如OpenAI的GPT-4。但随着生态发展局面变得复杂多模型供应商OpenAI、AnthropicClaude、GoogleGemini、国内各大厂商等各有优劣。多模型版本同一个供应商提供不同能力、不同成本的模型如GPT-4 Turbo, GPT-3.5-Turbo。专有与开源模型除了商用API还有大量可在本地或私有云部署的开源模型如Llama、Qwen、DeepSeek。功能特异性有些模型长于代码Claude Code有些长于推理有些则性价比高。开发者面临一个难题如何根据不同的请求内容、预算、时延要求智能地选择最合适的模型手动写一堆if-else判断既丑陋又难以维护。1.2 路由器的理想化职责一个理想的LLM路由器被期望承担以下职责负载均衡将请求分发到多个可用的模型终端节点避免单点过载。模型路由根据预定义的策略如内容类型、复杂度、成本预算选择最合适的模型。故障转移当首选模型API失败或超时时自动降级或切换到备用模型。A/B测试与灰度发布将一部分流量导向新模型以评估效果。统一接口与协议转换为上游应用提供一个统一的API屏蔽下游不同模型API的差异如请求/响应格式、认证方式。监控与观测集中收集所有模型调用的延迟、成本、错误率等指标。听起来非常美好对吧这几乎是微服务架构中API网关思想的直接映射。因此很多团队包括我们初期自然而然地开始构建这样一个中心化的“LLM Gateway”或“LLM Router”。2. 为什么我们决定废弃LLM路由器在构建并运行了我们自研的LLM路由器几个月后我们逐渐意识到它带来了许多意料之外的问题。2.1 引入的额外复杂度与成本新的单点故障路由器本身成为了系统的新单点。一旦路由器宕机所有LLM调用都会中断尽管下游的模型API可能全部健康。额外的延迟每个请求都需要经过路由器这一跳增加了网络延迟和序列化/反序列化开销。对于LLM这种本身延迟就较高的服务额外增加几十到几百毫秒是不可接受的。运维负担你需要部署、监控、扩缩容、保障另一个关键服务的SLA。这分散了本应用于核心AI能力开发的精力。配置爆炸路由规则哪个请求走哪个模型的配置变得极其复杂。是基于关键词基于输入长度基于历史性能维护一个动态、高效且准确的路由策略本身就是一个机器学习问题。2.2 架构上的不匹配逻辑与传输的耦合路由器通常混入了业务逻辑“这个代码问题应该用Claude Code”和基础设施职责负载均衡、熔断。这违反了单一职责原则。客户端灵活性的丧失在移动端或边缘场景客户端可能希望根据网络状况直接选择不同的终端。经过中心化路由器后这种灵活性消失了。与现有基础设施重叠大多数云原生公司已经拥有了成熟的API网关如Kong, Envoy、服务网格如Istio和负载均衡器。LLM路由器的很多功能负载均衡、熔断、观测与这些现有组件严重重叠造成“重复造轮子”。2.3 核心价值被质疑我们问自己路由器提供的核心价值是否无法通过更简单的方式获得模型选择这本质上是应用层的业务决策而不是基础设施层的流量调度。一个代码审查功能“知道”自己应该调用CodeLlama这个逻辑应该放在离业务代码最近的地方。故障转移可以在客户端SDK中通过重试和后备列表优雅实现无需经过中心节点。统一接口一个轻量级的客户端SDK或适配器库就能很好地封装不同API的差异。监控可以通过标准的遥测技术OpenTelemetry在客户端直接上报同样无需中心节点汇总。3. 我们的替代方案去中心化的智能客户端模式废弃路由器后我们转向了一种“智能客户端”模式。其核心思想是将路由决策逻辑下放到调用LLM的客户端或服务中同时利用现有云原生设施处理基础设施问题。3.1 架构概览[业务应用] - [智能客户端 SDK] - [多个LLM供应商 API] | | | |-- 模型选择逻辑本地策略 | |-- 请求适配统一格式-供应商格式 | |-- 本地重试与降级 | |--- [现有API网关] (负责通用流量管理、认证、限流) |--- [服务网格] (负责服务发现、负载均衡、熔断) |--- [可观测性平台] (接收来自SDK的遥测数据)在这个架构中不再有独立的“LLM Router”服务。3.2 核心组件智能客户端SDK我们开发了一个轻量级的客户端SDK它被集成到每个需要调用LLM的业务服务中。以下是该SDK的核心设计# 示例Python智能客户端SDK核心类设计 from typing import Dict, Any, Optional, List from abc import ABC, abstractmethod import httpx import openai from opentelemetry import trace class LLMProvider(ABC): LLM供应商抽象接口 abstractmethod async def generate(self, prompt: str, **kwargs) - str: pass abstractmethod def get_cost(self, prompt_tokens: int, completion_tokens: int) - float: pass class OpenAIClient(LLMProvider): OpenAI实现 def __init__(self, api_key: str, model: str gpt-3.5-turbo): self.client openai.AsyncOpenAI(api_keyapi_key) self.model model self.price_per_token 0.002 / 1000 # 示例价格 async def generate(self, prompt: str, **kwargs) - str: response await self.client.chat.completions.create( modelself.model, messages[{role: user, content: prompt}], **kwargs ) return response.choices[0].message.content def get_cost(self, prompt_tokens: int, completion_tokens: int) - float: return (prompt_tokens completion_tokens) * self.price_per_token class AnthropicClient(LLMProvider): Anthropic Claude实现 # ... 类似实现封装Anthropic API class RouterStrategy(ABC): 路由策略抽象 abstractmethod def select_provider(self, prompt: str, context: Dict) - LLMProvider: pass class CostAwareStrategy(RouterStrategy): 成本优先策略选择预估成本最低的可用模型 def __init__(self, providers: List[LLMProvider]): self.providers providers def select_provider(self, prompt: str, context: Dict) - LLMProvider: # 简化示例基于历史平均性能或简单规则选择 # 实际可嵌入更复杂的模型或规则引擎 if len(prompt) 4000: # 长文本使用支持更长上下文的模型 return next(p for p in self.providers if p.supports_long_context) else: # 默认返回成本最低的 return min(self.providers, keylambda p: p.estimated_cost_per_token) class IntelligentLLMClient: 智能客户端主类 def __init__(self, strategies: List[RouterStrategy], fallback_order: List[str]): self.strategies strategies self.fallback_order fallback_order self.tracer trace.get_tracer(__name__) async def generate(self, prompt: str, strategy_hint: Optional[str] None, **kwargs) - str: with self.tracer.start_as_current_span(llm_generate) as span: span.set_attribute(prompt_length, len(prompt)) span.set_attribute(strategy_hint, strategy_hint) selected_provider None last_error None # 1. 根据提示选择策略和供应商 for strategy in self.strategies: if strategy_hint and strategy.name strategy_hint: selected_provider strategy.select_provider(prompt, kwargs) break if not selected_provider: selected_provider self.strategies[0].select_provider(prompt, kwargs) # 2. 带重试和降级的调用 for provider_name in self.fallback_order: provider self._get_provider_by_name(provider_name) try: response await provider.generate(prompt, **kwargs) span.set_attribute(provider_used, provider.name) span.set_attribute(success, True) return response except Exception as e: last_error e span.record_exception(e) continue # 尝试下一个后备供应商 # 3. 所有后备都失败 span.set_attribute(success, False) raise ConnectionError(fAll LLM providers failed. Last error: {last_error}) def _get_provider_by_name(self, name: str) - LLMProvider: # ... 根据名称获取供应商实例 pass # 业务代码中的使用示例 async def business_logic(): # 初始化客户端配置策略和供应商 strategies [CostAwareStrategy([openai_client, claude_client])] client IntelligentLLMClient(strategies, fallback_order[openai, claude, local_llama]) # 调用时业务可以给出提示也可以使用默认策略 answer1 await client.generate(解释量子计算) answer2 await client.generate(请优化这段Python代码..., strategy_hintcode_optimization)3.3 如何实现原路由器的核心功能模型选择路由通过RouterStrategy抽象实现。策略可以非常简单基于输入长度也可以复杂集成一个轻量级分类器预测模型效果。策略作为配置可热更新。故障转移在IntelligentLLMClient.generate()方法中实现。维护一个后备供应商顺序列表当前供应商失败时自动按顺序尝试下一个。统一接口由LLMProvider抽象和IntelligentLLMClient主类提供对业务代码暴露统一的generate方法。监控通过集成OpenTelemetry在SDK内部关键点选择策略、调用开始、调用成功/失败添加追踪Trace和指标Metrics。数据直接上报到现有的可观测性后端如Jaeger、Prometheus。负载均衡与熔断这部分我们不再自己实现。对于指向我们私有化部署的LLM服务如本地部署的Llama我们将其注册到Kubernetes Service并通过服务网格如Istio来实现负载均衡、熔断、重试等策略。这利用了现有且成熟的基础设施。4. 具体实施步骤与代码示例假设我们有一个Python的FastAPI服务需要提供问答功能并智能选择使用OpenAI或本地部署的Qwen模型。4.1 项目结构与依赖llm_smart_client_demo/ ├── pyproject.toml ├── src/ │ ├── llm_client/ │ │ ├── __init__.py │ │ ├── providers.py # LLMProvider实现 │ │ ├── strategies.py # 路由策略 │ │ ├── client.py # IntelligentLLMClient │ │ └── telemetry.py # 可观测性设置 │ └── app/ │ ├── __init__.py │ ├── main.py # FastAPI主应用 │ ├── config.py # 配置管理 │ └── dependencies.py # 依赖注入 └── .env.examplepyproject.toml依赖示例[tool.poetry] name llm-smart-client-demo version 0.1.0 [tool.poetry.dependencies] python ^3.9 fastapi ^0.104.1 uvicorn ^0.24.0 openai ^1.3.0 httpx ^0.25.0 pydantic-settings ^2.0.0 opentelemetry-api ^1.21.0 opentelemetry-sdk ^1.21.0 opentelemetry-instrumentation-fastapi ^0.42b0 opentelemetry-exporter-otlp ^1.21.04.2 配置管理使用pydantic-settings管理配置支持从环境变量读取。# src/app/config.py from pydantic_settings import BaseSettings from pydantic import Field class Settings(BaseSettings): openai_api_key: str Field(..., envOPENAI_API_KEY) openai_base_url: str | None Field(None, envOPENAI_BASE_URL) qwen_api_base: str Field(http://qwen-service.default.svc.cluster.local/v1, envQWEN_API_BASE) default_llm_strategy: str Field(balanced, envDEFAULT_LLM_STRATEGY) otlp_endpoint: str | None Field(None, envOTLP_ENDPOINT) model_config { env_file: .env, extra: ignore } settings Settings()4.3 实现Provider和策略# src/llm_client/providers.py import httpx from abc import ABC, abstractmethod import logging from typing import Any logger logging.getLogger(__name__) class LLMProvider(ABC): name: str supports_long_context: bool False abstractmethod async def generate(self, prompt: str, **kwargs) - str: pass abstractmethod async def health_check(self) - bool: pass class OpenAIProvider(LLMProvider): def __init__(self, api_key: str, base_url: str | None None, model: str gpt-3.5-turbo): self.name openai self.model model self.supports_long_context True if gpt-4 in model else False self._client httpx.AsyncClient( base_urlbase_url or https://api.openai.com/v1, headers{Authorization: fBearer {api_key}}, timeout30.0 ) async def generate(self, prompt: str, **kwargs) - str: try: resp await self._client.post( /chat/completions, json{ model: self.model, messages: [{role: user, content: prompt}], temperature: kwargs.get(temperature, 0.7), max_tokens: kwargs.get(max_tokens, 1000), } ) resp.raise_for_status() data resp.json() return data[choices][0][message][content] except Exception as e: logger.error(fOpenAI API call failed: {e}) raise async def health_check(self) - bool: try: # 简单调用models端点验证连通性 resp await self._client.get(/models, timeout5.0) return resp.status_code 200 except Exception: return False class QwenProvider(LLMProvider): def __init__(self, base_url: str, model: str qwen-7b-chat): self.name qwen self.model model self.base_url base_url.rstrip(/) self._client httpx.AsyncClient(base_urlself.base_url, timeout60.0) async def generate(self, prompt: str, **kwargs) - str: try: resp await self._client.post( /chat/completions, json{ model: self.model, messages: [{role: user, content: prompt}], temperature: kwargs.get(temperature, 0.8), } ) resp.raise_for_status() data resp.json() return data[choices][0][message][content] except Exception as e: logger.error(fQwen API call failed: {e}) raise async def health_check(self) - bool: try: resp await self._client.get(/health, timeout10.0) return resp.status_code 200 except Exception: return False# src/llm_client/strategies.py from .providers import LLMProvider from typing import List, Dict, Any import tiktoken # 用于估算token可选 class RoutingStrategy: 路由策略基类 def __init__(self, name: str): self.name name async def select(self, providers: List[LLMProvider], prompt: str, context: Dict[str, Any]) - LLMProvider: raise NotImplementedError class FallbackStrategy(RoutingStrategy): 简单的后备策略按配置顺序选择第一个健康的Provider def __init__(self, name: str, order: List[str]): super().__init__(name) self.order order async def select(self, providers: List[LLMProvider], prompt: str, context: Dict[str, Any]) - LLMProvider: provider_map {p.name: p for p in providers} for name in self.order: if name in provider_map: provider provider_map[name] if await provider.health_check(): return provider raise RuntimeError(No healthy LLM provider available.) class SmartRoutingStrategy(RoutingStrategy): 智能路由策略示例 - 代码相关任务 - OpenAI (gpt-4更适合代码) - 长文档总结 - 支持长上下文的模型 - 简单问答 - 成本最低的模型 (如Qwen) def __init__(self, name: str): super().__init__(name) # 可以加载一个小的分类器模型或关键词列表 self.code_keywords [代码, 编程, function, def , class , bug, error, sql, python] async def select(self, providers: List[LLMProvider], prompt: str, context: Dict[str, Any]) - LLMProvider: # 将Provider按优先级或类型分类 openai_providers [p for p in providers if p.name openai] local_providers [p for p in providers if p.name qwen] # 策略1: 代码任务优先使用OpenAI if any(keyword in prompt.lower() for keyword in self.code_keywords): for p in openai_providers: if await p.health_check(): return p # 策略2: 长文本简单用长度判断优先使用支持长上下文的模型 if len(prompt) 3000: for p in providers: if p.supports_long_context and await p.health_check(): return p # 策略3: 默认选择健康的本地模型以节省成本 for p in local_providers: if await p.health_check(): return p # 策略4: 最后降级到OpenAI for p in openai_providers: if await p.health_check(): return p raise RuntimeError(No suitable LLM provider found.)4.4 集成智能客户端与FastAPI应用# src/llm_client/client.py import asyncio from typing import List, Dict, Any, Optional from opentelemetry import trace from .providers import LLMProvider from .strategies import RoutingStrategy, SmartRoutingStrategy, FallbackStrategy import logging logger logging.getLogger(__name__) tracer trace.get_tracer(__name__) class IntelligentLLMClient: def __init__(self, providers: List[LLMProvider], strategies: List[RoutingStrategy], default_strategy_name: str smart): self.providers providers self.strategy_map {s.name: s for s in strategies} self.default_strategy_name default_strategy_name # 缓存Provider健康状态避免每次选择都检查 self._health_cache: Dict[str, bool] {} self._cache_ttl 30 # 秒 self._last_health_check: Dict[str, float] {} async def generate(self, prompt: str, strategy_name: Optional[str] None, **kwargs) - str: strategy_name strategy_name or self.default_strategy_name strategy self.strategy_map.get(strategy_name) if not strategy: raise ValueError(fUnknown strategy: {strategy_name}) with tracer.start_as_current_span(llm_generate) as span: span.set_attributes({ strategy: strategy_name, prompt_length: len(prompt), provider_count: len(self.providers) }) # 更新Provider健康状态缓存 await self._refresh_health_cache() # 选择Provider try: selected_provider await strategy.select(self._get_healthy_providers(), prompt, kwargs) span.set_attribute(selected_provider, selected_provider.name) except Exception as e: span.record_exception(e) span.set_status(trace.Status(trace.StatusCode.ERROR, Provider selection failed)) logger.error(fFailed to select LLM provider: {e}) raise # 调用选中的Provider try: response await selected_provider.generate(prompt, **kwargs) span.set_status(trace.Status(trace.StatusCode.OK)) return response except Exception as e: span.record_exception(e) span.set_status(trace.Status(trace.StatusCode.ERROR, LLM generation failed)) logger.error(fLLM call failed for provider {selected_provider.name}: {e}) # 可选这里可以触发快速重试使用另一个Provider raise async def _refresh_health_cache(self): 异步更新所有Provider的健康状态缓存 current_time asyncio.get_event_loop().time() tasks [] for p in self.providers: if (p.name not in self._last_health_check or current_time - self._last_health_check.get(p.name, 0) self._cache_ttl): tasks.append(self._check_and_cache_health(p)) if tasks: results await asyncio.gather(*tasks, return_exceptionsTrue) for p, result in zip(self.providers, results): if not isinstance(result, Exception): self._health_cache[p.name] result self._last_health_check[p.name] current_time async def _check_and_cache_health(self, provider: LLMProvider) - bool: try: return await provider.health_check() except Exception as e: logger.warning(fHealth check failed for {provider.name}: {e}) return False def _get_healthy_providers(self) - List[LLMProvider]: return [p for p in self.providers if self._health_cache.get(p.name, False)]# src/app/dependencies.py from functools import lru_cache from llm_client.providers import OpenAIProvider, QwenProvider from llm_client.strategies import SmartRoutingStrategy, FallbackStrategy from llm_client.client import IntelligentLLMClient from .config import settings lru_cache def get_llm_client() - IntelligentLLMClient: # 初始化Provider providers [ OpenAIProvider( api_keysettings.openai_api_key, base_urlsettings.openai_base_url, modelgpt-3.5-turbo ), QwenProvider( base_urlsettings.qwen_api_base, modelqwen-7b-chat ) ] # 初始化策略 strategies [ SmartRoutingStrategy(namesmart), FallbackStrategy(namefallback, order[qwen, openai]), # 优先本地降级云端 ] # 创建客户端 client IntelligentLLMClient( providersproviders, strategiesstrategies, default_strategy_namesettings.default_llm_strategy ) return client# src/app/main.py from fastapi import FastAPI, Depends, HTTPException from pydantic import BaseModel from llm_client.client import IntelligentLLMClient from .dependencies import get_llm_client from .config import settings import logging logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) app FastAPI(titleLLM Smart Client Demo) class GenerationRequest(BaseModel): prompt: str strategy: str | None None temperature: float | None 0.7 max_tokens: int | None 1000 class GenerationResponse(BaseModel): answer: str provider_used: str | None None app.post(/generate, response_modelGenerationResponse) async def generate_text( request: GenerationRequest, llm_client: IntelligentLLMClient Depends(get_llm_client) ): 智能生成文本端点。 根据prompt内容和策略自动选择最合适的LLM。 try: answer await llm_client.generate( promptrequest.prompt, strategy_namerequest.strategy, temperaturerequest.temperature, max_tokensrequest.max_tokens ) # 注意实际客户端需要稍作修改以返回使用的provider信息 return GenerationResponse(answeranswer, provider_usedsee_trace) except Exception as e: logger.exception(Generation failed) raise HTTPException(status_code500, detailfGeneration failed: {str(e)}) app.get(/health) async def health_check(): return {status: healthy}4.5 部署与运行安装依赖poetry install # 或 pip install -r requirements.txt配置环境变量# .env 文件 OPENAI_API_KEYsk-... OPENAI_BASE_URL # 可选用于代理 QWEN_API_BASEhttp://localhost:8000/v1 # 本地Qwen服务地址 DEFAULT_LLM_STRATEGYsmart OTLP_ENDPOINThttp://localhost:4317 # OpenTelemetry收集器地址启动应用uvicorn src.app.main:app --reload --host 0.0.0.0 --port 8000测试请求curl -X POST http://localhost:8000/generate \ -H Content-Type: application/json \ -d {prompt: 如何用Python实现快速排序, strategy: smart}5. 常见问题与排查思路在实施“智能客户端”模式时你可能会遇到以下问题问题现象可能原因排查思路与解决方案所有Provider调用均超时或失败1. 网络问题防火墙、代理2. Provider配置错误API Key、Base URL3. 客户端请求格式不符1. 检查客户端网络连通性 (curl测试API端点)2. 验证环境变量配置是否正确加载3. 查看Provider的API文档确认请求格式、Headers路由策略未按预期选择模型1. 策略逻辑有误2. Provider健康检查不准确3. 缓存导致信息过时1. 在策略中添加详细日志打印决策依据2. 实现更可靠的健康检查如轻量级真实调用3. 调整健康状态缓存的TTL或提供手动刷新接口应用启动时初始化LLM客户端失败1. 依赖的配置缺失2. 初始化过程中网络调用失败如健康检查1. 将客户端初始化改为懒加载或异步初始化2. 为初始化过程添加重试机制和超时控制3. 提供降级模式允许部分Provider不可用监控数据缺失或不准1. OpenTelemetry SDK配置错误2. 追踪未正确传播1. 检查OTLP导出器配置和收集器状态2. 确保在异步上下文中正确使用start_as_current_span3. 在关键路径添加日志作为辅助客户端内存或CPU占用过高1. 健康检查过于频繁2. 请求/响应体过大未限制3. 连接池未复用1. 优化健康检查频率和缓存策略2. 对输入输出长度做限制3. 确保HTTP客户端使用连接池如httpx.AsyncClient6. 最佳实践与工程建议从“构建路由器”到“废弃路由器”的转变不仅仅是技术选型的变化更是架构思维的升级。以下是我们总结的最佳实践遵循“胖客户端瘦网关”原则将业务逻辑模型选择尽可能放在客户端让通用的基础设施API网关、服务网格做它们最擅长的事流量转发、安全、可观测性。避免在中间层堆积过多业务状态和逻辑。设计可插拔的策略系统路由策略应该是可配置、可热更新的。可以将策略定义为配置文件如YAML或甚至是一个小型的、可解释的规则引擎如使用duckduckgo。这比将策略硬编码在路由器中灵活得多。重视客户端可观测性在SDK中集成完整的遥测Tracing, Metrics, Logging。记录每次调用的模型选择结果、延迟、token用量、成本、错误信息。这些数据是优化路由策略和成本控制的黄金依据。实现优雅降级与熔断在客户端内部实现简单的熔断器模式如circuitbreaker库。当某个Provider失败率过高时自动将其标记为不可用一段时间避免雪崩效应。同时确保总有至少一个可用的后备方案。将配置外部化Provider的API密钥、端点、策略参数等都应通过环境变量或配置中心如Apollo、Nacos管理而不是硬编码在代码中。这便于在不同环境开发、测试、生产间切换。编写全面的单元和集成测试为你的智能客户端SDK编写测试模拟Provider成功、失败、超时等各种场景。确保路由逻辑和故障转移机制按预期工作。可以使用pytest和pytest-asyncio配合responses或httpx-mock来模拟HTTP请求。性能与资源管理连接池为每个Provider的HTTP客户端配置合理的连接池大小和超时。超时控制设置全局、连接、读取等多层超时避免慢请求阻塞整个应用。限流在客户端或API网关层对LLM调用实施限流保护下游服务和自己。安全考虑密钥管理永远不要在代码或版本库中明文存储API密钥。使用安全的密钥管理服务。输入输出审查在将用户输入发送给LLM或返回给用户前考虑进行内容安全过滤防止提示词注入或返回有害内容。废弃一个自己精心构建的组件需要勇气但软件架构的本质是管理复杂度。当发现一个组件引入的复杂度超过了其带来的价值时果断地简化架构往往是更优的选择。LLM智能客户端模式通过将智能下放、利用现有设施为我们提供了更简洁、更灵活、更可控的解决方案。希望我们的经验能帮助你重新审视自己的LLM架构做出最适合当前阶段的技术决策。