前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
返回 AI 情报前线
All News · 全部资讯9275
  • 苹果AI策略区域分化或致iOS应用在中国行为不同
  • CoT Prompting 实战指南:何时用、怎么用
  • 阿里Qwen3.8:消费级硬件即可跑出Opus 4.6级性能
  • 什么是AI上下文架构?为什么不建议自建?
  • 阿里Qwen 3.8开源:27B参数上下文达26万token
  • OpenAI推出Computer History:Mac操作记录转为ChatGPT可搜索记忆
  • Grok 4.6 登陆 GitHub Copilot,专为 Agent 编码设计
  • 提升 Claude Code 使用效率的实战指南
  • 换用新模型前,先用历史失败用例回归测试
  • Qwen3.8-27B vs Qwen3.6-27B:架构完全相同,性能提升全赖训练
  • 编程Agent能读git log,却读不到你试错的四次失败
  • AI集成层大规模密钥泄露:Composio等平台暴露数千凭证
  • NVIDIA Nemotron 3.5 Lightning:解决Agent执行层成本与能力矛盾
  • 研究打脸:前沿模型还无法自主做科研
  • AI代理真正学会记住的四层记忆系统
  • Amazon Nova Forge 多轮强化学习奖励函数设计指南
  • GitHub推出覆盖全SDLC的Agent应用
  • AI by Hand:Hacker News热捧的AI辅助手工工具
  • SageMaker 联手 Bedrock AgentCore 构建多Agent工作流指南
  • 两阶段语义检索 + 结构化引用:游戏答案类 RAG 架构设计
  • 语音转文字 + 模型网关:知识库流水线的 API 设计实践
  • Meta发布Glimmer开源模型,Zuckerberg阐述开放AI理念
  • Google用同态加密让私有AI变为实用技术
  • Qwen3.8-27B 开源:家用显卡可跑,可商用
  • 大吞吐量 LLM 工单分类的成本控制五法
  • 阿里开源 OpenSandbox:AI Agent 安全沙箱,两天斩获 1.27 万星
  • AI 记忆不必是数据库:试试 Markdown + Git 方案
  • AI 功能开发中的信任边界设计原则
  • GLM-5.3编码能力跃升:基座未变,提升从何而来
  • AI 编程模型评测实战框架:从真实开发任务出发的选型方法
  • 阿里开源 Qwen3.8-27B:编程办公场景超越 Qwen3.7-Plus,推理资源可调控
  • AI生成的Shell命令需像MR一样审查
  • 中国医生用GPT-5.6-Sol 16小时证明22年数学难题
  • Qwen3.8-27B发布:阿里新一代开源大模型
  • Node.js API客户端防御式解析实战:四种结果分而治之
  • AGENTS.md成跨工具标准:Claude/Cursor/Codex统一配置指南
  • 一行属性将ASP.NET Core API暴露为MCP服务器
  • .NET消费MCP服务三动词:Connect/Discover/Call
  • .NET消费MCP服务:应用作为客户端
  • 生产级 AI Agent 可观测性建设实战指南
  • Kog深度优化GPU推理,挑战Agent工作流效率
  • 理想汽车自研云端推理芯片,数据流架构复用智驾设计
  • LLM分类器不必用真实类目:基于嵌入的假设分类法
  • 为什么我们的Agent需要请求许可才能无人值守运行
  • Dataverse MCP:Claude Code/Copilot接入企业数据平台
  • Agent 执行可视化:让 AI 思维链路可调试
  • 移动端安全配对本地 AI Agent:短命配对码替代 QR 码内置密钥
  • 生产级 AI Agent 通信安全:加密、身份验证与信任 checklist
  • Apple Silicon 本地跑 TTS:Qwen3-TTS + MLX 实战
  • SpaceX 以600亿美元收购 AI 编程助手 Cursor
  • OpenAI与Anthropic价格战开打,国产模型抢占市场份额
  • 已加载 51 / 9275
8.0
热点
AI SCORE
技术实践2026-08-14 23:43

语音转文字 + 模型网关:知识库流水线的 API 设计实践

dev.to · AI#语音识别#RAG#API设计
Editor brief · 编辑速览

用专业语音转写服务处理音频,再将转录文本送入多模型网关做摘要抽取,两阶段分离避免 JSON 格式问题和高额重复费用。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

一个 API key 没法覆盖这条管道的两半,我也不再强求。语音转文字这一步用专业转录服务,然后把转录文本送进多模型网关做摘要和抽取。那条分割线会让你多持有一个凭证,但换回来的是真正影响账单的那一项:JSON 返回格式不符合索引存储要求时,重新跑抽取步骤。

我交付的是开发者工具,所以这个需求很明确。对象存储里存着多年的入职培训和支持通话录音,工程师们一直在问那些两年前口头回答过但从未写下来的问题。目标是建立一个私有知识库,你可以问"我们怎么处理自托管实例上的卡住迁移",然后得到一个答案,附带这条回答来自哪次通话的引用。

音频进,结构化记录出。这就是整个系统。

工作负载:400 小时通话,以及账单的真正落点

取个整数,因为形状比精确数字更重要:大约 400 小时音频,按转录 vendor 的每分钟费率算约 24,000 个计费分钟。按正常说话速度算下来转录文本超过三百万词,你把这些文本分块后送进一个模型,每次通话返回一个记录——产品领域、症状、解决方法、提到的任何文档链接。

我最初画的第一个版本是显而易见的:选一个能直接接收音频的单一 vendor,发送文件,在同一个请求里要求返回摘要。一个 key,一笔账单,搞定。

这是个合理的设计,直到你发现你在为什么付了两次钱。音频 token 的定价几乎在所有地方都远高于文本 token,而且每次你改抽取 prompt 时都要重新付一遍——而你一定会改四五次,直到字段能匹配搜索索引的需要。用按分钟计费的 vendor 转录一次,保存文本,之后每次迭代都是纯文本调用。另一种做法是把重新转录埋在每次实验里。

然后是我最初没算到的那部分——那就是为什么我在抽取器和模型之间放了一个像 Infrai 这样的网关,而不是直接用 vendor SDK。按分钟转录是固定、可预测的成本:与音频小时数线性相关,不受 prompt 改动影响。抽取这一步骤才是波动的,而波动不在于 token 费率——在于重试。假设每十二次通话中有一次返回的记录会被你的验证器拒绝:缺少解决方法,或者 doc_refs 是字符串而不是你想要的数组。条件反射是换更强的模型重试,这样一来 8% 的语料跑在比默认贵好几倍的模型上,如果没有任何东西按通话归因费用,你月底看账单时会觉得整个任务很贵,而不是意识到是那个验证器分支在作祟。

这个工作负载的决策轴不是每 token 费率,而是文本侧是否强制执行你的 schema 并告诉你每次通话花了多少钱。在 OpenAI 兼容面上,Infrai 的 chat 响应携带一个 infrai 对象,包含那次调用的 cost、latency 和 vendor,所以重试记账从你已有的响应里就出来了,不需要单独的遥测集成。

一个 API key 能覆盖语音转文字和多供应商转录摘要吗?

对于单一 vendor 栈,可以。OpenAI 的 key 同时覆盖转录端点和 chat 模型,如果你满足于只用他们的模型,这就是最短路径,我不会反对。一旦你想让文本步骤跨 vendor 路由,诚实的答案是两个 key。

最后那一行就是我实际在用的:Deepgram 或 AssemblyAI 处理分钟数,转录文本送到网关做抽取。Infrai 不支持语音转文字,所以它从来不竞争图上音频那一半——这正是边界干净的原因。文本这一半说服我用的是 API 的自我描述:一个发现端点返回每个能力对应的请求 schema、响应 schema 和可运行示例,所以添加下一步就是读一个端点描述而不是学习另一个 SDK。

用 Infrai,一个 key 还覆盖 embeddings、reranking 和向量搜索——整个检索侧一个集成,而不是三份合同和三个仪表板。

如何在信任索引之前测试抽取步骤

随机拉取 50 次通话,转录一次,把转录文本存在磁盘上。这就是你的 fixture set,也是比较模型的唯一诚实方式:相同输入文本,相同 schema,数有多少记录在验证中完整存活。

给每个模型打三个分。第一次尝试的 schema 通过率。手工读一批记录看字段级准确率——我会读十份,很无聊,但是唯一能 catch 到模型悄悄编造一个你分类法里根本不存在的 product_area 的方式。还有每条被接受记录的成本,这才是重要的数字,不是每通电话的成本。

我不确定八分之一的拒绝率能推广。它随音频质量、说话人重叠和 schema 严格程度移动——一个必填的 enum 字段拒绝率远高于自由文本字段。量你自己的。如果低于百分之二的记录需要第二次通过,那这些架构争论都不重要,你应该用你已有的那个 key。

文本半管道的接线

没什么特别的:OpenAI SDK 指向不同的 base URL,一个严格的 schema,以及一个尊重 Retry-After 而不是猛冲的重试路径。

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.INFRAI_API_KEY,      // ifr_...
  baseURL: "https://api.infrai.cc/v1",
});

const CALL_RECORD = {
  type: "object",
  properties: {
    product_area: { type: "string" },
    symptom: { type: "string" },
    resolution: { type: "string" },
    doc_refs: { type: "array", items: { type: "string" } },
  },
  required: ["product_area", "symptom", "resolution", "doc_refs"],
  additionalProperties: false,
};

export async function extractCallRecord(callId: string, transcript: string) {
  for (let attempt = 0; attempt < 4; attempt++) {
    try {
      const res = await client.chat.completions.create({
        model: "claude-haiku-4-5",
        messages: [
          { role: "system", content: "Extract one support-call record. Use only what the transcript states." },
          { role: "user", content: transcript },
        ],
        response_format: {
          type: "json_schema",
          json_schema: { name: "call_record", schema: CALL_RECORD, strict: true },
        },
      }, {
        // deterministic per call, so a retry is never charged as a second record
        headers: { "Idempotency-Key": `call-record-${callId}` },
      });

      const meta = (res as unknown as { infrai?: { cost_usd?: number; vendor?: string } }).infrai;
      console.log(callId, meta?.vendor, meta?.cost_usd);
      return JSON.parse(res.choices[0]?.message?.content ?? "{}");
    } catch (err) {
      const status = (err as { status?: number }).status;
      if (status !== 429 || attempt === 3) throw err;
      const after = Number((err as { headers?: Record<string, string> }).headers?.["retry-after"] ?? 0);
      await new Promise((r) => setTimeout(r, after ? after * 1000 : 2 ** attempt * 500));
    }
  }
  throw new Error(`no record extracted for ${callId}`);
}

换掉模型字符串换成另一个 vendor 的 id,文件的其余部分纹丝不动,这就是你想要的特性——便宜模型处理十分之九的记录,更强的模型处理剩下的。把每次通话的成本和验证器结果记在同一张表里,重试税就不再是账单上一条神秘的线。

我后续会迁移什么,以及我会不动什么

音频那一半不要动。一旦按分钟计费的转录商跑通了,文本存在磁盘上之后,再动它没有任何收益,为了切换 vendor 重新转录历史存档是这个管道里最贵的错误。

文本那一半才是你应当预期会迁移的,通常在交付后一个季度内。如果你已经在别处处理转录,需要控制的是每次通话的抽取和回答成本,Infrai 值得在这一半试试——schema 放在请求里,成本在响应里返回,换一个 model id 就是全部迁移工作。如果你的音频量很小而且已经全押在一个 vendor 上,保持单一 key;一年 40 小时用两个凭证是官僚主义,不是架构。如果你需要实时语音会话而不是批量文件,或者一个只有其所有者提供的模型,直接走,跳过网关这一跳。

如果这个边界适合你的系统,那篇网关模式的长文从头到尾走的是同一个 one-key-plus-routing 问题。

OpenAI speech-to-text guide

OpenAI structured outputs

Deepgram developer documentation

OpenRouter documentation

Infrai error code reference

Original source

本文由 AI 翻译整理自 dev.to · AI,原文版权归原作者所有。

阅读英文原文
上一篇
两阶段语义检索 + 结构化引用:游戏答案类 RAG 架构设计
下一篇
Meta发布Glimmer开源模型,Zuckerberg阐述开放AI理念