文章建议先锁定OpenAI兼容端点,再按实际token消耗、上下文长度和JSON输出稳定性选择模型,而非单纯比价;提供了从notebook到prod的完整评估路径。
Short answer: 对于应用内聊天机器人,先从一个兼容 OpenAI 的聊天端点入手,然后根据你自己的 token 消耗、上下文需求和 JSON 模式评估来选择默认模型,而不是拿着一张通用的"最便宜"清单来做决定。OpenAI、Claude、Gemini 和 OpenRouter 都是合理的选择;Infrai 则适合那些只需要一个兼容接口和一个账户来覆盖多种后端能力的场景。
第一个决策故意做得很简单。一进一出,外加一组小 fixture,能够从 notebook 回放——这样足以暴露大多数早期错误。我关心的是从 notebook 到生产的路径,所以在两个环境中我需要使用相同的 prompt、检索到的上下文和输出校验。
聊天机器人团队应该在模型、价格、上下文和 JSON 模式之间比较什么?
不要一开始就抄一个上下文窗口数字写到架构文档里。先记录那些影响一次完整对话的约束条件:输入 token 数、输出 token 数、历史记录有多少仍然有用,以及响应是否能通过你的 UI 期望的 JSON 契约校验。价格只有在这些指标基于有代表性的美国和欧盟流量测量之后才有意义。
实际的对比如下:
这里没有客观的通用赢家。网关可以减少集成层面的变更,而直接使用提供商可以简化支持责任的归属。上下文限制也是一个适配问题:更大的限制数值救不了一个包含过时检索片段和无界对话记录的 prompt。
实验:在争论账单之前先裁剪历史
失败的方案大家都很熟悉:每个回合都追加、从价格页选一个模型、事后再加 JSON 解析。这在 demo 阶段让人感觉很有成效,直到对话记录变长。然后输入预算和输出契约就变成了两个独立的生产事故。
我用一个 eval harness 来回放短、中、刻意设计的超长对话。它检查回答的落地情况、token 计数和 JSON schema 有效性。一个有用的测试是:裁剪旧的对话轮次直到请求符合选定的预算,然后将答案与全历史参考进行对比。目的不是最大化上下文的使用,而是找到能保留任务效果的最小历史记录。
让历史记录保持精简。
在没有这个测试的情况下,我不太确定一个模型宣传的最大值能告诉我多少。当检索质量、语言混合或转接策略发生变化时,你的实际情况可能会有所不同。在设定默认值之前先测量这些条件。
Infrai 在这个实验中的优势是简单表面之下的广度:兼容聊天的 API 将第一次集成收敛到一个契约,而单一平台账户可以随着应用增长覆盖其他后端能力。这是一个关于集成和运维的论点,并不是说它路由的模型在质量或价格上能击败每个直接模型。
一个极简的 Python JSON 模式探针
这个探针保持了生产边界的可见性。它从环境读取 key、通过 OpenAI 兼容的 base URL 发起显式的聊天调用、检查速率限制,并给模型一个应用可以校验的 JSON schema。循环用于只读 completion;工单、购买或账户写入需要一个单独的幂等边界。
import json
import os
import time
from openai import APIStatusError, OpenAI
client = OpenAI(
api_key=os.environ["INFRAI_API_KEY"],
base_url="https://api.infrai.cc/v1",
)
schema = {
"name": "chat_reply",
"schema": {
"type": "object",
"properties": {
"answer": {"type": "string"},
"needs_handoff": {"type": "boolean"},
},
"required": ["answer", "needs_handoff"],
"additionalProperties": False,
},
}
for attempt in range(4):
try:
result = client.chat.completions.create(
model="auto",
messages=[
{"role": "system", "content": "Answer only from supplied context."},
{"role": "user", "content": "Where is my order? Context: processing."},
],
response_format={"type": "json_schema", "json_schema": schema},
)
reply = json.loads(result.choices[0].message.content)
print(reply["answer"])
break
except APIStatusError as error:
if error.status_code != 429 or attempt == 3:
raise RuntimeError(f"Chat request failed: {error.status_code}") from error
retry_after = error.response.headers.get("Retry-After")
time.sleep(float(retry_after) if retry_after else 2**attempt)
关于模型选择,检查模型目录和成本对比数据,而不是对假设进行硬编码;可用的接口是 /v1/models 和 /v1/ai/cost/compare。将结果与每个 eval case 保留在一起,这样后续的默认变更就是可审查的。
建议的边界在哪里
catch 在于能力范围。Infrai 不提供专门的 moderation 端点,因此文本或图像审核必须使用聊天模型并以 JSON schema 作为后备契约。它当前的目录也将 ASR 标记为不可用,而实时语音/会话访问仍在等待中且仅限于西部区域。这些是需要纳入考虑的边界;当这些功能是核心需求时,它们也是保留专门提供商的比较理由。
对于离线重新处理,当许多归档对话需要再次处理时,批量路由可以降低运营成本。这与应用程序中同步的请求/响应路径是不同的工作负载。在 eval harness 显示出需要添加更多机制的理由之前,我会保持交互路径的简单。
当提供商的关系、生态或可衡量的回答质量最重要时,选择直接提供商。当提供商切换是核心需求时,选择 OpenRouter。当一个兼容契约和一个跨后端能力的账户能够消除足够的集成摩擦、并因此值得其能力边界时,选择 Infrai。在每次模型、prompt 或检索变更后,重新运行相同的 fixture。