{"repo": "boyzhong123/testmcp", "files": {"src/app/[locale]/docs/page.tsx": {"6270b78927175ed620bfbf35547988ca74f83f20": {"t": 1785746567.7356908, "n": 190353, "h": "ecf33defbf4a8dac", "c": "'use client';\n\nimport { useLocale } from 'next-intl';\nimport { Link } from '@/i18n/routing';\nimport { DocsShell, type NavGroup } from './docs-shell';\nimport {\n CodeBlock,\n DocSection,\n SubDoc,\n ParamTable,\n Callout,\n FlowStep,\n ToolTable,\n} from './docs-shared';\nimport { DocsEnglishBody } from './docs-content-en';\nimport {\n BookOpen,\n Code2,\n Zap,\n FileText,\n Terminal,\n Globe,\n Mic,\n MessageSquare,\n BarChart3,\n AlertTriangle,\n Radio,\n FolderOpen,\n Workflow,\n Sparkles,\n Plug,\n Bot,\n Building2,\n Check,\n Sparkle,\n Languages,\n GraduationCap,\n Notebook,\n Gauge,\n ListChecks,\n Network,\n} from 'lucide-react';\n\n/* ─── Navigation Structure ─── */\n\nconst NAV = [\n { id: 'concept', icon: Workflow, label: 'MCP 工作原理', children: [\n { id: 'why-mcp', label: '为什么需要 MCP' },\n { id: 'scenario-walkthrough', label: '场景走查 · 6 步' },\n { id: 'dev-responsibility', label: '开发者只做两件事' },\n { id: 'integration-paths', label: '三种接入姿势' },\n ]},\n { id: 'architecture', icon: Terminal, label: '架构说明', children: [\n { id: 'arch-overview', label: '两种接入模式总览' },\n { id: 'arch-mcp', label: 'MCP 模式架构' },\n { id: 'arch-rest', label: 'functioncalling 模式架构' },\n { id: 'transport', label: '传输协议对比' },\n ]},\n { id: 'quick-start', icon: Zap, label: '快速开始', children: [\n { id: 'overview', label: '概述' },\n { id: 'requirements', label: '系统要求' },\n { id: 'install', label: '安装方式' },\n { id: 'env-vars', label: '环境变量' },\n ]},\n { id: 'config', icon: Plug, label: '接入 · 直接用(零代码)', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: '扣子(Coze)' },\n { id: 'config-coze-workflow', label: 'Coze 工作流' },\n { id: 'config-ai-workspace', label: 'AI 工作台 · 豆包 / 飞书 / WorkBuddy / 钉钉' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: '其他 MCP 客户端' },\n ]},\n { id: 'config-code', icon: Code2, label: '接入 · 编程用 MCP(SDK / 代码)', children: [\n { id: 'code-mcp-sdk', label: '① 官方 MCP 客户端库' },\n { id: 'code-agent-frameworks', label: '② LangChain / Mastra / Agents SDK' },\n { id: 'code-function-calling', label: '③ 直调 chat.completions · 动态 tools' },\n { id: 'code-selfhosted-agent', label: '④ 自研后端 Agent' },\n { id: 'llm-deepseek', label: 'DeepSeek' },\n { id: 'llm-glm', label: 'GLM(智谱)' },\n { id: 'llm-kimi', label: 'KIMI(Moonshot)' },\n { id: 'llm-doubao', label: '豆包 Seed 2.0(火山方舟)' },\n { id: 'llm-openai', label: 'OpenAI(GPT-5.1)' },\n { id: 'llm-claude', label: 'Claude(Anthropic)' },\n { id: 'llm-gemini', label: 'Gemini(Google)' },\n { id: 'llm-comparison', label: '模型对比速查' },\n ]},\n { id: 'config-rest', icon: Network, label: '接入 · 非 MCP 原生 REST(cvx_fc)', children: [\n { id: 'rest-overview', label: 'functioncalling 模式总览' },\n { id: 'rest-catalog', label: '函数目录 · GET /v1/functions' },\n { id: 'rest-oneshot', label: '一次性文件评测' },\n { id: 'rest-streaming', label: '流式评测 · 三步骤' },\n { id: 'rest-examples', label: 'JS / Android 完整示例' },\n { id: 'rest-resume', label: '断线恢复 · 兜底拉取' },\n ]},\n { id: 'eval-modes', icon: Radio, label: '评测模式', children: [\n { id: 'stream-eval', label: '实时录音评测' },\n { id: 'stream-flow', label: '流式评测流程' },\n { id: 'file-eval', label: '音频文件评测' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API 参考', children: [\n { id: 'tools-en', label: '英文评测工具' },\n { id: 'tools-cn', label: '中文评测工具' },\n { id: 'result-fields', label: '评测结果字段' },\n { id: 'error-codes', label: '错误码' },\n ]},\n { id: 'best-practices', icon: FileText, label: '最佳实践', children: [\n { id: 'prompt-templates', label: 'Prompt 模板' },\n { id: 'error-handling', label: '错误处理' },\n { id: 'performance', label: '性能优化' },\n ]},\n { id: 'service-info', icon: Globe, label: '服务信息', children: [\n { id: 'endpoints', label: '服务端点' },\n { id: 'limits', label: '服务限制' },\n { id: 'changelog', label: '更新日志' },\n ]},\n];\n\nconst NAV_EN: NavGroup[] = [\n { id: 'concept', icon: Workflow, label: 'How MCP works', children: [\n { id: 'why-mcp', label: 'Why MCP' },\n { id: 'scenario-walkthrough', label: 'Scenario · 6 steps' },\n { id: 'dev-responsibility', label: 'Two developer tasks' },\n { id: 'integration-paths', label: 'Three integration styles' },\n ]},\n { id: 'architecture', icon: Terminal, label: 'Architecture', children: [\n { id: 'arch-overview', label: 'Two integration modes' },\n { id: 'arch-mcp', label: 'MCP mode architecture' },\n { id: 'arch-rest', label: 'Function-calling architecture' },\n { id: 'transport', label: 'Transport comparison' },\n ]},\n { id: 'quick-start', icon: Zap, label: 'Quick start', children: [\n { id: 'overview', label: 'Overview' },\n { id: 'requirements', label: 'Requirements' },\n { id: 'install', label: 'Install' },\n { id: 'env-vars', label: 'Environment' },\n ]},\n { id: 'config', icon: Plug, label: 'Zero-code clients', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: 'Coze' },\n { id: 'config-coze-workflow', label: 'Coze workflows' },\n { id: 'config-ai-workspace', label: 'Enterprise AI workspaces' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: 'Other MCP clients' },\n ]},\n { id: 'config-code', icon: Code2, label: 'MCP · SDK / code integration', children: [\n { id: 'code-mcp-sdk', label: '① Official MCP SDK' },\n { id: 'code-agent-frameworks', label: '② Agent frameworks' },\n { id: 'code-function-calling', label: '③ chat.completions · dynamic tools' },\n { id: 'code-selfhosted-agent', label: '④ Custom backend agent' },\n { id: 'llm-deepseek', label: 'DeepSeek' },\n { id: 'llm-glm', label: 'GLM (Zhipu)' },\n { id: 'llm-kimi', label: 'KIMI (Moonshot)' },\n { id: 'llm-doubao', label: 'Doubao Seed 2.0 (Volcano Ark)' },\n { id: 'llm-qwen', label: 'Qwen (Alibaba)' },\n { id: 'llm-openai', label: 'OpenAI (GPT-5.1)' },\n { id: 'llm-claude', label: 'Claude (Anthropic)' },\n { id: 'llm-gemini', label: 'Gemini (Google)' },\n { id: 'llm-comparison', label: 'Model comparison' },\n ]},\n { id: 'config-rest', icon: Network, label: 'Non-MCP REST (cvx_fc)', children: [\n { id: 'rest-overview', label: 'Function-calling overview' },\n { id: 'rest-catalog', label: 'Function catalog · GET /v1/functions' },\n { id: 'rest-oneshot', label: 'One-shot file eval' },\n { id: 'rest-streaming', label: 'Streaming · 3 steps' },\n { id: 'rest-examples', label: 'JS / Android samples' },\n { id: 'rest-resume', label: 'Resume & fallback' },\n ]},\n { id: 'eval-modes', icon: Radio, label: 'Evaluation modes', children: [\n { id: 'stream-eval', label: 'Streaming mic' },\n { id: 'stream-flow', label: 'Streaming flow' },\n { id: 'file-eval', label: 'Audio files' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API reference', children: [\n { id: 'tools-en', label: 'English tools' },\n { id: 'tools-cn', label: 'Chinese tools' },\n { id: 'result-fields', label: 'Result fields' },\n { id: 'error-codes', label: 'Errors' },\n ]},\n { id: 'best-practices', icon: FileText, label: 'Best practices', children: [\n { id: 'prompt-templates', label: 'Prompt templates' },\n { id: 'error-handling', label: 'Errors & retries' },\n { id: 'performance', label: 'Performance' },\n ]},\n { id: 'service-info', icon: Globe, label: 'Service info', children: [\n { id: 'endpoints', label: 'Endpoints' },\n { id: 'limits', label: 'Limits' },\n { id: 'changelog', label: 'Changelog' },\n ]},\n];\n\n/* ─── Page(英文 / 中文拆成两个组件,避免切换语言时 Hooks 数量变化导致白屏)─── */\n\nfunction DocsPageEn() {\n return (\n \n \n \n );\n}\n\nfunction DocsPageZh() {\n return (\n \n {/* ══════ MCP 工作原理 ══════ */}\n \n\n \n

\n 大模型(GPT / Claude / Gemini / 通义千问 等)本质上是文字大脑:它擅长读和写,但天生听不到音频、打不开你的数据库、调不通第三方 API。\n

\n

\n MCP(Model Context Protocol)是一套由 Anthropic 主导、业界共同推进的开放协议,它像一根\"对讲机\":让大模型可以在需要时主动去调用外部能力(工具、数据源、服务),然后把结果接回来继续对话。\n

\n
\n
\n
\n \n 没有 MCP 的做法\n
\n
    \n
  • · 研究评测服务的 REST 文档
  • \n
  • · 自己写鉴权 / 上传 / 轮询代码
  • \n
  • · 把结果序列化后塞进 prompt
  • \n
  • · 每换一个大模型都得重写一遍
  • \n
\n
\n
\n
\n \n 用驰声 MCP 之后\n
\n
    \n
  • · 填一行 MCP Server 地址
  • \n
  • · 大模型自动发现&调用评测工具
  • \n
  • · 换任何支持 MCP 的大模型都能用
  • \n
  • · 不写一行调用代码
  • \n
\n
\n
\n \n MCP 让\"接入语音评测\"从一个\"后端工程\"变成了一个\"配置项\"。这也是为什么 Cursor、Claude Desktop、Dify、Coze、字节豆包、飞书智能助手都已经原生支持 MCP。\n \n
\n\n \n

\n 想象一个具体场景:一位开发者用 Claude 做了一款 「AI 雅思口语陪练」小程序,接入驰声语音评测 MCP。当用户发来一段录音,整个链路是这样的:\n

\n
\n \n

配置阶段(开发者 · 一次性)

\n

在 AI 后端的配置文件里填一行驰声 MCP Server 地址。大模型启动时自动发现:「我多了一个叫语音评测的工具」。

\n
\n \n

接收用户指令(终端用户)

\n

小程序用户发来一段自我介绍录音:「帮我听听,发音哪里有问题?」后端把「文字 + 录音链接」打包给大模型。

\n
\n \n

大模型自主思考(LLM · 最核心的魔法)

\n
\n 「用户让我听发音。」
\n 「但我只是文字大脑,我听不到。」
\n 「等等 —— 开发者给了我一个叫 chivox_voice_eval 的 MCP 工具!」\n
\n
\n \n

MCP 协议 · 自动调用(LLM → 驰声)

\n

大模型自动按 MCP 标准构造 tools/call 请求,把录音链接和参考文本发到驰声服务。开发者不需要写任何调用代码。

\n
\n \n

驰声服务处理(评测引擎)

\n

驰声对音频进行考试级打分,把结构化结果通过 MCP 原路返回:overall 85、/θ/ 音发音错误、流利度 88。

\n
\n \n

大模型整合并输出反馈(LLM)

\n

大模型把冷冰冰的分数翻译成温柔反馈:

\n
\n 「你的自我介绍很棒!综合 85 分 🎉 不过 think 这个词的 /θ/ 咬舌音不太标准,我们一起来练一下……」\n
\n
\n
\n \n 整条链路里,MCP 只出现在 ① 和 ④:① 让开发者一次性告诉大模型「你多了一个工具」,④ 让大模型可以自动调用它。这两步的标准化,就是 MCP 的全部价值。\n \n
\n\n \n

听起来复杂,但对开发者来说只需要两件事:

\n
\n
\n
\n 1\n 填一次 MCP 配置\n
\n

\n 在 AI 后端的配置里填入驰声 MCP Server 地址和 API Key,就这一次,以后新加评测能力完全免开发。\n

\n {`{\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://mcp.cloud.chivox.com\",\n \"apiKey\": \"sk-••••••••••\"\n }\n}`}\n
\n
\n
\n 2\n 写一段 System Prompt\n
\n

\n 告诉大模型这个工具是做什么的、什么时候调用、结果怎么转成用户友好的反馈。\n

\n {`你是一位英语口语教练。\n当用户发来录音时:\n1. 调用 chivox_voice_eval 评分\n2. 聚焦 <70 分的音素家族\n3. 用高情商话术给出练习建议`}\n
\n
\n

\n 其余所有事情 —— 音频上传、鉴权、工具发现、调用时机、返回格式、结果整合 —— 都由 MCP 协议和大模型自己搞定。\n

\n
\n\n \n

根据你的技术栈,有三种等价的接入方式,底层都走完全相同的 MCP 协议:

\n\n {/* ── 姿势一:可视化 ── */}\n
\n
\n \n

姿势一 · 可视化拖拽(扣子 / Coze / 飞书智能助手)

\n
\n

\n 适合产品经理、运营、不写后端代码的开发者。整个过程像在手机上装 App。\n

\n
    \n
  1. 找到入口:在扣子平台的 「插件 / 工具」 配置区,点击「添加 MCP 服务」。
  2. \n
  3. 填两个字段(这也是你未来会从驰声这边拿到的):\n
    \n \n \n \n \n \n
    服务器地址https://mcp.cloud.chivox.com
    鉴权密钥sk-•••••••••• (由驰声分配,用于计费与识别)
    \n
    \n
  4. \n
  5. 平台自动发现能力:扣子会访问你填的地址,读取 MCP Server 自描述的\"说明书\"。瞬间明白:「这是个语音评测工具,需要传音频,会返发音分」。
  6. \n
  7. 右侧测试:在平台的聊天框里发一段语音,大模型就会自动调用工具。整个过程不需要写一行代码。
  8. \n
\n
\n\n {/* ── 姿势二:代码框架 ── */}\n
\n
\n \n

姿势二 · 代码框架配置(Dify / LangChain / 自研后端)

\n
\n

\n 适合做独立 APP / 小程序、用 Dify 或 LangChain 写 Agent 的极客开发者。核心就是往配置文件里加一段 JSON。\n

\n
    \n
  1. 打开配置文件(项目根目录下的 mcp.json 或框架指定的配置路径)。
  2. \n
  3. 在 mcpServers 下增加一个节点:\n {`{\n \"mcpServers\": {\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://mcp.cloud.chivox.com\",\n \"env\": {\n \"API_KEY\": \"你的专属密钥\"\n }\n }\n }\n}`}\n
  4. \n
  5. 重启后端服务。大模型的底层调度器会在启动时自动连上驰声 MCP Server,把 16 种评测工具注册成随时待命的 tools。
  6. \n
  7. 触发调用:用户发来录音后,大模型看到 system prompt 的引导,自动选择合适的工具(单词/句子/段落/半开放)调用。
  8. \n
\n
\n\n {/* ── 姿势三:Function Calling 直连(分 A / B 两种做法) ── */}\n
\n
\n \n

姿势三 · 原生 Function Calling(豆包 / DeepSeek / OpenAI 兼容 API)

\n
\n

\n 适合不用任何 Agent 框架、直接调用 LLM API 的后端开发者。豆包 1.5+ / DeepSeek / GPT / Qwen 等模型都走标准 chat.completions 的 tools 参数。这里又分 A / B 两种做法,B 才是生产推荐。\n

\n\n \n 常见疑问:\"要不要手写一个 tool 定义?\"
\n — 姿势一 / 二不用(Coze、Dify、火山方舟控制台、Claude Desktop 会自动从 MCP Server 拉工具列表)。
\n — 姿势三看你选 A 还是 B:A 要手写,B 用 MCP 客户端库自动拉。\n
\n\n {/* ── 3-A:手写 tool schema ── */}\n
\n
\n

3-A · 手写 tool schema(最快验证,不推荐生产)

\n 快速 Demo\n
\n

\n 自己写一段 JSON Schema 告诉豆包\"有个工具叫 xxx,参数长这样\",豆包返回 tool_call 后你再手动去调驰声 MCP。缺点:驰声有 16 个评测工具,你每加一个题型都要改代码。\n

\n {`import os, json\nfrom openai import OpenAI\n\nclient = OpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv('ARK_API_KEY'),\n)\n\n# ─── 手写一段 tool schema(不推荐:16 个工具就要写 16 段)───\ntools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": \"en_word_eval\",\n \"description\": \"英语单词发音评测。当用户让你评价英语发音并提供录音链接时调用。\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"audio_url\": {\"type\": \"string\", \"description\": \"录音 URL\"},\n \"reference_text\": {\"type\": \"string\", \"description\": \"参考文本,如 Apple\"},\n },\n \"required\": [\"audio_url\", \"reference_text\"]\n }\n }\n}]\n\nresp = client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,拿到评测结果后温柔地反馈,不要直接报分数。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n)\n\nmsg = resp.choices[0].message\nif msg.tool_calls:\n args = json.loads(msg.tool_calls[0].function.arguments)\n # ↓↓↓ 这里手动调驰声 MCP,再把结果回填给豆包做第二趟 ↓↓↓\n # result = requests.post(\"https://mcp.cloud.chivox.com\", json={...})`}\n
\n\n {/* ── 3-B:MCP 自动发现 ── */}\n
\n
\n

\n 3-B · 用 MCP 客户端库自动发现 \n

\n 生产推荐\n
\n

\n 启动时连上驰声 MCP Server,调一次 tools/list,把 16 个评测工具自动转成 Function Calling 的 tools 格式。驰声加新工具,你代码不用改。这才是 MCP 协议的真正价值。\n

\n {`import asyncio, os\nfrom openai import AsyncOpenAI\nfrom mcp import ClientSession\nfrom mcp.client.streamable_http import streamablehttp_client\n\nclient = AsyncOpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv(\"ARK_API_KEY\"),\n)\n\nasync def main():\n # ─── 1. 连驰声 MCP Server,自动拉取全部 16 个工具 ───\n async with streamablehttp_client(\n \"https://mcp.cloud.chivox.com\",\n headers={\"Authorization\": f\"Bearer {os.getenv('CHIVOX_KEY')}\"},\n ) as (read, write, _):\n async with ClientSession(read, write) as session:\n await session.initialize()\n mcp_tools = (await session.list_tools()).tools # ← 一行拿到全部工具\n\n # ─── 2. MCP schema → OpenAI Function Calling schema ───\n tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema, # MCP 直接给 JSON Schema\n }\n } for t in mcp_tools]\n\n # ─── 3. 正常调豆包,tools 由 MCP 动态注入 ───\n resp = await client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,收到评测结果后温柔反馈。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n )\n\n # ─── 4. 折返跑:豆包选好工具后,直接走 MCP 调驰声 ───\n msg = resp.choices[0].message\n if msg.tool_calls:\n call = msg.tool_calls[0]\n result = await session.call_tool(\n call.function.name,\n arguments=__import__(\"json\").loads(call.function.arguments),\n )\n # 把 result 回填给豆包做第二趟 chat.completions 即可\n\nasyncio.run(main())`}\n

\n 想要更省心?直接用 官方 mcp python sdk、mcp-use、openai-agents,或火山官方 Arkitect 高代码 SDK,它们都把上面这段\"MCP → Function Calling\"的桥接封装好了。\n

\n
\n
\n\n \n 三种姿势走的是完全相同的 MCP 协议,能力完全等价。选型建议:产品经理 / 原型验证用姿势一(Coze 填表单);AI 客户端用户用姿势二(Cursor / Claude Desktop 填 mcp.json);后端生产服务用姿势三-B(MCP 客户端库自动发现工具,不要手写 tool schema)。\n \n
\n\n
\n\n {/* ══════ 架构说明 ══════ */}\n \n\n \n

驰声语音评测对外提供两条并行入口,底层指向同一个评测引擎,但面向不同的客户端环境,按能力选其一即可:

\n\n
\n
\n

\n \n MCP 模式(推荐首选)\n

\n
    \n
  • • JSON-RPC 2.0 · Streamable HTTP / stdio
  • \n
  • • 所有支持 MCP 的 IDE / 桌面 AI / Agent 框架 零代码即用
  • \n
  • • 工具列表自动注入,新增题型业务侧不用改
  • \n
  • • 本地代理 chivox-local-mcp 支持麦克风实时录音
  • \n
\n

典型客户端:Cursor / Claude Desktop / Coze / Dify / LangChain / 自研后端 Agent

\n
\n
\n

\n \n functioncalling 模式(非 MCP · cvx_fc)\n

\n
    \n
  • • OpenAI function-calling 风格 · 纯 REST + WebSocket
  • \n
  • • 不依赖任何 MCP SDK,普通 HTTP 客户端即可打
  • \n
  • • 内置 resume_token 断线续播、intermediate 中间结果、backpressure 反压
  • \n
  • • 为不能 / 不想引入 MCP 的客户端环境保留兜底通道
  • \n
\n

典型客户端:原生 Android / iOS / Flutter、微信 / 支付宝小程序、老版本 Java / PHP 后端

\n
\n
\n\n

怎么选?

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
你的客户端环境建议
Cursor / Claude Desktop / 各类 AI IDE 能装 MCPMCP 模式
Python / Node / Java 后端能引入 MCP SDKMCP 模式
Coze / Dify / n8n 等可视化平台MCP 模式
原生 Android / iOS App,想直接打 HTTP + WSfunctioncalling 模式
微信 / 支付宝 / 抖音小程序functioncalling 模式
老系统 / 封闭运行时,不想引入 MCP 依赖functioncalling 模式
\n
\n \n 同一个会话二选一、不要混用:MCP 的 /ws/audio/ 和 functioncalling 的 /ws/eval/ 属于不同的会话 ID 空间。\n \n
\n\n \n

MCP 模式下有两种部署形态,底层均走 JSON-RPC 2.0,区别只在客户端离服务端有没有一层本地代理:

\n\n

形态 A · 远程直连(零代码)

\n

适合 Cursor / Coze / Dify / n8n 等支持 Streamable HTTP 的客户端,无本地依赖。

\n
\n
\n

AI 客户端

\n

Cursor / Coze /
Dify / n8n …

\n
\n
\n

⇄

\n

Streamable HTTP
JSON-RPC 2.0

\n
\n
\n

驰声 MCP Server

\n

/mcp · /ws/audio
评测引擎

\n
\n
\n\n

形态 B · 本地代理(支持麦克风实时录音)

\n

适合 Claude Desktop / Claude Code 等以 stdio 挂载 MCP 的客户端,需要本地实时录音时走这条路径。

\n
\n
\n

AI 客户端

\n

Claude Desktop /
Claude Code

\n
\n
\n

⇄

\n

stdio

\n
\n
\n

chivox-local-mcp

\n

本地代理 · SoX 录音

\n
\n
\n

⇄

\n

HTTP / WS

\n
\n
\n

Remote Chivox

\n

MCP Server
评测引擎

\n
\n
\n\n

标准数据流

\n
    \n
  1. initialize → 协商协议版本与能力
  2. \n
  3. tools/list → 拉取 16 个评测工具的 JSON Schema
  4. \n
  5. 文件模式:tools/call → 服务端执行评测 → 返回 JSON-RPC 响应
  6. \n
  7. 实时模式:create_stream_session → 走 /ws/audio/{'{session_id}'} 推流 → stream_eval_result 收结构化评分
  8. \n
\n\n

原始 JSON-RPC 请求示例(自建客户端可直接抄)

\n

\n 如果你不使用官方 MCP SDK 而是直接通过 POST /mcp 自己拼 JSON-RPC 2.0 报文,最小可用的三条请求如下。所有请求均需携带 Authorization: Bearer <your_api_key>。\n

\n\n

① 初始化 · initialize

\n {`{\n \"jsonrpc\": \"2.0\",\n \"id\": 1,\n \"method\": \"initialize\",\n \"params\": {\n \"protocolVersion\": \"2024-11-05\",\n \"capabilities\": {},\n \"clientInfo\": { \"name\": \"my-client\", \"version\": \"1.0.0\" }\n }\n}`}\n

成功后服务端返回协议版本、服务端能力、服务端信息,此后方可调用其他方法。

\n\n

② 拉取工具清单 · tools/list

\n {`{\n \"jsonrpc\": \"2.0\",\n \"id\": 2,\n \"method\": \"tools/list\",\n \"params\": {}\n}`}\n

返回全部 16 个评测工具(英 10 + 中 6)+ 2 个流式工具,含名字、描述、参数 JSON Schema。客户端应缓存此响应,后续按需展示 / 桥接给 LLM。

\n\n

③ 调用工具 · tools/call

\n {`{\n \"jsonrpc\": \"2.0\",\n \"id\": 3,\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"en_word_eval\",\n \"arguments\": {\n \"ref_text\": \"hello\",\n \"audio_base64\": \"\",\n \"accent\": 2,\n \"rank\": 100\n }\n }\n}`}\n

\n 成功响应放在 result.content[0].text(JSON 字符串形式,内部就是评测结果结构);失败则返回 error.code + error.message。\n

\n\n \n 用 Python / TypeScript 官方 MCP SDK 的用户不需要关心以上 JSON-RPC 细节——SDK 已经封装好 session.initialize() / session.list_tools() / session.call_tool()。这里仅供裸协议实现或排障时参考。\n \n
\n\n \n

没有代理、没有 SDK,客户端 ↔ 服务端只有两条链路:一条 REST 管会话 / 文件评测,一条 WebSocket 推音频帧。

\n\n
\n
\n

客户端

\n

原生 App / 小程序 /
老版后端 / 纯前端

\n
\n
\n

⇄

\n

HTTP REST
/v1/call · /v1/functions

\n
\n
\n

cvx_fc 服务

\n

function-calling 网关
评测引擎

\n
\n
\n

⇄

\n

WebSocket
/ws/eval/{id}

\n
\n
\n

客户端推流

\n

麦克风 / 分片缓冲

\n
\n
\n\n

三条典型数据流

\n
\n
\n

a. 一次性文件评测

\n

POST /v1/call(audio_url 或 audio_base64) → 同步返回评分

\n
\n
\n

b. 流式实时评测

\n

POST /v1/call → start_stream_eval → 拿 ws_url → 连 /ws/eval/{id} → 推 PCM → 收 intermediate / backpressure → 发 stop → 收 result

\n
\n
\n

c. 断线恢复 + 兜底拉取

\n

网络断开 60 秒内 → 用 resume_token 重连续播;彻底失败 → POST /v1/call → get_stream_result 兜底

\n
\n
\n\n

特色能力

\n
    \n
  • resume_token — 网络抖动 60 秒内可无缝续播,服务端挂起会话状态
  • \n
  • intermediate 帧 — 边推边吐部分结果,前端可做实时波形 / 分数涂色
  • \n
  • backpressure 反馈 — 服务端主动下发 suggested_interval_ms,客户端按建议降速
  • \n
  • 结构化错误码 — SESSION_EXPIRED / INVALID_STATE / … 便于客户端写重试逻辑
  • \n
\n

详细的接入示例见下文 「接入 · 非 MCP 原生 REST」 大节。

\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
维度MCP 模式functioncalling(cvx_fc)
协议JSON-RPC 2.0REST + WebSocket
入口路径POST /mcpPOST /v1/call
列出工具tools/listGET /v1/functions
调用工具tools/callPOST /v1/call + name
流式音频 WS{'/ws/audio/{session_id}'}{'/ws/eval/{session_id}'}
本地 stdio 代理支持(chivox-local-mcp)不适用
断线重连客户端 SDK 自动重连resume_token(60s 挂起)
中间结果stream_eval 回调intermediate 帧
背压反馈—backpressure 帧
客户端依赖MCP SDK(官方 / 框架)仅 HTTP + WS 客户端
\n
\n
\n
\n\n {/* ══════ 快速开始 ══════ */}\n \n\n \n

chivox-local-mcp 是驰声语音评测的 MCP 本地代理,通过 Model Context Protocol 将远程驰声评测服务桥接到本地,让 AI 助手(Claude Desktop、Claude Code、Cursor 等)直接调用语音评测能力。

\n

它支持两种评测模式,覆盖从即时交互到批量处理的全部场景:

\n
\n
\n
\n \n 实时录音评测\n
\n

通过麦克风边录边评,音频以 WebSocket 流式推送,无需生成中间文件,延迟更低、体验更佳。

\n
\n
\n
\n \n 音频文件评测\n
\n

支持本地文件路径、Base64 编码、URL 三种输入,适合已有音频的批量评测场景。

\n
\n
\n 当前支持 16 种评测工具:英文 10 种(单词、句子、段落、纠音、自然拼读、口语选择、半开放题等)+ 中文 6 种(汉字、拼音、词句、段落、有限分支、AI Talk)。\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n
依赖版本说明
Node.js{'>'}= 18运行时必须
SoXany仅实时录音功能需要(处理麦克风音频流)
\n
\n

安装 SoX(仅在使用实时录音时需要):

\n {`# macOS\nbrew install sox\n\n# Ubuntu / Debian\nsudo apt-get install sox`}\n
\n\n \n

方式一:npm 全局安装(推荐)

\n {`npm install -g chivox-local-mcp`}\n\n

方式二:npx 免安装运行

\n {`MCP_REMOTE_URL=https://fc.cloud.chivox.com npx chivox-local-mcp`}\n\n

方式三:从源码构建

\n {`git clone https://git.chivox.com/CLOUD_DEV/cvx_local_mcp.git\ncd cvx_local_mcp\nbash scripts/build.sh`}\n
\n\n \n \n \n
\n\n {/* ══════ 接入 · 直接用(零代码) ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 不用写代码、不用装 SDK,只在客户端的「MCP 配置」或「扩展」里填一段 JSON / URL
  • \n
  • 保存后 LLM 自动发现 16 个评测工具,并在对话 / Agent 中自主调用
  • \n
  • 覆盖 IDE 编程助手、桌面 AI 客户端、企业 AI 工作台、可视化 Bot / 工作流平台四大生态
  • \n
\n
\n\n\n \n
    \n
  1. 打开 Cursor 设置(Cmd + ,)
  2. \n
  3. 左侧选择 MCP(或搜索 "MCP")
  4. \n
  5. 点击 Add new MCP server
  6. \n
  7. 填写配置并保存:
  8. \n
\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://mcp.cloud.chivox.com\"\n}`}\n Cursor 使用远程 Streamable HTTP 模式直连,无需安装本地代理。如需实时录音功能,请使用下方 Claude Desktop 的本地代理配置。\n
\n\n \n

编辑配置文件(macOS:~/Library/Application Support/Claude/claude_desktop_config.json):

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"chivox-local-mcp\",\n \"env\": {\n \"MCP_REMOTE_URL\": \"https://fc.cloud.chivox.com\",\n \"MCP_API_KEY\": \"your-api-key\"\n }\n }\n }\n}`}\n

如果是从源码构建:

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/cvx_local_mcp/dist/index.js\"],\n \"env\": {\n \"MCP_REMOTE_URL\": \"https://fc.cloud.chivox.com\"\n }\n }\n }\n}`}\n Claude Desktop 使用本地代理模式(stdio),支持实时录音评测。本地代理会自动桥接远程服务。\n
\n\n \n {`# npm 全局安装后\nclaude mcp add chivox -- env MCP_REMOTE_URL=https://fc.cloud.chivox.com chivox-local-mcp\n\n# 源码构建后\nclaude mcp add chivox -- env MCP_REMOTE_URL=https://fc.cloud.chivox.com node /path/to/cvx_local_mcp/dist/index.js`}\n \n\n \n

除了 Cursor 和 Claude Code,主流的 AI 编程 IDE 都原生支持 MCP。以下客户端使用完全一致的 Streamable HTTP 配置,区别只在配置入口:

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
客户端配置入口备注
Windsurf (Codeium)Settings → Cascade → MCP Servers直接贴下方 JSON
Zed~/.config/zed/settings.json 的 context_serversAssistant Panel 自动发现
Continue (VS Code / JetBrains)config.yaml 的 mcpServersv0.9+ 支持
通义灵码 / CodeGeeX / 文心快码插件设置 → MCP 服务2026 Q1 起陆续支持
Cline (原 Claude Dev)MCP Servers 面板 → 编辑配置VS Code 扩展
\n
\n {`{\n \"mcpServers\": {\n \"chivox-speech-eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://mcp.cloud.chivox.com\"\n }\n }\n}`}\n 所有 IDE 类客户端都走远程 Streamable HTTP,零本地依赖。需要实时录音才需切到 Claude Desktop 的本地代理模式。\n
\n\n \n

扣子(Coze)是字节跳动推出的 AI 应用开发平台,支持通过 MCP 扩展为 Agent 赋予外部工具能力。接入驰声语音评测后,你可以构建口语练习 Bot、发音诊断助手等应用。

\n

方式一:扣子空间 MCP 扩展(推荐)

\n
    \n
  1. 打开 扣子空间(space.coze.cn)
  2. \n
  3. 在对话框下方点击 「添加扩展」
  4. \n
  5. 选择 「自定义」 标签,点击添加新的 MCP 服务
  6. \n
  7. 填入以下配置信息:
  8. \n
\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
名称chivox-speech-eval
传输类型streamable-http
URLhttps://mcp.cloud.chivox.com
\n
\n
    \n
  1. 保存后,在对话中输入 「帮我评测这段英文发音」 即可触发 Agent 调用
  2. \n
\n 添加 MCP 扩展后,扣子空间的 Agent 会自动识别并调用评测工具。你可以在 Agent 的思考过程中看到具体的工具调用细节。\n\n

方式二:在 Coze 开发平台的 Bot 中使用

\n
    \n
  1. 进入 Coze 开发平台,创建或编辑 Bot
  2. \n
  3. 在 Bot 的 「插件」 或 「工具」 面板中,添加 MCP 工具
  4. \n
  5. 选择 Streamable HTTP 类型,填入 URL:https://mcp.cloud.chivox.com
  6. \n
  7. Bot 将自动发现所有可用的评测工具(如 evaluate_english_word 等)
  8. \n
  9. 在 Bot 的人设提示词中,添加语音评测相关的引导语
  10. \n
\n {`你是一位专业的英语口语教练。当用户上传音频并请求评测时:\n1. 使用 evaluate_english_word / evaluate_english_sentence 等工具进行评测\n2. 根据评测结果(overall、accuracy、fluency 等分数)给出专业分析\n3. 针对得分较低的维度提供具体改进建议\n4. 鼓励用户持续练习`}\n
\n\n \n

如果你需要在 Coze 工作流中集成语音评测能力,可以通过 HTTP Request 节点调用评测 API:

\n\n

步骤 1:上传音频

\n

在工作流中添加一个 HTTP Request 节点,配置如下:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
配置项值
方法POST
URLhttps://your-audio-host.com/upload
Content-Typeaudio/mp3
Body音频文件二进制数据
\n
\n

响应中获取 {'{{audioId}}'},传递给下一步。

\n\n

步骤 2:调用评测

\n

添加第二个 HTTP Request 节点,通过 MCP 接口调用评测工具:

\n {`{\n \"jsonrpc\": \"2.0\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"evaluate_english_sentence\",\n \"arguments\": {\n \"audioId\": \"{{audioId}}\",\n \"sentence\": \"{{ref_text}}\"\n }\n },\n \"id\": 1\n}`}\n\n

步骤 3:处理结果

\n

评测结果通过 JSON 格式返回,可使用 Coze 的 代码节点 或 LLM 节点 对结果进行解析和二次处理(如生成学习建议、计算进步趋势等)。

\n\n 工作流方式适合需要固定流程的场景(如批量评测、定时任务、与其他系统联动)。如果是交互式场景,推荐使用上方的 MCP 扩展方式,Agent 会自动选择合适的工具。\n\n
\n

完整工作流示意

\n
\n 用户输入音频\n →\n HTTP: 上传音频\n →\n HTTP: 调用评测\n →\n LLM: 分析结果\n →\n 输出反馈\n
\n
\n
\n\n \n

这一类是面向「上班族」的企业 / 日常 AI 助手,产品形态是个聊天框 + 插件市场 / 扩展面板。接入后,员工在 App 里打字「帮我评一下这段录音」就能自动触发驰声评测,不用写任何代码。

\n\n
\n
\n

豆包(Doubao)App / 桌面版

\n

字节跳动官方 AI 助手,2026 年起桌面版支持 MCP 扩展。

\n
    \n
  1. 桌面版设置 → 「智能体扩展」 → 添加 MCP 服务
  2. \n
  3. 类型选 streamable-http,URL 填 https://mcp.cloud.chivox.com
  4. \n
  5. 对话中直接说「帮我评测」即可自动调用
  6. \n
\n
\n\n
\n

飞书智能伙伴(My AI)

\n

飞书企业 AI,支持以 MCP / Function Calling 挂载外部工具给团队 Bot。

\n
    \n
  1. 飞书开发者后台 → 创建应用 → 「AI 能力 / 智能伙伴」
  2. \n
  3. 在「工具」中选 外部 MCP 服务,填入上方 URL
  4. \n
  5. 把智能伙伴拉进群聊,@ 它提交音频即可评测
  6. \n
\n
\n\n
\n

WorkBuddy / 企业智能助手

\n

字节 WorkBuddy、腾讯会议 AI、企业微信智能助手等企业 AI 工作台场景。

\n
    \n
  1. 在工作台的「技能 / 扩展」后台新增一个 MCP 连接器
  2. \n
  3. 传输协议选 Streamable HTTP,地址填 https://mcp.cloud.chivox.com
  4. \n
  5. 把技能发布到指定部门 / 群组,HR、培训、销售口语陪练场景即可直接用
  6. \n
\n
\n\n
\n

钉钉 AI 助理 / 通义千问 App

\n

阿里生态:钉钉 AI 助理支持自定义插件,通义 App 可通过「AI 工具箱」挂载 MCP。

\n
    \n
  1. 钉钉开发者后台 → AI 助理 → 「插件开发 / MCP 接入」
  2. \n
  3. 选 HTTP Streamable,填入驰声 MCP URL 并开启鉴权(可选)
  4. \n
  5. 在钉钉群 @AI 助理上传音频,自动返回评测卡片
  6. \n
\n
\n
\n\n 典型场景 · 小龙虾们的共同剧本:销售口语陪练 → 外语培训 → 主持 / 播音岗位考核 → K12 英语作业批改 → 客服话术复盘。这些「上班族 AI 工作台」接入驰声 MCP 后,员工 / 学员只要对着话筒说话,AI 就能自动打分并给出个性化改进建议,运营 / 培训 / 教研团队零开发即可上线。\n
\n\n \n

如果你需要把语音评测编排进多步业务流(例如:学员录音 → 评测 → 生成错题集 → 推送到 CRM),可视化工作流平台比聊天 Bot 更合适。

\n\n
\n
\n

Dify

\n

开源 LLMOps,v0.15+ 原生 MCP 工具。

\n
    \n
  • 「工具」→「自定义 MCP」→ 填 URL
  • \n
  • 在 Chatflow / Workflow 节点里直接拖用
  • \n
\n
\n
\n

n8n

\n

工作流自动化,用 MCP Client 节点。

\n
    \n
  • 添加 MCP Client 节点
  • \n
  • Transport 选 HTTP Stream,URL 贴驰声地址
  • \n
  • Tool 下拉自动列出 16 个评测能力
  • \n
\n
\n
\n

Flowise / LangFlow

\n

可视化 LangChain Agent 编排。

\n
    \n
  • 拖出 MCP Tool 节点
  • \n
  • 连到 AgentExecutor 即可
  • \n
\n
\n
\n\n 可视化平台的好处是流程可追溯、可回放,适合教育机构 / 培训部门做批量评测 + 报表导出;缺点是单步延迟略高于直接 MCP 调用,对延迟敏感的交互场景建议用 Cursor / Claude Desktop 直连。\n
\n\n \n

任何遵循 MCP 协议的客户端都可以接入,统一使用以下配置:

\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
传输类型streamable-http
URLhttps://mcp.cloud.chivox.com
鉴权(可选)Header:Authorization: Bearer <MCP_API_KEY>
\n
\n

还没找到你用的客户端?任何支持 Model Context Protocol 的终端都通用。找不到入口?下一小节「编程用 MCP」里用 SDK 直接接即可。

\n
\n
\n\n {/* ══════ 接入 · 编程用 MCP ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 你在写一段真正的后端服务:一个 Agent Worker、一个 API、一个自动化脚本
  • \n
  • 业务里的「语音评测」是其中一个步骤,需要由代码 决定何时调用、如何解析结果
  • \n
  • 四种主流写法:① 官方 MCP 客户端库 → ② Agent 框架自动桥接 → ③ 直调 chat.completions + tools → ④ 把 MCP Client 嵌进业务后端
  • \n
  • 如果客户端环境不能引入 MCP SDK(原生 App / 小程序 / 老系统),请跳转下一大节 「接入 · 非 MCP 原生 REST(cvx_fc)」
  • \n
\n

💡 强烈推荐①或②:驰声有 16 个评测工具,让 MCP 自动注入 tool schema,每新增一个题型不用改一行业务代码。

\n
\n\n \n

最底层、也最推荐的方式。由 Anthropic 官方维护,一次连接自动拿到全部工具的 JSON Schema,然后交给任意 LLM。

\n\n

Python:mcp

\n {`# pip install mcp openai\nimport asyncio, os\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nMCP_URL = \"https://mcp.cloud.chivox.com\"\nllm = OpenAI(api_key=os.getenv(\"DOUBAO_KEY\"),\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\") # 豆包 / DeepSeek / OpenAI 同构\n\nasync def main(audio_id: str, ref: str):\n async with streamablehttp_client(MCP_URL) as (reader, writer, _):\n async with ClientSession(reader, writer) as sess:\n await sess.initialize()\n\n tools = await sess.list_tools()\n openai_tools = [{\n \"type\": \"function\",\n \"function\": {\"name\": t.name, \"description\": t.description,\n \"parameters\": t.inputSchema},\n } for t in tools.tools]\n\n resp = llm.chat.completions.create(\n model=\"doubao-1-5-pro-32k\",\n messages=[{\"role\": \"user\",\n \"content\": f\"帮我评测 audioId={audio_id},参考文本:{ref}\"}],\n tools=openai_tools,\n )\n\n for call in resp.choices[0].message.tool_calls or []:\n result = await sess.call_tool(call.function.name,\n arguments=eval(call.function.arguments))\n print(call.function.name, \"→\", result.content[0].text[:200])\n\nasyncio.run(main(\"abc123\", \"I think therefore I am\"))`}\n\n

TypeScript / Node.js:@modelcontextprotocol/sdk

\n {`// npm i @modelcontextprotocol/sdk openai\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport OpenAI from \"openai\";\n\nconst mcp = new Client({ name: \"chivox-biz\", version: \"1.0.0\" });\nawait mcp.connect(new StreamableHTTPClientTransport(new URL(\"https://mcp.cloud.chivox.com\")));\n\nconst { tools } = await mcp.listTools();\nconst openai = new OpenAI({ apiKey: process.env.DEEPSEEK_KEY, baseURL: \"https://api.deepseek.com/v1\" });\n\nconst resp = await openai.chat.completions.create({\n model: \"deepseek-chat\",\n messages: [{ role: \"user\", content: \"评测 audioId=abc123, 参考 I think therefore I am\" }],\n tools: tools.map(t => ({ type: \"function\", function: {\n name: t.name, description: t.description, parameters: t.inputSchema\n }})),\n});\n\nfor (const call of resp.choices[0].message.tool_calls ?? []) {\n const r = await mcp.callTool({ name: call.function.name,\n arguments: JSON.parse(call.function.arguments) });\n console.log(call.function.name, r.content);\n}`}\n 这种写法 LLM 供应商可换(豆包 / DeepSeek / GPT / Qwen / Moonshot),工具自动更新(驰声新增题型无需改业务代码),适合生产后端。\n
\n\n \n

如果项目已经在用 Agent 框架,几行 adapter 就能把驰声 MCP 塞进去,框架本身会接管 tool-calling 循环、重试、日志。

\n\n
\n
\n

LangChain / LangGraph(Python)

\n {`# pip install langchain-mcp-adapters langgraph\nfrom langchain_mcp_adapters.client import MultiServerMCPClient\nfrom langgraph.prebuilt import create_react_agent\n\nclient = MultiServerMCPClient({\n \"chivox\": {\n \"transport\": \"streamable_http\",\n \"url\": \"https://mcp.cloud.chivox.com\",\n }\n})\ntools = await client.get_tools()\n\nagent = create_react_agent(\"openai:gpt-4o-mini\", tools)\nresult = await agent.ainvoke({\"messages\":\n [(\"user\", \"评测 audioId=abc123 参考 think\")]})\nprint(result[\"messages\"][-1].content)`}\n
\n\n
\n

Mastra(TypeScript)

\n {`// npm i @mastra/core @mastra/mcp\nimport { MCPClient } from \"@mastra/mcp\";\nimport { Agent } from \"@mastra/core/agent\";\nimport { openai } from \"@ai-sdk/openai\";\n\nconst mcp = new MCPClient({ servers: {\n chivox: { url: new URL(\"https://mcp.cloud.chivox.com\") }\n}});\n\nexport const speechCoach = new Agent({\n name: \"speech-coach\",\n instructions: \"你是口语教练,用 chivox 工具评测并给改进建议。\",\n model: openai(\"gpt-4o-mini\"),\n tools: await mcp.getTools(),\n});`}\n
\n\n
\n

OpenAI Agents SDK(Python)

\n {`# pip install openai-agents\nfrom agents import Agent, Runner\nfrom agents.mcp import MCPServerStreamableHttp\n\nchivox = MCPServerStreamableHttp(\n params={\"url\": \"https://mcp.cloud.chivox.com\"},\n name=\"chivox-speech-eval\",\n)\n\nasync with chivox:\n agent = Agent(name=\"coach\",\n instructions=\"专业口语教练\",\n mcp_servers=[chivox])\n r = await Runner.run(agent, \"评测 audioId=abc123\")\n print(r.final_output)`}\n
\n\n
\n

LlamaIndex / AutoGen / CrewAI

\n

这些框架都有官方或社区 MCP adapter,用法与上述类似:

\n
    \n
  • LlamaIndex:llama-index-tools-mcp
  • \n
  • AutoGen:autogen-ext[mcp]
  • \n
  • CrewAI:crewai-tools 的 MCPServerAdapter
  • \n
  • Spring AI(Java):spring-ai-mcp-client
  • \n
\n
\n
\n
\n\n \n

\n DeepSeek、GLM(智谱)、KIMI(Moonshot)、豆包(火山方舟)、千帆、DashScope 等若提供 OpenAI 兼容的 HTTP API,接入驰声 MCP 的套路一致:用 MCP 客户端拉取工具列表 → 转为{' '}\n tools → 模型决策 tool_calls → MCP 执行并回填 → 再让模型生成诊断话术。\n

\n
\n
\n ① MCP list_tools()\n →\n ② 转 OpenAI tools 格式\n →\n ③ LLM 决策 tool_calls\n →\n ④ MCP call_tool()\n →\n ⑤ 评测结果回填 → LLM 诊断\n
\n
\n 各厂商仅需替换 base_url 与 api_key,驰声 MCP 与 tools 桥接代码可原样复用。\n\n

先上传音频,拿到 audioId

\n

文件评测工具通常需要 audioId(或路径参数,视工具而定)。下面是用 HTTP 上传的最小示例:

\n {`import requests\n\nwith open('audio.mp3', 'rb') as f:\n r = requests.post(\n 'https://your-audio-host.com/upload',\n data=f,\n headers={'Content-Type': 'audio/mp3'}\n )\n\nresult = r.json()\nprint(f\"audioId: {result['audioId']}\")\nprint(f\"size: {result['size']} bytes\")\nprint(f\"expires: {result['expiresIn']}\")`}\n {`const fs = require('fs');\n\nconst audioData = fs.readFileSync('audio.mp3');\n\nconst res = await fetch('https://your-audio-host.com/upload', {\n method: 'POST',\n headers: { 'Content-Type': 'audio/mp3' },\n body: audioData,\n});\n\nconst result = await res.json();\nconsole.log('audioId:', result.audioId);`}\n\n

再以豆包为例:MCP 动态 tools + chat.completions 折返跑

\n

当你用的 LLM SDK 还没有原生 MCP 支持(比如老版本的火山方舟 / 百度千帆 / 通义 DashScope),退化方案是:用 MCP 客户端一次性拉到 tool schema,然后按 OpenAI Function Calling 格式喂给 LLM。

\n {`# 适用:豆包(火山方舟)/ DeepSeek / Qwen / Moonshot / GLM 等 OpenAI 兼容 API\n# 核心思路:MCP 列工具 → 转 OpenAI tools → LLM 决策 → MCP 执行 → 回填\n\nasync with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n\n # ① 用 MCP 拉到的 schema 自动转 OpenAI 格式\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 喂给豆包\n messages = [{\"role\": \"user\", \"content\": \"评测一下 audioId=abc123\"}]\n resp = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages, tools=oa_tools,\n )\n\n # ③ LLM 回 tool_calls → 折返跑到 MCP 执行\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for c in msg.tool_calls:\n result = await mcp.call_tool(\n c.function.name, arguments=json.loads(c.function.arguments))\n messages.append({\"role\": \"tool\", \"tool_call_id\": c.id,\n \"content\": result.content[0].text})\n # ④ 再喂一轮,让豆包根据评测结果产出自然语言诊断\n final = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages)\n print(final.choices[0].message.content)`}\n 千万别手写 tool schema!驰声共 16 个评测工具(英文 10 + 中文 6),每个工具参数较多,手写既容易错也难维护。一定用 MCP list_tools() 动态拿。\n
\n\n \n

大部分落地场景其实是:你已有一个业务后端(教育 SaaS / 培训系统 / 客服平台),只需要新增一个「语音评测」能力。推荐架构:

\n\n
\n
\n 前端录音 / 上传\n →\n 业务后端\n →\n MCP Client(常驻连接)\n →\n 驰声 MCP\n ↘\n LLM(诊断 / 出题)\n
\n
\n\n

FastAPI 示例(生产最小骨架)

\n {`from fastapi import FastAPI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\nfrom contextlib import asynccontextmanager\n\nmcp_session: ClientSession | None = None\n\n@asynccontextmanager\nasync def lifespan(app):\n global mcp_session\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as s:\n await s.initialize()\n mcp_session = s\n yield\n mcp_session = None\n\napp = FastAPI(lifespan=lifespan)\n\n@app.post(\"/api/evaluate\")\nasync def evaluate(audio_id: str, ref_text: str):\n # 直接选一个最合适的工具执行(不经 LLM,延迟最低)\n r = await mcp_session.call_tool(\"evaluate_english_sentence\",\n {\"audioId\": audio_id, \"sentence\": ref_text})\n return {\"result\": r.content[0].text}`}\n\n 关键优化:① MCP 连接在 lifespan 里做成长连接,不要每次请求都重连;② 对延迟敏感的场景可以「跳过 LLM 直接调 tool」,把 LLM 放到「生成诊断报告」那一步。\n
\n\n
\n

下面是 ① ~ ④ 中第③种「直调 chat.completions」按主流 LLM 厂商的细化写法

\n

各家 SDK / base_url / 鉴权写法略有差别,挑你当前用的那一家看即可;驰声 MCP 侧代码不用改。

\n
\n\n \n

\n DeepSeek 提供与 OpenAI 完全兼容的 API,当前最新模型为 DeepSeek-V3.2(2025 年 12 月发布,首个把\"思考 + 工具调用\"原生融合的模型)。\n 通过 deepseek-chat 进入非思考模式,\n 通过 deepseek-reasoner 进入思考模式,\n 两种模式均支持 Function Calling,128K 上下文。\n

\n\n

环境准备

\n {`DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# DeepSeek 客户端(OpenAI 兼容)\nclient = OpenAI(\n api_key=os.environ[\"DEEPSEEK_API_KEY\"],\n base_url=\"https://api.deepseek.com/v1\",\n)\n\nasync def evaluate_with_deepseek(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # ① 拉取驰声 MCP 工具列表\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 调用 DeepSeek,让它选择合适的评测工具\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段英文录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"deepseek-chat\", # 或 deepseek-reasoner\n messages=messages,\n tools=oa_tools,\n )\n\n # ③ 执行 tool_calls\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n # ④ 让 DeepSeek 根据评测结果生成自然语言诊断\n final = client.chat.completions.create(\n model=\"deepseek-chat\",\n messages=messages,\n )\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_deepseek(\"audio_abc123\", \"Hello, nice to meet you.\"))`}\n \n 选型建议(V3.2):日常评测诊断用 deepseek-chat,速度快、token 消耗低;\n 需要深度分析(错误归因 / 个性化练习路径)时用 deepseek-reasoner,\n V3.2 起思考模式也能在思维链中调用工具,可以一次性完成\"调评测 → 思考 → 出诊断\",无需再切回 V3 做工具调用。\n \n
\n\n \n

\n 智谱 AI 当前最新旗舰为 GLM-5 / GLM-5.1(2026 年 2 月发布,744B-A40B MoE,200K 上下文,对标 Claude Opus 4.5),\n 以及上一代 GLM-4.7、GLM-4.6。\n 此外保留 glm-4-flash(免费快速版)方便开发测试。\n 全部模型支持 OpenAI 兼容接口与原生 zhipuai SDK,原生 Function Calling。\n

\n\n

环境准备

\n {`ZHIPU_API_KEY=xxxxxxxx.xxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

方式一:OpenAI 兼容接口(推荐)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = OpenAI(\n api_key=os.environ[\"ZHIPU_API_KEY\"],\n base_url=\"https://open.bigmodel.cn/api/paas/v4/\",\n)\n\nasync def evaluate_with_glm(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"glm-4-flash\", # 免费快速版;生产推荐 glm-5 / glm-4.7\n messages=messages,\n tools=oa_tools,\n )\n\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n final = client.chat.completions.create(\n model=\"glm-4-flash\", messages=messages)\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_glm(\"audio_abc123\", \"How are you today?\"))`}\n\n

方式二:官方 zhipuai SDK

\n {`from zhipuai import ZhipuAI\n\nclient = ZhipuAI(api_key=os.environ[\"ZHIPU_API_KEY\"])\n\n# 其余逻辑与方式一相同,仅替换 client 实例\nresp = client.chat.completions.create(\n model=\"glm-5\", # 旗舰;也可用 glm-4.7 / glm-4-flash\n messages=messages,\n tools=oa_tools,\n)`}\n \n 选型建议:\n 开发联调用 glm-4-flash(免费);\n 在线辅导日常诊断用 glm-4.7 性价比最高;\n K12 / 复杂 Agent 编排(多步评测 + 个性化练习路径)用 glm-5 / glm-5.1,\n 200K 上下文、Agent 能力对标 Claude Opus 系列。\n \n
\n\n \n

\n Moonshot AI 当前最新旗舰是 Kimi K2.5(2026 年 1 月 27 日发布,MoE 架构、256K 上下文、原生多模态、Agent 集群协作)。\n 另外提供 kimi-k2-thinking(深度思考)、kimi-k2-turbo-preview(高速版)。\n 上一代 moonshot-v1-8k/32k/128k 仍然兼容,但推荐迁移到 kimi-k2.5。\n 全部模型 OpenAI 兼容,原生 Function Calling。\n

\n\n

环境准备

\n {`MOONSHOT_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# 中国大陆用 api.moonshot.cn;海外/国际版用 api.moonshot.ai\nclient = OpenAI(\n api_key=os.environ[\"MOONSHOT_API_KEY\"],\n base_url=\"https://api.moonshot.cn/v1\",\n)\n\nasync def evaluate_with_kimi(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段英文录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"kimi-k2.5\", # 旗舰;也可选 kimi-k2-turbo-preview / moonshot-v1-128k\n messages=messages,\n tools=oa_tools,\n )\n\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n final = client.chat.completions.create(\n model=\"kimi-k2.5\", messages=messages)\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_kimi(\"audio_abc123\", \"Nice to meet you.\"))`}\n \n Kimi K2.5 原生 256K 上下文 + Agent 集群协作,特别适合「多轮口语练习 + 历史分析 + 多步评测编排」场景:\n 把用户过去 30 次评测的完整 JSON 全部塞进 messages,让 K2.5 一次性生成跨多次练习的进步报告与个性化练习路径。\n 需要更深推理时使用 kimi-k2-thinking,\n 追求实时反馈用 kimi-k2-turbo-preview。\n \n
\n\n \n

\n 字节跳动 豆包 Seed 2.0(2026 年 2 月发布)是 ByteDance Seed 团队推出的新一代通用大模型,覆盖 Pro / Lite / Mini / Code 多种规格,\n 通过 火山方舟(Volcano Ark) 提供 OpenAI 兼容的 /api/v3/chat/completions 接口,\n 原生支持 Function Calling、JSON Schema 结构化输出、深度思考(Chain-of-Thought)模式,\n 接驰声 MCP 几乎无须改动业务代码。\n

\n\n \n 豆包 Seed 2.0 的优势在 深度思考 + 工具编排:让模型一次性规划\"先调 en.sent.score,看完弱项再调 en.word.score 进一步定位音素\",\n 适合做\"多步评测 + 自动纠音\"这类 Agent 场景。\n 默认开启思考模式,可通过 {'thinking: { type: \"disabled\" }'} 关闭以节省时延。\n \n\n

推荐版本

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
model规格推荐用途
doubao-seed-2-0-pro-260215Pro · 旗舰多步评测 + 深度诊断 + 复杂 Agent 编排
doubao-seed-2-0-lite-260215Lite · 平衡在线辅导单轮评测 + 自然语言反馈,性价比首选
doubao-seed-2-0-mini-260215Mini · 极小高并发 / 边缘部署 / 移动端实时反馈
doubao-seed-2-0-code-preview-260215Code · 预览代码生成 / 工具编排 DSL,对评测场景非主推
doubao-seed-1-8-2512281.8 · 深度思考支持 reasoning_effort 调档(minimal/low/medium/high),上一代深度思考强化版仍可用
doubao-seed-1-6-2510151.6 · 经典256K 上下文经典版,已上线项目可继续沿用
\n
\n\n

环境准备

\n {`# 火山方舟控制台 → API Key 管理\nARK_API_KEY=ak-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · 动态 tools + 折返跑)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# 火山方舟 OpenAI 兼容端点\nclient = OpenAI(\n api_key=os.environ[\"ARK_API_KEY\"],\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n)\n\nMODEL = \"doubao-seed-2-0-pro-260215\" # 也可换成 lite / mini\n\nasync def evaluate_with_doubao(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # ① 把驰声 16 个评测工具的 schema 动态注入豆包\n tools = (await mcp.list_tools()).tools\n ark_tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n },\n } for t in tools]\n\n messages = [\n {\"role\": \"system\",\n \"content\": \"你是一位专业的英语口语教练,会主动调用驰声评测工具获取真实分数。\"},\n {\"role\": \"user\",\n \"content\": f\"请评测这段录音,audio_id={audio_id},参考文本:{ref_text}。\"\n f\"先做句子级评测,弱项再追加单词级定位。\"},\n ]\n\n # ② 第一轮 —— 让豆包根据 prompt 自主选工具\n resp = client.chat.completions.create(\n model=MODEL,\n messages=messages,\n tools=ark_tools,\n tool_choice=\"auto\",\n # extra_body={\"thinking\": {\"type\": \"disabled\"}}, # 需要时可关思考\n )\n\n msg = resp.choices[0].message\n messages.append(msg)\n\n # ③ 折返跑:豆包可能一次发起多个 tool_calls,全部回填\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n # ④ 第二轮 —— 让豆包基于真实评测 JSON 输出诊断 / 练习建议\n final = client.chat.completions.create(\n model=MODEL,\n messages=messages,\n )\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_doubao(\n audio_id=\"audio_abc123\",\n ref_text=\"The quick brown fox jumps over the lazy dog.\",\n)))`}\n\n

深度思考模式(可选)

\n

\n 豆包 Seed 2.0 默认开启 thinking 模式,会在内部生成思维链再产出答案,\n 对\"多步评测编排 / 复杂诊断\"质量明显更好;但会增加 30%~80% 的端到端延迟。\n 在 extra_body 里可显式控制:\n

\n {`# 关闭思考(更快、适合实时反馈)\nclient.chat.completions.create(\n model=\"doubao-seed-2-0-lite-260215\",\n messages=messages,\n tools=ark_tools,\n extra_body={\"thinking\": {\"type\": \"disabled\"}},\n)\n\n# 开启思考(默认,适合 Pro 模型 + 多步 Agent)\nclient.chat.completions.create(\n model=\"doubao-seed-2-0-pro-260215\",\n messages=messages,\n tools=ark_tools,\n extra_body={\"thinking\": {\"type\": \"enabled\"}},\n)`}\n\n \n 选型建议:\n 课堂 / 培训类一对一辅导用 doubao-seed-2-0-lite + 关思考;\n K12 / 考试场景需要\"多题型联动 + 升级建议\"时用 doubao-seed-2-0-pro + 开思考;\n 移动端实时口语对话用 doubao-seed-2-0-mini 控制成本与时延。\n \n
\n\n \n

\n OpenAI 当前旗舰为 GPT-5.1(2025-11-13 发布),400K 上下文、128K 最大输出,\n 支持可调推理强度 reasoning_effort(none / low / medium / high)。\n 另有 gpt-5.1-chat-latest(ChatGPT 同款,128K 上下文,对话场景更优)和 gpt-5-mini(性价比版)。\n 全部模型原生支持 Function Calling 与 Structured Outputs。\n

\n\n

环境准备

\n {`OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · GPT-5.1 + 驰声 MCP)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = OpenAI(api_key=os.environ[\"OPENAI_API_KEY\"])\n\nasync def evaluate_with_gpt(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [\n {\"role\": \"system\",\n \"content\": \"你是英语口语教练,必须调用驰声评测工具拿真实分数后再回答。\"},\n {\"role\": \"user\",\n \"content\": f\"请评测:audioId={audio_id},参考文本:{ref_text}\"},\n ]\n\n resp = client.chat.completions.create(\n model=\"gpt-5.1\",\n messages=messages,\n tools=oa_tools,\n tool_choice=\"auto\",\n reasoning_effort=\"medium\", # GPT-5.1 新参数:none / low / medium / high\n )\n\n msg = resp.choices[0].message\n messages.append(msg)\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n final = client.chat.completions.create(\n model=\"gpt-5.1\", messages=messages)\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_gpt(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n \n 选型建议:\n 评测调用 + 诊断默认用 gpt-5.1(reasoning_effort="medium",质量与延迟平衡);\n 纯对话/课堂讲解用 gpt-5.1-chat-latest;\n 高并发批量评测降本用 gpt-5-mini。\n 深度推理 / 多步 Agent 编排把 reasoning_effort 调到 high。\n \n
\n\n \n

\n Anthropic 当前最新为 Claude Opus 4.7(旗舰)、Claude Sonnet 4.6(平衡)、Claude Haiku 4.5(高速)。\n Claude 用 Messages API(与 OpenAI Chat Completions 不同),工具协议是 tool_use / tool_result 块结构。\n 支持文本 + 视觉输入,工具 schema 用 input_schema 字段(与 OpenAI 的 parameters 等价)。\n

\n\n

环境准备

\n {`ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · 原生 Anthropic SDK + MCP 工具桥接)

\n {`# pip install anthropic mcp\nimport os, json, asyncio\nfrom anthropic import Anthropic\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = Anthropic(api_key=os.environ[\"ANTHROPIC_API_KEY\"])\n\nasync def evaluate_with_claude(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # 把驰声 MCP 工具转成 Anthropic 风格(用 input_schema 而非 parameters)\n tools = (await mcp.list_tools()).tools\n anth_tools = [{\n \"name\": t.name,\n \"description\": t.description,\n \"input_schema\": t.inputSchema,\n } for t in tools]\n\n messages = [{\"role\": \"user\",\n \"content\": f\"请评测这段录音 audioId={audio_id},参考文本:{ref_text}\"}]\n\n # 工具循环:Claude 可能多轮 tool_use,需逐轮回填\n while True:\n resp = client.messages.create(\n model=\"claude-opus-4-7\", # 或 claude-sonnet-4-6 / claude-haiku-4-5\n max_tokens=2048,\n tools=anth_tools,\n messages=messages,\n system=\"你是专业英语口语教练,必须调用驰声评测工具获取真实分数。\",\n )\n\n # 把整段助手回复(含 tool_use 块)追加进 messages\n messages.append({\"role\": \"assistant\", \"content\": resp.content})\n\n if resp.stop_reason != \"tool_use\":\n # 没有更多工具调用,输出最终诊断\n return \"\".join(b.text for b in resp.content if b.type == \"text\")\n\n # 提取所有 tool_use 块、并行执行、把 tool_result 回填给 Claude\n tool_results = []\n for block in resp.content:\n if block.type == \"tool_use\":\n result = await mcp.call_tool(block.name, arguments=block.input)\n tool_results.append({\n \"type\": \"tool_result\",\n \"tool_use_id\": block.id,\n \"content\": result.content[0].text,\n })\n messages.append({\"role\": \"user\", \"content\": tool_results})\n\nprint(asyncio.run(evaluate_with_claude(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n \n 选型建议:\n 深度评测诊断 + 复杂 Agent 编排用 claude-opus-4-7(旗舰,编程/Agent 提升明显);\n 日常评测 + 性价比首选 claude-sonnet-4-6;\n 高并发实时反馈用 claude-haiku-4-5。\n Opus 4.5 起新增 effort 参数(low/medium/high),medium 即可达到 Sonnet 4.5 同等质量但 token 减少 ~76%。\n \n
\n\n \n

\n Google 最新 Gemini 3 Flash(gemini-3-flash-preview,2025-12-17)以 Flash 价位提供 Pro 级推理;\n 另有 Gemini 3.1 Pro Preview(旗舰)、Gemini 3.1 Flash-Lite Preview。\n 全部支持 Function Calling、并行调用、组合调用,原生多模态,thinking_level 控制推理深度。\n 推荐用 OpenAI 兼容端点,可直接复用 OpenAI SDK 与已有的 MCP 工具桥接代码。\n

\n\n

环境准备

\n {`GEMINI_API_KEY=AIzaSyxxxxxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

方式一:OpenAI 兼容端点(推荐,零迁移成本)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# Gemini OpenAI 兼容端点 —— 完全复用 OpenAI SDK\nclient = OpenAI(\n api_key=os.environ[\"GEMINI_API_KEY\"],\n base_url=\"https://generativelanguage.googleapis.com/v1beta/openai/\",\n)\n\nasync def evaluate_with_gemini(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\",\n \"content\": f\"请评测:audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"gemini-3-flash-preview\", # 或 gemini-3.1-pro-preview\n messages=messages,\n tools=oa_tools,\n tool_choice=\"auto\",\n )\n msg = resp.choices[0].message\n messages.append(msg)\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n final = client.chat.completions.create(\n model=\"gemini-3-flash-preview\", messages=messages)\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_gemini(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n\n

方式二:原生 google-genai SDK(thinking_level / 流式工具调用)

\n {`# pip install google-genai\nfrom google import genai\nfrom google.genai import types\n\nclient = genai.Client(api_key=os.environ[\"GEMINI_API_KEY\"])\n\n# 把 MCP 工具转成 Gemini function_declarations\nfn_decls = [{\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n} for t in tools]\n\nresp = client.models.generate_content(\n model=\"gemini-3-flash-preview\",\n contents=f\"评测 audioId={audio_id},参考文本:{ref_text}\",\n config=types.GenerateContentConfig(\n tools=[types.Tool(function_declarations=fn_decls)],\n # Gemini 3 起:thinking_level 替代旧的 thinking_budget\n # thinking_level=\"high\",\n ),\n)\n\n# tool_call 在 response.candidates[0].content.parts[0].function_call\nfc = resp.candidates[0].content.parts[0].function_call\nprint(f\"call: {fc.name}({dict(fc.args)}) id={fc.id}\")`}\n \n 选型建议:\n 日常评测用 gemini-3-flash-preview(速度比 2.5 Pro 快 3 倍、价格 ~$0.50/M 输入),已是 Gemini App 默认;\n 复杂多步 Agent / 编程任务用 gemini-3.1-pro-preview;\n 超大上下文 + 多模态批处理用同系列的 gemini-3.1-flash-lite-preview。\n \n \n 注意:Gemini 3 起每次 function_call 自动带 id,多轮工具调用必须把 id 透传回 function_response,否则会被拒绝(OpenAI 兼容端点已自动处理)。\n \n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
模型推荐版本base_urlFunction Calling适合场景
DeepSeek V3.2 · 非思考deepseek-chatapi.deepseek.com/v1✓ 支持评测调用 + 诊断,性价比最高
DeepSeek V3.2 · 思考deepseek-reasonerapi.deepseek.com/v1✓ 支持(思考中可调工具)深度分析 + 错因归因 + 个性化练习路径
GLM-5 · 旗舰glm-5 / glm-5.1open.bigmodel.cn/…/v4✓ 支持200K 长上下文 + Agent 编排,复杂诊断
GLM-4.7glm-4.7open.bigmodel.cn/…/v4✓ 支持在线辅导日常诊断,性价比首选
GLM-4-Flashglm-4-flashopen.bigmodel.cn/…/v4✓ 支持免费额度,开发联调
Kimi K2.5(旗舰)kimi-k2.5api.moonshot.cn/v1✓ 支持256K + 多模态 + Agent 集群协作
Kimi K2 Thinkingkimi-k2-thinkingapi.moonshot.cn/v1✓ 支持多步推理 + 多轮历史进度报告
Kimi K2 Turbokimi-k2-turbo-previewapi.moonshot.cn/v1✓ 支持高速响应版,实时反馈
豆包 Seed 2.0 Prodoubao-seed-2-0-pro-260215ark.cn-beijing.volces.com/api/v3✓ 支持(含深度思考)多步评测编排 + 深度诊断 Agent
豆包 Seed 2.0 Litedoubao-seed-2-0-lite-260215ark.cn-beijing.volces.com/api/v3✓ 支持在线辅导 + 单轮诊断,性价比首选
豆包 Seed 2.0 Minidoubao-seed-2-0-mini-260215ark.cn-beijing.volces.com/api/v3✓ 支持移动端 / 边缘部署 / 低延迟实时反馈
GPT-5.1(旗舰)gpt-5.1api.openai.com/v1✓ 支持(reasoning_effort 可调)400K 上下文 + 深度推理 + 复杂 Agent 编排
GPT-5.1 Chatgpt-5.1-chat-latestapi.openai.com/v1✓ 支持ChatGPT 同款,对话 / 课堂讲解
GPT-5 minigpt-5-miniapi.openai.com/v1✓ 支持高并发 / 批量评测降本
Claude Opus 4.7claude-opus-4-7api.anthropic.com/v1✓ 支持(tool_use 协议)旗舰,编程 / Agent / 深度诊断
Claude Sonnet 4.6claude-sonnet-4-6api.anthropic.com/v1✓ 支持日常评测 + 性价比首选
Claude Haiku 4.5claude-haiku-4-5api.anthropic.com/v1✓ 支持高并发实时反馈
Gemini 3 Flashgemini-3-flash-preview…/v1beta/openai/✓ 支持(并行 / 组合)Pro 级推理 + Flash 价位,Gemini App 默认
Gemini 3.1 Pro Previewgemini-3.1-pro-preview…/v1beta/openai/✓ 支持(thinking_level 可调)复杂多步 Agent + 编程任务
\n
\n \n 除 Claude 用 Anthropic 原生 SDK(anthropic 包,tool_use / tool_result 协议)外,其余所有模型均可通过 OpenAI Python SDK(openai 包)调用,仅需替换 base_url 与 api_key,驰声 MCP 侧代码无需改动。\n \n
\n\n
\n

方案选型速查

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n
场景推荐方案
AI 对话 / Copilot 类产品,LLM 供应商可能会换① 官方 MCP 客户端库
已有 LangChain / Mastra / Agents SDK 技术栈② Agent 框架 + adapter
火山方舟 / 千帆控制台直连,最小侵入③ chat.completions + tools
教育 SaaS / 培训 / 客服等业务后端集成④ 自研后端 Agent
原生 Android / iOS / 小程序 / 不装 MCP SDK 的老系统→ 走下一大节「非 MCP REST」
\n
\n
\n
\n\n {/* ══════ 接入 · 非 MCP 原生 REST(cvx_fc) ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 客户端环境不能 / 不想引入 MCP SDK:原生 Android / iOS / Flutter、微信 / 支付宝小程序、老版本 Java / PHP / Go 后端
  • \n
  • 希望把驰声当作普通 REST + WebSocket调,不经过 JSON-RPC、不走 stdio 代理
  • \n
  • 内部代号 cvx_fc(OpenAI function-calling 风格),与 MCP 模式指向同一个评测引擎,两者为并行入口
  • \n
\n

💡 能走 MCP 的一律优先 MCP;仅当客户端限制无法装 SDK 时走本大节。

\n
\n\n \n

\n 驰声在 MCP 之外提供一套 OpenAI 兼容的 Function Calling 风格 REST API(内部代号 cvx_fc)。它和 MCP 模式指向同一个评测引擎,但协议层走纯 HTTP / WebSocket,不依赖任何 MCP SDK。\n

\n\n \n 与 MCP 模式的关系:MCP 模式(POST /mcp,JSON-RPC 2.0)和 functioncalling 模式(POST /v1/call,REST)是两个并行入口,功能等价、工具/函数列表基本一致。\n \n\n

API 端点

\n
\n \n \n \n \n \n \n \n \n \n \n \n
方法路径说明
GET/v1/functions列出全部可用评测函数(等价 MCP tools/list)
POST/v1/call调用一个评测函数(等价 MCP tools/call)· 同时用于创建流式会话和拉取流式结果
WS{'/ws/eval/{session_id}'}流式评测音频传输
\n
\n\n

认证

\n

所有请求在 HTTP Header 中携带 API Key:

\n {`Authorization: Bearer `}\n

认证失败返回 401(缺少 Authorization)或 403(Key 无效 / 无权使用该评测类型)。结构化错误码见 API 参考 · 错误码。

\n
\n\n \n

\n 调用 GET /v1/functions 拿到当前 API Key 已授权的全部评测函数列表,响应格式与 OpenAI function-calling 的工具清单一致,可以直接喂给大模型作为 tools:\n

\n {`GET /v1/functions\nAuthorization: Bearer `}\n {`{\n \"object\": \"list\",\n \"data\": [\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"en_word_eval\",\n \"description\": \"英文单词发音评测,返回总分和每个音标得分。\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"ref_text\": { \"type\": \"string\", \"description\": \"参考文本\" },\n \"audio_base64\": { \"type\": \"string\", \"description\": \"Base64 编码音频(与 audio_url 二选一)\" },\n \"audio_url\": { \"type\": \"string\", \"description\": \"音频 HTTP(S) URL(与 audio_base64 二选一)\" },\n \"accent\": { \"type\": \"number\", \"description\": \"1=英式 / 2=美式 / 3=不区分(默认)\" },\n \"rank\": { \"type\": \"number\", \"description\": \"评分制:4 或 100(默认)\" }\n },\n \"required\": [\"ref_text\"]\n }\n }\n }\n /* … 其它函数依此类推 … */\n ]\n}`}\n \n 这个端点语义等价于 MCP 的 tools/list,每个 API Key 可见的函数集合由后台权限决定——客户端应以实际返回为准,不要在本地硬编码全量 19 个。\n \n\n

英文评测函数(10 个)

\n
\n \n \n \n \n \n \n \n {[\n ['en_word_eval', 'en.word.score', '单词发音评测'],\n ['en_word_correction', 'en.word.pron', '单词发音纠错'],\n ['en_phonics_eval', 'en.nsp.score', '自然拼读评测'],\n ['en_sentence_eval', 'en.sent.score', '句子朗读评测'],\n ['en_sentence_correction', 'en.sent.pron', '句子发音纠错'],\n ['en_vocab_eval', 'en.vocabs.pron', '词汇批量评测'],\n ['en_paragraph_eval', 'en.pred.score', '段落朗读评测'],\n ['en_realtime_eval', 'en.rltm.score', '实时朗读评测'],\n ['en_choice_eval', 'en.choc.score', '口语选择题'],\n ['en_semi_open_eval', 'en.scne.exam', '半开放题(情景对话等)'],\n ].map(([fn, ct, desc]) => (\n \n \n \n \n \n ))}\n \n
函数名core_type说明
{fn}{ct}{desc}
\n
\n\n

中文评测函数(6 个)

\n
\n \n \n \n \n \n \n \n {[\n ['cn_word_pinyin_eval', 'cn.word.score', '拼音 / 汉字发音评测'],\n ['cn_word_raw_eval', 'cn.word.raw', '汉字发音评测'],\n ['cn_sentence_eval', 'cn.sent.raw', '句子朗读评测'],\n ['cn_paragraph_eval', 'cn.pred.raw', '段落朗读评测'],\n ['cn_rec_eval', 'cn.rec.raw', '有限分支识别'],\n ['cn_aitalk_eval', 'cn.recscore.raw', '口语表达评测(AI Talk)'],\n ].map(([fn, ct, desc]) => (\n \n \n \n \n \n ))}\n \n
函数名core_type说明
{fn}{ct}{desc}
\n
\n\n

流式评测函数(3 个)

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
函数名作用
start_stream_eval创建流式评测会话,返回 session_id / ws_url / resume_token
get_stream_result兜底拉取:WS 没拿到 result 时,通过 HTTP 把最终评分捞回来
stream_eval_result(MCP 模式的别名;cvx_fc 模式统一用 get_stream_result)
\n
\n\n

\n 📘 每个函数的业务语义 / 参数 / 返回字段与 MCP 模式下的同名工具完全一致,可直接参考下文 API 参考 · 英文评测工具 与 中文评测工具。\n

\n
\n\n \n

把完整音频通过 audio_base64 或 audio_url 二选一传给 /v1/call,同步返回评分(与 MCP 模式的 evaluate_english_word 等工具语义等价):

\n {`curl -X POST https://fc.cloud.chivox.com/v1/call \\\\\n -H \"Authorization: Bearer your_api_key\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\n \"name\": \"en_word_eval\",\n \"arguments\": {\n \"ref_text\": \"hello\",\n \"audio_url\": \"https://example.com/hello.mp3\",\n \"accent\": 2,\n \"rank\": 100\n }\n }'`}\n

成功响应:

\n {`{\n \"name\": \"en_word_eval\",\n \"result\": {\n \"overall\": 85.5,\n \"details\": { /* 音素 / 韵律 / 流利度等结构与 MCP 模式完全一致 */ }\n }\n}`}\n

失败响应:

\n {`{\n \"name\": \"en_word_eval\",\n \"error\": { \"message\": \"错误描述\" }\n}`}\n

单次音频 ≤ 50MB,推荐 16 kHz / 单声道 / 16bit。

\n
\n\n \n
\n \n

创建会话:POST /v1/call 调用 start_stream_eval

\n

响应中拿到 session_id / ws_url / resume_token。

\n
\n \n

WebSocket 推送:连接 ws_url,收到 {`{\"type\":\"ready\"}`} 即可开始发二进制音频帧。

\n

边推边收 intermediate 中间结果;结束时发 {`{\"type\":\"stop\"}`},收到 result 即为最终评分。

\n
\n \n

兜底拉取(可选):如 WS 断开未收到最终 result,可再次 POST /v1/call 调用 get_stream_result 兜底。

\n
\n
\n\n

start_stream_eval 参数

\n \n\n

WebSocket 帧协议

\n
\n
\n

客户端 → 服务端

\n
    \n
  • • Binary — 原始音频帧,连上即可直接发送,无需握手
  • \n
  • • {`{\"type\":\"stop\"}`} — 结束录音
  • \n
  • • {`{\"type\":\"ping\"}`} — 心跳
  • \n
\n
\n
\n

服务端 → 客户端

\n
    \n
  • • ready — 连接就绪,可开始发送音频
  • \n
  • • intermediate — 实时中间结果
  • \n
  • • result — 最终评测结果
  • \n
  • • backpressure — 背压,含 suggested_interval_ms,建议降低发送频率
  • \n
  • • error — 错误(含结构化 code + message,见错误码一节)
  • \n
  • • pong — 心跳响应
  • \n
\n
\n
\n
\n\n \n

JavaScript(浏览器 / Node.js)

\n {`// ① 创建会话\nconst resp = await fetch('https://fc.cloud.chivox.com/v1/call', {\n method: 'POST',\n headers: {\n 'Authorization': 'Bearer your_api_key',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n name: 'start_stream_eval',\n arguments: {\n core_type: 'en.sent.score',\n ref_text: 'Hello world',\n audio_type: 'pcm',\n sample_rate: 16000,\n },\n }),\n});\nconst { result } = await resp.json();\n\n// ② WebSocket 推送音频\nconst ws = new WebSocket(result.ws_url);\nws.onmessage = (ev) => {\n const msg = JSON.parse(ev.data);\n switch (msg.type) {\n case 'ready': startRecording(); break;\n case 'intermediate': console.log('部分结果', msg.data); break;\n case 'result': console.log('最终结果', msg.data); ws.close(); break;\n case 'backpressure': console.warn('降速 ~', msg.suggested_interval_ms, 'ms'); break;\n case 'error': console.error(msg.code, msg.message); break;\n }\n};\n\nfunction onAudioChunk(pcm) {\n if (ws.readyState === WebSocket.OPEN) ws.send(pcm); // 直接发二进制\n}\n\nfunction stopRecording() {\n ws.send(JSON.stringify({ type: 'stop' }));\n}`}\n\n

Android(OkHttp · Kotlin)

\n {`val wsUrl = \"ws://your-host:8080/ws/eval/$sessionId\"\nval client = OkHttpClient()\nval req = Request.Builder()\n .url(wsUrl)\n .addHeader(\"Authorization\", \"Bearer \\${apiKey}\")\n .build()\n\nval ws = client.newWebSocket(req, object : WebSocketListener() {\n override fun onMessage(ws: WebSocket, text: String) {\n val msg = JSONObject(text)\n when (msg.getString(\"type\")) {\n \"ready\" -> startRecording()\n \"intermediate\" -> updateUI(msg.getJSONObject(\"data\"))\n \"result\" -> handleFinalResult(msg.getJSONObject(\"data\"))\n \"error\" -> handleError(msg.getString(\"code\"), msg.getString(\"message\"))\n }\n }\n})\n\n// 录音回调中发送 PCM 字节\nfun onAudioData(pcm: ByteArray) {\n ws.send(ByteString.of(*pcm))\n}\n\nfun stop() {\n ws.send(\"\"\"{\"type\":\"stop\"}\"\"\")\n}`}\n iOS / Flutter / 小程序同理,只要平台提供 WebSocket 客户端即可:连接 ws_url、把 PCM bytes 发出去、按 type 字段解析服务端消息就行。\n
\n\n \n

resume_token · 60 秒续播

\n

\n 客户端意外断开时,会话在服务端挂起 60 秒;用创建会话拿到的 resume_token 续播即可:\n

\n {`GET ws://your-host:8080/ws/eval/{session_id}?resume={resume_token}\nAuthorization: Bearer `}\n \n 重连成功后会收到新的 ready,继续推送音频即可;服务端会颁发新的 resume_token,原 token 立即作废。\n \n\n

兜底拉取 · get_stream_result

\n

如果 WS 没能收到最终 result,可主动通过 HTTP 拉取:

\n {`curl -X POST https://fc.cloud.chivox.com/v1/call \\\\\n -H \"Authorization: Bearer your_api_key\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\n \"name\": \"get_stream_result\",\n \"arguments\": {\n \"session_id\": \"stream-1713340800-a1b2c3\",\n \"auto_stop\": true,\n \"timeout\": 30\n }\n }'`}\n \n\n \n functioncalling 模式与 MCP 模式二选一、不要混用:同一个会话不要同时走 MCP 的 /ws/audio/ 和 cvx_fc 的 /ws/eval/,两条链路的会话 ID 空间是分开的。\n \n
\n\n
\n\n {/* ══════ 评测模式 ══════ */}\n \n\n \n

通过本地麦克风实时录音,音频以 WebSocket 流式推送到评测服务,无需生成中间文件。这是最灵活、延迟最低的评测方式,特别适合交互式口语练习场景。

\n 实时录音评测需要安装 SoX 并使用本地代理模式(Claude Desktop / Claude Code)。Cursor 等远程直连模式暂不支持实时录音。\n\n

需要按顺序调用三个工具:

\n\n
\n
\n

create_stream_session — 创建流式评测会话

\n \n

返回 session_id,后续步骤需使用。

\n
\n\n
\n

start_recording — 开始麦克风录音

\n \n

调用后自动启动麦克风,音频通过 WebSocket 实时推送到评测服务。

\n
\n\n
\n

stop_recording — 停止录音并获取结果

\n \n
\n
\n
\n\n \n
\n \n

用户:"请评测我的英文发音,文本是 Hello"

\n

AI 调用 create_stream_session(core_type="en.word.score", ref_text="Hello")

\n

→ 获得 session_id

\n
\n \n

AI 调用 start_recording(session_id=xxx)

\n

麦克风开始录音,音频通过 WebSocket 实时推送到评测服务

\n
\n \n

用户说完后告知 AI "结束"

\n

AI 调用 stop_recording(session_id=xxx)

\n

→ 返回评测结果(总分、准确度、流利度、音素得分等)

\n
\n
\n
\n\n \n

适用于已有音频文件的评测场景,支持三种输入方式:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
参数说明适用场景
audio_file_path本地文件路径代理自动读取并转为 Base64,最便捷
audio_base64Base64 编码数据已有编码数据时使用
audio_url音频文件 URL音频托管在云存储时使用
\n
\n 推荐使用 audio_file_path,只需传入本地文件路径,代理会自动处理编码和上传。\n

支持的音频格式:mp3, wav, ogg, m4a, aac, pcm

\n

限制:单文件最大 50MB,大于 500KB 的文件自动压缩为 16kHz / 单声道 / 32kbps。

\n
\n
\n\n {/* ══════ API 参考 ══════ */}\n \n\n \n \n\n

通用参数:所有英文评测工具均支持以下参数。

\n \n
\n\n \n \n\n

通用参数:

\n \n
\n\n \n

所有评测工具返回统一的结构化结果:

\n {`{\n \"overall\": 85,\n \"accuracy\": 82,\n \"pron\": 88,\n \"fluency\": {\n \"overall\": 78,\n \"speed\": 65,\n \"pause\": 2\n },\n \"integrity\": 95,\n \"details\": [\n {\n \"char\": \"hello\",\n \"score\": 85,\n \"phone\": [\n { \"phoneme\": \"h\", \"score\": 90 },\n { \"phoneme\": \"ɛ\", \"score\": 82 },\n { \"phoneme\": \"l\", \"score\": 88 },\n { \"phoneme\": \"oʊ\", \"score\": 80 }\n ]\n }\n ]\n}`}\n
\n \n \n \n \n \n \n \n {[\n ['overall', '0–100', '综合总分,反映整体语音质量'],\n ['accuracy', '0–100', '准确度,音素级别的发音准确率'],\n ['pron', '0–100', '发音得分,整体发音质量评价'],\n ['fluency.overall', '0–100', '流利度,语流的自然度与平滑度'],\n ['fluency.speed', '0–100', '语速得分,每分钟词/音节计量'],\n ['fluency.pause', 'number', '不自然停顿次数'],\n ['integrity', '0–100', '完整度,是否完整朗读了参考文本'],\n ['details[].phone[]', 'array', '每个音素的独立评分,可定位具体弱项'],\n ['details[].stress[]', 'array', '重音得分,检测重弱读是否正确'],\n ].map(([field, range, desc]) => (\n \n \n \n \n \n ))}\n \n
字段范围说明
{field}{range}{desc}
\n
\n
\n\n \n

常见业务场景

\n
\n \n \n \n \n \n \n \n {[\n ['音频 ID 无效或已过期', '音频上传后 5 分钟内有效,评测完成后自动删除', '重新上传音频'],\n ['服务器繁忙', '当前请求过多,排队已满', '稍后重试,使用指数退避策略'],\n ['存储空间已满', '服务器临时音频存储已满', '稍后重试,系统会自动清理'],\n ['音频格式不支持', '上传了不支持的文件类型', '使用 mp3/wav/ogg/m4a/aac/pcm'],\n ['音频时长超限', '超过该题型最大时长限制', '裁剪音频后重试'],\n ['WebSocket 连接断开', '网络不稳定导致流式连接中断', '代理会自动重连,如持续失败请检查网络'],\n ].map(([scene, reason, fix]) => (\n \n \n \n \n \n ))}\n \n
场景原因解决方式
{scene}{reason}{fix}
\n
\n\n

HTTP 状态码(functioncalling 模式)

\n
\n \n \n \n \n \n \n {[\n ['400', '请求格式错误(JSON 缺字段 / 类型错)'],\n ['401', '未认证(缺少 Authorization 头)'],\n ['403', '权限不足(API Key 无效或无权使用该评测类型)'],\n ['404', '会话不存在(session_id 错误或已回收)'],\n ['409', '会话状态不允许当前操作(如已 stop 后又发音频)'],\n ].map(([code, desc]) => (\n \n \n \n \n ))}\n \n
状态码含义
{code}{desc}
\n
\n\n

流式评测结构化错误码

\n

\n WebSocket 的 error 帧与 get_stream_result 的 HTTP 错误体统一使用以下错误码,便于客户端差错分流:\n

\n
\n \n \n \n \n \n \n \n {[\n ['SESSION_NOT_FOUND', '会话不存在', '重新调用 start_stream_eval / create_stream_session 创建'],\n ['SESSION_EXPIRED', '会话已过期(60s 未续流)', '重新创建会话'],\n ['INVALID_STATE', '当前状态不允许该操作', '检查调用顺序(例如已 stop 后又发音频)'],\n ['INVALID_PARAMS', '参数无效', '核对 core_type / ref_text / 采样率等'],\n ['RESUME_INVALID', 'resume_token 无效或已过期', '重新创建会话(每次重连会颁发新 token)'],\n ['AUDIO_TOO_LARGE', '单次音频超过 50MB', '压缩或切片后重传'],\n ['UPSTREAM_CONNECT', '评测引擎连接失败', '稍后重试;持续发生请联系驰声'],\n ['UPSTREAM_TIMEOUT', '评测超时', '缩短音频 / 检查网络'],\n ['UPSTREAM_EVAL_ERROR', '评测引擎返回错误', '查看 message 字段细节'],\n ['CAPACITY_FULL', '并发会话已满', '退避重试或升级配额'],\n ].map(([code, desc, fix]) => (\n \n \n \n \n \n ))}\n \n
错误码说明建议处理
{code}{desc}{fix}
\n
\n
\n
\n\n {/* ══════ 最佳实践 ══════ */}\n \n\n \n

\n 下面这些模板与{' '}\n 免费体验{' '}\n Demo 中实际使用的「教练 Prompt」一脉相承,全部围绕 角色 / 任务 / 方法 / 输出格式 / 语气 五段式结构,并使用占位符{' '}\n {'{mcp_response}'} 直接拼接 MCP 工具返回的 JSON。\n 推荐在 system 消息里挂载,再把工具返回原文塞进\n user 消息,由 LLM 基于真实分数和音素生成可读诊断 / 练习材料。\n

\n\n \n 使用建议:\n
    \n
  • 把 MCP 工具调用的完整 JSON(含 overall / dp_type / phonemes 等字段)原样塞入 {'{mcp_response}'},不要预先做汇总——细节越完整诊断越具体。
  • \n
  • 「诊断」类模板让 LLM 输出 Markdown 给最终用户阅读;「练习」类模板要求 LLM 输出严格 JSON 给前端渲染。两步分开调用,效果远好于一次性混合。
  • \n
  • 题型决定 prompt:单词题用音素级、句子题加韵律、段落题加 chunk / 整体性,半开放题套四维评级。下面按这 6 类分别给出。
  • \n
\n
\n\n {/* ─── A. 诊断类 · 输出 Markdown 给学习者阅读 ─── */}\n

\n A. 二次诊断 · 输出 Markdown\n

\n
\n
\n

\n 1. 单词级 · 音素诊断\n

\n

\n 适用工具:en.word.score / cn.word.raw。围绕 phonemes[].dp_type 找出错读音。\n

\n {`你是一位专业的英语发音教练。下面是驰声 MCP(en.word.score)返回的单词级评测数据:\n一个目标词、总分与发音分、以及带有 dp_type 的音素数组。\n\n## 任务\n为学习者写一份 **可直接阅读** 的发音诊断,每一条都要引用音素分数(写出 IPA 符号)。\n\n## 方法\n- 按 dp_type 分组:先看 mispron,再补充 normal 但分数 < 70 的\"边缘音\"。\n- 每个问题音素:① 典型母语干扰 → ② 你听到的声音 → ③ 一条具体的发音修正动作(下颌 / 舌位 / 气流 / 唇形)。\n- 重音符号 ˈ 标记的音节,重音错位也要单独列出(即便音素本身分数尚可)。\n- 最多列 4 条,按 **影响力从弱到强** 排序。\n\n## 输出\n精简 Markdown:可选一句总结 → 编号列表 → 单行 **🎯 优先级** 排序。\n\n## 语气\n友善、具体、可执行,不要空喊\"加油\"。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 2. 句子级 · 节奏 + 重音诊断\n

\n

\n 适用工具:en.sent.score。开头先给一行\"计分牌\",再从 phones → words → prosody。\n

\n {`你是一位专业的英语口语教练。下面是驰声 MCP(en.sent.score)返回的句子级数据:refText、总分、发音子分(accuracy / integrity / fluency / rhythm)、可选 speed(WPM),以及 details[] 中的逐词得分、dp_type 与可选 phonemes[]。\n\n## 任务\n开头给一行紧凑的 **计分牌**(总分 + 各子分 + 速度),再按 **音素 → 词 → 韵律** 顺序展开诊断。\n\n## 检查清单(每项都要覆盖;不适用则写\"无明显问题\")\n1. **音素级**:每个 score < 70 或 dp_type ≠ normal 的词,展开 phonemes,命名典型错误(如 /ð/ → /d/)并给一条修正动作。\n2. **漏读 / 多读**:标注 dp_type=omit / insert,解释如何拉低 integrity。\n3. **韵律**:基于 rhythm + 错读词的重音,指出重音错位、陈述句调型平直、断句过多等。\n4. **流利度 vs 准确度**:若 fluency 高但 accuracy 低,明确指出,让学习者知道优先改哪一项。\n\n## 输出格式\nMarkdown 子标题:**Pronunciation / Prosody / Study priority**(最后一行简短排序,按 ROI 从高到低)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 3. 段落级 · 音素族归并 + 完整度\n

\n

\n 适用工具:en.pred.score。把同类错音合并为\"音素族\",避免逐词复述。\n

\n {`你是一位专业的英语口语教练。下面是驰声 MCP(en.pred.score)返回的段落级数据:长 refText、总分、发音子分、可选 speed / integrity,以及大量 details[](同一个词可能在不同子句中重复出现;空 char + dp_type=omit 表示漏读)。\n\n## 任务\n对整段做 **整体诊断**:\n(a) 完整度 / 漏读,\n(b) 反复出现的 **音素族**,\n(c) 节奏与断句,\n(d) 各子分之间是否相互印证。\n\n## 检查清单\n1. **integrity / dp_type**:列出每个 omit / insert,并给出所在子句;解释长读时为什么虚词容易被吞。\n2. **音素聚类**:将弱词按共同音素问题归族(/θ/ 链、/e/ 链、/ɒ/ 等),引用 details 中的实例。\n3. **韵律**:结合 rhythm 与标点 —— 短语内停顿过多?子句边界缺失?\n4. **整体一致性**:若 fluency 正常但 accuracy 差(或反之),点明并指出对练习设计的影响。\n\n## 输出格式\nMarkdown 章节:**Summary / Completeness / Pronunciation (families) / Rhythm / Study priorities**(最后一项最多 4 条,按影响力排序)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 4. 半开放题 · IELTS 风格四维评级\n

\n

\n 适用工具:en.pqan.score。结合学习者 transcript + 四维分数,给出可教学的\"升档建议\"。\n

\n {`你是一位 **IELTS / 课堂口语风格** 的口语教练。下面是驰声 MCP(en.pqan.score)返回的半开放题数据:题目 refText、学习者 transcript、overall、四个维度分(grammar / content / fluency / pron)、speed(WPM)、以及结构化的 issues[] 标记。\n\n## 任务\n给出 **基于 rubric 的诊断**:先用一句话给出 0–100 的整体段位估计,再 **逐维度** 解释,并 **引用 transcript 中的短句**(不要复述全文)。最后给 3–5 条 **可执行的\"升档建议\"**(句型 / 模板,而不是\"多练一点\")。\n\n## 权重(要明确告诉学习者)\n- **Content ~30%** — 想法深度、举例、具体程度\n- **Grammar ~25%** — 句型多样性、主谓一致、从句\n- **Fluency ~25%** — 语速、停顿、口头禅、衔接\n- **Pronunciation ~20%** — 音素 + 可懂度\n\n## 跨维度检查\n- 若 content 最低,先给\"展开模板\",不要先抠音素。\n- 若 fluency 低 + WPM 低,区分\"思考型停顿\"与\"发音卡顿\"。\n- 若 pron 标出特定音,绑定到 transcript 里 **真实出现过的词**。\n\n## 输出格式\nMarkdown:**段位估计** → 紧凑的 **得分表格** → **\"To reach the next band\"** 编号列表(每条给出可仿写的句型)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 5. 中文专项 · 声调 / 儿化 / 变调\n

\n

\n 适用工具:cn.word.raw / cn.sent.raw / cn.pred.raw。中文评测最大权重在 **声调**,必须单独检查。\n

\n {`你是一位专业的普通话口语教练。下面是驰声 MCP(cn.sent.raw)返回的中文句子评测数据:整句分数 + 逐字 details + 可选 phonemes + 流利 / 节奏分。\n\n## 中文评测的权重\n- **声调错误权重最高** —— 声调读错可能直接改变词义\n- dp_type=mispron 多来自:声调错、平翘舌混用、前后鼻音混用\n- 拼音对、声调错,听感仍是\"洋腔洋调\"\n\n## 检查清单(缺则写\"无明显问题\")\n1. **儿化**:phonemes 出现 r(儿化) 或 dp_type 提示时,确认是否被读成\"主音节 + 单独儿\"两拍。\n2. **轻声**:叠词、词缀、句末语气词 —— 第二字应短促轻读,无完整声调曲线。\n3. **变调**:三声连读、不 + 后字、一 + 后字,是否符合普通话规则。\n4. **节奏**:用 rhythm + 逗号位置,标记停顿过长或过碎,建议 chunk 边界。\n\n## 输出\nMarkdown 子标题:**总览 / 儿化 / 轻声 / 变调 / 节奏 / 学习优先级**(最后一项 1–3 条,按\"听感自然度提升\"排序)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n {/* ─── B. 练习类 · 输出 JSON 给前端渲染 ─── */}\n

\n B. 微练习生成 · 输出严格 JSON\n

\n
\n
\n

\n 6. 单词 / 句子 · 微练习\n

\n

\n 建议在 诊断完成后 第二轮调用:让 LLM 严格按弱项音素生成,避免\"通用绕口令包\"。\n

\n {`你仍是这位学习者的发音教练。**第二轮诊断已经完成** —— 现在严格基于诊断里点名的弱音素,生成 **1:1 对应** 的微练习(不要给通用题)。\n\n## 输出(仅返回一段合法 JSON 数组,外层不要任何文字)\n根节点必须是数组,每个元素含 category(字符串)、icon(单个 emoji)、items({ \"label\", \"content\" } 数组)。\n\\`\\`\\`json\n[\n { \"category\": \"Phoneme drills\", \"icon\": \"🎯\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Awareness\", \"icon\": \"🗣️\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Whole word\", \"icon\": \"📝\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] }\n]\n\\`\\`\\`\n\n## 规则\n- **Phoneme drills**:诊断里每个 mispron 音素至少给一对最小对立对 + 一句短绕口令 / 重复句。\n- **Awareness**:当重音偏弱时,给一条 stress / 舌位 / 下颌姿态提示。\n- **Whole word**:2–3 句自然句,目标词分别出现在句首 / 句中 / 句末。\n- 所有 content 必须可念出声;字符串内不要再嵌套 JSON。\n\n## 上下文\n诊断结论:{previous_diagnosis}\n原始 MCP:\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 7. 段落 · Chunk Map + 元认知\n

\n

\n 段落级练习要从\"音素\"上升到\"短语 / 整段 / 元认知录回放\"。直接对应 en.pred.score 的诊断结果。\n

\n {`你仍是这位学习者的口语教练。**段落级二次诊断** 已经列出了漏读位置和音素族 —— 现在请生成 **整段练习**:把弱音素串成\"族\"练习、用 chunk map 把虚词粘回短语,并附一条录音 → 回放 → 对照 MCP details 的元认知步骤。\n\n## 输出(仅返回一段合法 JSON 数组)\n\\`\\`\\`json\n[\n { \"category\": \"Phoneme families\", \"icon\": \"🎯\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Chunking\", \"icon\": \"🎵\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Metacognition\", \"icon\": \"🧠\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] }\n]\n\\`\\`\\`\n\n## 规则\n- **Phoneme families**:至少 3 条,按诊断里的音素族(/θ/、/e/、/ɒ/ 等)组织最小对立对 / 词链。\n- **Chunking**:① 给一行用 [ ] 和 / 标注的 chunk map(可加大致停顿秒数);② 给一句\"把漏掉的虚词嵌入短语\"的练习(不要孤立练)。\n- **Metacognition**:一条\"录音 → 回放 → 对照 MCP details\"的 N 遍练习(N 写明,2–3 之间)。\n- 字符串只能是纯展示文本,禁止嵌套 JSON。\n\n## 上下文\n诊断结论:{previous_diagnosis}\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n {/* ─── C. 跨题 / 运营 ─── */}\n

\n C. 跨题 / 运营\n

\n
\n
\n

\n 8. 多日学习报告\n

\n

\n 把过去 N 天的 MCP 评测结果聚合后丢给 LLM,输出适合发给学生 / 家长的周报。\n

\n {`你是一位英语口语学习顾问。下面是这位学习者过去 7 天的驰声 MCP 评测历史(按时间顺序),每条包含题型、coreType、overall、子分、weak_phonemes 摘要。\n\n## 任务\n为学习者生成一份 **周报**,目标读者:本人 + 家长 / 老师。\n强调 **趋势** 与 **下一步计划**,不要复述每一次具体分数。\n\n## 必须包含\n1. **整体趋势**:进步 / 持平 / 退步(一句话 + 简短依据)\n2. **维度变化**:accuracy / fluency / rhythm / integrity / speed 任意有数据的维度,给出\"本周均分 vs 上周\"\n3. **本周高光**:分数提升最大的题型 / 音素 / 句型\n4. **顽固问题**:连续 3 次以上未达 70 的音素或维度\n5. **下周计划**:3 条具体动作(每条对应一个 MCP 工具或一个练习类型)\n6. **结尾**:1–2 句鼓励性总结,避免空话\n\n## 风格\n- 像一位认真但不啰嗦的私教\n- 出现学生姓名时使用占位 {student_name}\n- 数字一律保留整数\n\n## 评测历史\n\\`\\`\\`json\n{history}\n\\`\\`\\``}\n
\n\n
\n

\n 9. 错误归因 · JSON 摘要\n

\n

\n 用于后端聚合 / 数据看板:让 LLM 把一次评测压缩成结构化摘要,方便入库统计。\n

\n {`你是一个评测结果归类器。下面是驰声 MCP 一次评测的完整返回。请抽取关键信息并 **仅返回合法 JSON**(不要任何解释文字)。\n\n## Schema\n\\`\\`\\`json\n{\n \"core_type\": \"string,例如 en.sent.score\",\n \"overall\": 0,\n \"sub_scores\": { \"accuracy\": 0, \"integrity\": 0, \"fluency\": 0, \"rhythm\": 0 },\n \"weak_phonemes\": [\n { \"ipa\": \"string\", \"avg_score\": 0, \"occur\": 0, \"example_word\": \"string\" }\n ],\n \"omissions\": [{ \"after\": \"string\", \"missing\": \"string\" }],\n \"stress_issues\": [{ \"word\": \"string\", \"expected\": \"string\", \"actual\": \"string\" }],\n \"primary_issue_tag\": \"phoneme|stress|fluency|integrity|content|none\",\n \"next_action_hint\": \"string,10 字以内,例如 \\\"练 /θ/ 对立对\\\"\"\n}\n\\`\\`\\`\n\n## 规则\n- weak_phonemes 只收 avg_score < 70 的项,最多 5 项,按 occur 降序。\n- 不要复述 refText,不要 markdown。\n- 字段缺失时使用 null 或空数组,不要省略 key。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n \n 怎么接到 MCP 工具调用?\n
\n 以「直调 chat.completions + 动态 tools」为例:第一轮 LLM 调出 en.sent.score 工具,把工具 result(即 tool 消息内容)原样填入上面任意「诊断」模板的{' '}\n {'{mcp_response}'},作为第二轮 user 消息发回;拿到诊断结论再走第三轮,套「微练习」模板得到 JSON。三轮调用即可串起 评测 → 诊断 → 练习 全链路。\n
\n
\n\n \n
    \n
  • 音频过期:上传后 5 分钟内有效。建议在上传后 3 分钟内完成评测。
  • \n
  • 服务繁忙:使用指数退避策略重试(1s → 2s → 4s),最多 3 次。
  • \n
  • 录音中断:WebSocket 断线后代理会自动重连。如持续失败,检查网络连接和 SoX 安装。
  • \n
\n
\n\n \n
    \n
  • 优先使用流式评测:实时录音模式跳过了文件上传环节,端到端延迟比文件评测低 30-50%。
  • \n
  • 音频压缩:文件评测时,上传前将音频转为 16kHz 单声道 mp3,可减少 60-80% 的上传体积。
  • \n
  • 选择合适的工具:单词评测比段落评测快 3-5 倍。如只需单词级分数,不要用句子评测。
  • \n
  • 本地文件路径最便捷:使用 audio_file_path 参数传入本地路径,代理自动处理编码,无需手动转 Base64。
  • \n
\n
\n
\n\n {/* ══════ 服务信息 ══════ */}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
端点方法说明
/uploadPOST音频文件上传(MCP 模式文件评测使用)
/mcpPOSTMCP 模式 · JSON-RPC(Streamable HTTP)
{'/ws/audio/{session_id}'}WSMCP 模式 · 流式音频 WebSocket
/v1/functionsGETfunctioncalling 模式 · 列出全部评测函数
/v1/callPOSTfunctioncalling 模式 · 一次性评测 / 创建流式会话 / 拉取流式结果
{'/ws/eval/{session_id}'}WSfunctioncalling 模式 · 流式音频 WebSocket
/healthGET健康检查
\n
\n
\n \n
\n \n \n \n \n \n \n \n {[\n ['存储限制', '500MB', '最大音频存储空间'],\n ['最大排队', '10', '等待处理的请求数'],\n ['最大并发', '3', '同时处理的评测数'],\n ['音频有效期', '5 分钟', '上传后未评测自动过期'],\n ['文件大小限制', '50MB', '单个音频文件最大'],\n ].map(([k, v, d]) => (\n \n ))}\n \n
配置项默认值说明
{k}{v}{d}
\n
\n

\n 上表为托管侧技术默认;计费与试用/商用调用配额、并发档位以{' '}\n \n 会员套餐\n \n 说明为准,与上表独立。\n

\n
\n \n \n 当前线上版本:v1.0.0(网站未正式上线)。以下变更项为开发阶段规划记录,以正式发布公告为准。\n \n
\n {[\n { ver: 'v1.0.0', date: 'TBD', desc: '当前线上版本(网站未正式上线)' },\n ].map(l => (\n
\n {l.ver}\n {l.date}\n {l.desc}\n
\n ))}\n
\n
\n
\n\n \n );\n}\n\nexport default function DocsPage() {\n const locale = useLocale();\n return locale.startsWith('zh') ? : ;\n}\n"}, "bcc3fdfc23e8e34802364c99952e7d8836e9d43e": {"t": 1785765787.197597, "n": 190353, "h": "ecf33defbf4a8dac", "c": "'use client';\n\nimport { useLocale } from 'next-intl';\nimport { Link } from '@/i18n/routing';\nimport { DocsShell, type NavGroup } from './docs-shell';\nimport {\n CodeBlock,\n DocSection,\n SubDoc,\n ParamTable,\n Callout,\n FlowStep,\n ToolTable,\n} from './docs-shared';\nimport { DocsEnglishBody } from './docs-content-en';\nimport {\n BookOpen,\n Code2,\n Zap,\n FileText,\n Terminal,\n Globe,\n Mic,\n MessageSquare,\n BarChart3,\n AlertTriangle,\n Radio,\n FolderOpen,\n Workflow,\n Sparkles,\n Plug,\n Bot,\n Building2,\n Check,\n Sparkle,\n Languages,\n GraduationCap,\n Notebook,\n Gauge,\n ListChecks,\n Network,\n} from 'lucide-react';\n\n/* ─── Navigation Structure ─── */\n\nconst NAV = [\n { id: 'concept', icon: Workflow, label: 'MCP 工作原理', children: [\n { id: 'why-mcp', label: '为什么需要 MCP' },\n { id: 'scenario-walkthrough', label: '场景走查 · 6 步' },\n { id: 'dev-responsibility', label: '开发者只做两件事' },\n { id: 'integration-paths', label: '三种接入姿势' },\n ]},\n { id: 'architecture', icon: Terminal, label: '架构说明', children: [\n { id: 'arch-overview', label: '两种接入模式总览' },\n { id: 'arch-mcp', label: 'MCP 模式架构' },\n { id: 'arch-rest', label: 'functioncalling 模式架构' },\n { id: 'transport', label: '传输协议对比' },\n ]},\n { id: 'quick-start', icon: Zap, label: '快速开始', children: [\n { id: 'overview', label: '概述' },\n { id: 'requirements', label: '系统要求' },\n { id: 'install', label: '安装方式' },\n { id: 'env-vars', label: '环境变量' },\n ]},\n { id: 'config', icon: Plug, label: '接入 · 直接用(零代码)', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: '扣子(Coze)' },\n { id: 'config-coze-workflow', label: 'Coze 工作流' },\n { id: 'config-ai-workspace', label: 'AI 工作台 · 豆包 / 飞书 / WorkBuddy / 钉钉' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: '其他 MCP 客户端' },\n ]},\n { id: 'config-code', icon: Code2, label: '接入 · 编程用 MCP(SDK / 代码)', children: [\n { id: 'code-mcp-sdk', label: '① 官方 MCP 客户端库' },\n { id: 'code-agent-frameworks', label: '② LangChain / Mastra / Agents SDK' },\n { id: 'code-function-calling', label: '③ 直调 chat.completions · 动态 tools' },\n { id: 'code-selfhosted-agent', label: '④ 自研后端 Agent' },\n { id: 'llm-deepseek', label: 'DeepSeek' },\n { id: 'llm-glm', label: 'GLM(智谱)' },\n { id: 'llm-kimi', label: 'KIMI(Moonshot)' },\n { id: 'llm-doubao', label: '豆包 Seed 2.0(火山方舟)' },\n { id: 'llm-openai', label: 'OpenAI(GPT-5.1)' },\n { id: 'llm-claude', label: 'Claude(Anthropic)' },\n { id: 'llm-gemini', label: 'Gemini(Google)' },\n { id: 'llm-comparison', label: '模型对比速查' },\n ]},\n { id: 'config-rest', icon: Network, label: '接入 · 非 MCP 原生 REST(cvx_fc)', children: [\n { id: 'rest-overview', label: 'functioncalling 模式总览' },\n { id: 'rest-catalog', label: '函数目录 · GET /v1/functions' },\n { id: 'rest-oneshot', label: '一次性文件评测' },\n { id: 'rest-streaming', label: '流式评测 · 三步骤' },\n { id: 'rest-examples', label: 'JS / Android 完整示例' },\n { id: 'rest-resume', label: '断线恢复 · 兜底拉取' },\n ]},\n { id: 'eval-modes', icon: Radio, label: '评测模式', children: [\n { id: 'stream-eval', label: '实时录音评测' },\n { id: 'stream-flow', label: '流式评测流程' },\n { id: 'file-eval', label: '音频文件评测' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API 参考', children: [\n { id: 'tools-en', label: '英文评测工具' },\n { id: 'tools-cn', label: '中文评测工具' },\n { id: 'result-fields', label: '评测结果字段' },\n { id: 'error-codes', label: '错误码' },\n ]},\n { id: 'best-practices', icon: FileText, label: '最佳实践', children: [\n { id: 'prompt-templates', label: 'Prompt 模板' },\n { id: 'error-handling', label: '错误处理' },\n { id: 'performance', label: '性能优化' },\n ]},\n { id: 'service-info', icon: Globe, label: '服务信息', children: [\n { id: 'endpoints', label: '服务端点' },\n { id: 'limits', label: '服务限制' },\n { id: 'changelog', label: '更新日志' },\n ]},\n];\n\nconst NAV_EN: NavGroup[] = [\n { id: 'concept', icon: Workflow, label: 'How MCP works', children: [\n { id: 'why-mcp', label: 'Why MCP' },\n { id: 'scenario-walkthrough', label: 'Scenario · 6 steps' },\n { id: 'dev-responsibility', label: 'Two developer tasks' },\n { id: 'integration-paths', label: 'Three integration styles' },\n ]},\n { id: 'architecture', icon: Terminal, label: 'Architecture', children: [\n { id: 'arch-overview', label: 'Two integration modes' },\n { id: 'arch-mcp', label: 'MCP mode architecture' },\n { id: 'arch-rest', label: 'Function-calling architecture' },\n { id: 'transport', label: 'Transport comparison' },\n ]},\n { id: 'quick-start', icon: Zap, label: 'Quick start', children: [\n { id: 'overview', label: 'Overview' },\n { id: 'requirements', label: 'Requirements' },\n { id: 'install', label: 'Install' },\n { id: 'env-vars', label: 'Environment' },\n ]},\n { id: 'config', icon: Plug, label: 'Zero-code clients', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: 'Coze' },\n { id: 'config-coze-workflow', label: 'Coze workflows' },\n { id: 'config-ai-workspace', label: 'Enterprise AI workspaces' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: 'Other MCP clients' },\n ]},\n { id: 'config-code', icon: Code2, label: 'MCP · SDK / code integration', children: [\n { id: 'code-mcp-sdk', label: '① Official MCP SDK' },\n { id: 'code-agent-frameworks', label: '② Agent frameworks' },\n { id: 'code-function-calling', label: '③ chat.completions · dynamic tools' },\n { id: 'code-selfhosted-agent', label: '④ Custom backend agent' },\n { id: 'llm-deepseek', label: 'DeepSeek' },\n { id: 'llm-glm', label: 'GLM (Zhipu)' },\n { id: 'llm-kimi', label: 'KIMI (Moonshot)' },\n { id: 'llm-doubao', label: 'Doubao Seed 2.0 (Volcano Ark)' },\n { id: 'llm-qwen', label: 'Qwen (Alibaba)' },\n { id: 'llm-openai', label: 'OpenAI (GPT-5.1)' },\n { id: 'llm-claude', label: 'Claude (Anthropic)' },\n { id: 'llm-gemini', label: 'Gemini (Google)' },\n { id: 'llm-comparison', label: 'Model comparison' },\n ]},\n { id: 'config-rest', icon: Network, label: 'Non-MCP REST (cvx_fc)', children: [\n { id: 'rest-overview', label: 'Function-calling overview' },\n { id: 'rest-catalog', label: 'Function catalog · GET /v1/functions' },\n { id: 'rest-oneshot', label: 'One-shot file eval' },\n { id: 'rest-streaming', label: 'Streaming · 3 steps' },\n { id: 'rest-examples', label: 'JS / Android samples' },\n { id: 'rest-resume', label: 'Resume & fallback' },\n ]},\n { id: 'eval-modes', icon: Radio, label: 'Evaluation modes', children: [\n { id: 'stream-eval', label: 'Streaming mic' },\n { id: 'stream-flow', label: 'Streaming flow' },\n { id: 'file-eval', label: 'Audio files' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API reference', children: [\n { id: 'tools-en', label: 'English tools' },\n { id: 'tools-cn', label: 'Chinese tools' },\n { id: 'result-fields', label: 'Result fields' },\n { id: 'error-codes', label: 'Errors' },\n ]},\n { id: 'best-practices', icon: FileText, label: 'Best practices', children: [\n { id: 'prompt-templates', label: 'Prompt templates' },\n { id: 'error-handling', label: 'Errors & retries' },\n { id: 'performance', label: 'Performance' },\n ]},\n { id: 'service-info', icon: Globe, label: 'Service info', children: [\n { id: 'endpoints', label: 'Endpoints' },\n { id: 'limits', label: 'Limits' },\n { id: 'changelog', label: 'Changelog' },\n ]},\n];\n\n/* ─── Page(英文 / 中文拆成两个组件,避免切换语言时 Hooks 数量变化导致白屏)─── */\n\nfunction DocsPageEn() {\n return (\n \n \n \n );\n}\n\nfunction DocsPageZh() {\n return (\n \n {/* ══════ MCP 工作原理 ══════ */}\n \n\n \n

\n 大模型(GPT / Claude / Gemini / 通义千问 等)本质上是文字大脑:它擅长读和写,但天生听不到音频、打不开你的数据库、调不通第三方 API。\n

\n

\n MCP(Model Context Protocol)是一套由 Anthropic 主导、业界共同推进的开放协议,它像一根\"对讲机\":让大模型可以在需要时主动去调用外部能力(工具、数据源、服务),然后把结果接回来继续对话。\n

\n
\n
\n
\n \n 没有 MCP 的做法\n
\n
    \n
  • · 研究评测服务的 REST 文档
  • \n
  • · 自己写鉴权 / 上传 / 轮询代码
  • \n
  • · 把结果序列化后塞进 prompt
  • \n
  • · 每换一个大模型都得重写一遍
  • \n
\n
\n
\n
\n \n 用驰声 MCP 之后\n
\n
    \n
  • · 填一行 MCP Server 地址
  • \n
  • · 大模型自动发现&调用评测工具
  • \n
  • · 换任何支持 MCP 的大模型都能用
  • \n
  • · 不写一行调用代码
  • \n
\n
\n
\n \n MCP 让\"接入语音评测\"从一个\"后端工程\"变成了一个\"配置项\"。这也是为什么 Cursor、Claude Desktop、Dify、Coze、字节豆包、飞书智能助手都已经原生支持 MCP。\n \n
\n\n \n

\n 想象一个具体场景:一位开发者用 Claude 做了一款 「AI 雅思口语陪练」小程序,接入驰声语音评测 MCP。当用户发来一段录音,整个链路是这样的:\n

\n
\n \n

配置阶段(开发者 · 一次性)

\n

在 AI 后端的配置文件里填一行驰声 MCP Server 地址。大模型启动时自动发现:「我多了一个叫语音评测的工具」。

\n
\n \n

接收用户指令(终端用户)

\n

小程序用户发来一段自我介绍录音:「帮我听听,发音哪里有问题?」后端把「文字 + 录音链接」打包给大模型。

\n
\n \n

大模型自主思考(LLM · 最核心的魔法)

\n
\n 「用户让我听发音。」
\n 「但我只是文字大脑,我听不到。」
\n 「等等 —— 开发者给了我一个叫 chivox_voice_eval 的 MCP 工具!」\n
\n
\n \n

MCP 协议 · 自动调用(LLM → 驰声)

\n

大模型自动按 MCP 标准构造 tools/call 请求,把录音链接和参考文本发到驰声服务。开发者不需要写任何调用代码。

\n
\n \n

驰声服务处理(评测引擎)

\n

驰声对音频进行考试级打分,把结构化结果通过 MCP 原路返回:overall 85、/θ/ 音发音错误、流利度 88。

\n
\n \n

大模型整合并输出反馈(LLM)

\n

大模型把冷冰冰的分数翻译成温柔反馈:

\n
\n 「你的自我介绍很棒!综合 85 分 🎉 不过 think 这个词的 /θ/ 咬舌音不太标准,我们一起来练一下……」\n
\n
\n
\n \n 整条链路里,MCP 只出现在 ① 和 ④:① 让开发者一次性告诉大模型「你多了一个工具」,④ 让大模型可以自动调用它。这两步的标准化,就是 MCP 的全部价值。\n \n
\n\n \n

听起来复杂,但对开发者来说只需要两件事:

\n
\n
\n
\n 1\n 填一次 MCP 配置\n
\n

\n 在 AI 后端的配置里填入驰声 MCP Server 地址和 API Key,就这一次,以后新加评测能力完全免开发。\n

\n {`{\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://mcp.cloud.chivox.com\",\n \"apiKey\": \"sk-••••••••••\"\n }\n}`}\n
\n
\n
\n 2\n 写一段 System Prompt\n
\n

\n 告诉大模型这个工具是做什么的、什么时候调用、结果怎么转成用户友好的反馈。\n

\n {`你是一位英语口语教练。\n当用户发来录音时:\n1. 调用 chivox_voice_eval 评分\n2. 聚焦 <70 分的音素家族\n3. 用高情商话术给出练习建议`}\n
\n
\n

\n 其余所有事情 —— 音频上传、鉴权、工具发现、调用时机、返回格式、结果整合 —— 都由 MCP 协议和大模型自己搞定。\n

\n
\n\n \n

根据你的技术栈,有三种等价的接入方式,底层都走完全相同的 MCP 协议:

\n\n {/* ── 姿势一:可视化 ── */}\n
\n
\n \n

姿势一 · 可视化拖拽(扣子 / Coze / 飞书智能助手)

\n
\n

\n 适合产品经理、运营、不写后端代码的开发者。整个过程像在手机上装 App。\n

\n
    \n
  1. 找到入口:在扣子平台的 「插件 / 工具」 配置区,点击「添加 MCP 服务」。
  2. \n
  3. 填两个字段(这也是你未来会从驰声这边拿到的):\n
    \n \n \n \n \n \n
    服务器地址https://mcp.cloud.chivox.com
    鉴权密钥sk-•••••••••• (由驰声分配,用于计费与识别)
    \n
    \n
  4. \n
  5. 平台自动发现能力:扣子会访问你填的地址,读取 MCP Server 自描述的\"说明书\"。瞬间明白:「这是个语音评测工具,需要传音频,会返发音分」。
  6. \n
  7. 右侧测试:在平台的聊天框里发一段语音,大模型就会自动调用工具。整个过程不需要写一行代码。
  8. \n
\n
\n\n {/* ── 姿势二:代码框架 ── */}\n
\n
\n \n

姿势二 · 代码框架配置(Dify / LangChain / 自研后端)

\n
\n

\n 适合做独立 APP / 小程序、用 Dify 或 LangChain 写 Agent 的极客开发者。核心就是往配置文件里加一段 JSON。\n

\n
    \n
  1. 打开配置文件(项目根目录下的 mcp.json 或框架指定的配置路径)。
  2. \n
  3. 在 mcpServers 下增加一个节点:\n {`{\n \"mcpServers\": {\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://mcp.cloud.chivox.com\",\n \"env\": {\n \"API_KEY\": \"你的专属密钥\"\n }\n }\n }\n}`}\n
  4. \n
  5. 重启后端服务。大模型的底层调度器会在启动时自动连上驰声 MCP Server,把 16 种评测工具注册成随时待命的 tools。
  6. \n
  7. 触发调用:用户发来录音后,大模型看到 system prompt 的引导,自动选择合适的工具(单词/句子/段落/半开放)调用。
  8. \n
\n
\n\n {/* ── 姿势三:Function Calling 直连(分 A / B 两种做法) ── */}\n
\n
\n \n

姿势三 · 原生 Function Calling(豆包 / DeepSeek / OpenAI 兼容 API)

\n
\n

\n 适合不用任何 Agent 框架、直接调用 LLM API 的后端开发者。豆包 1.5+ / DeepSeek / GPT / Qwen 等模型都走标准 chat.completions 的 tools 参数。这里又分 A / B 两种做法,B 才是生产推荐。\n

\n\n \n 常见疑问:\"要不要手写一个 tool 定义?\"
\n — 姿势一 / 二不用(Coze、Dify、火山方舟控制台、Claude Desktop 会自动从 MCP Server 拉工具列表)。
\n — 姿势三看你选 A 还是 B:A 要手写,B 用 MCP 客户端库自动拉。\n
\n\n {/* ── 3-A:手写 tool schema ── */}\n
\n
\n

3-A · 手写 tool schema(最快验证,不推荐生产)

\n 快速 Demo\n
\n

\n 自己写一段 JSON Schema 告诉豆包\"有个工具叫 xxx,参数长这样\",豆包返回 tool_call 后你再手动去调驰声 MCP。缺点:驰声有 16 个评测工具,你每加一个题型都要改代码。\n

\n {`import os, json\nfrom openai import OpenAI\n\nclient = OpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv('ARK_API_KEY'),\n)\n\n# ─── 手写一段 tool schema(不推荐:16 个工具就要写 16 段)───\ntools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": \"en_word_eval\",\n \"description\": \"英语单词发音评测。当用户让你评价英语发音并提供录音链接时调用。\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"audio_url\": {\"type\": \"string\", \"description\": \"录音 URL\"},\n \"reference_text\": {\"type\": \"string\", \"description\": \"参考文本,如 Apple\"},\n },\n \"required\": [\"audio_url\", \"reference_text\"]\n }\n }\n}]\n\nresp = client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,拿到评测结果后温柔地反馈,不要直接报分数。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n)\n\nmsg = resp.choices[0].message\nif msg.tool_calls:\n args = json.loads(msg.tool_calls[0].function.arguments)\n # ↓↓↓ 这里手动调驰声 MCP,再把结果回填给豆包做第二趟 ↓↓↓\n # result = requests.post(\"https://mcp.cloud.chivox.com\", json={...})`}\n
\n\n {/* ── 3-B:MCP 自动发现 ── */}\n
\n
\n

\n 3-B · 用 MCP 客户端库自动发现 \n

\n 生产推荐\n
\n

\n 启动时连上驰声 MCP Server,调一次 tools/list,把 16 个评测工具自动转成 Function Calling 的 tools 格式。驰声加新工具,你代码不用改。这才是 MCP 协议的真正价值。\n

\n {`import asyncio, os\nfrom openai import AsyncOpenAI\nfrom mcp import ClientSession\nfrom mcp.client.streamable_http import streamablehttp_client\n\nclient = AsyncOpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv(\"ARK_API_KEY\"),\n)\n\nasync def main():\n # ─── 1. 连驰声 MCP Server,自动拉取全部 16 个工具 ───\n async with streamablehttp_client(\n \"https://mcp.cloud.chivox.com\",\n headers={\"Authorization\": f\"Bearer {os.getenv('CHIVOX_KEY')}\"},\n ) as (read, write, _):\n async with ClientSession(read, write) as session:\n await session.initialize()\n mcp_tools = (await session.list_tools()).tools # ← 一行拿到全部工具\n\n # ─── 2. MCP schema → OpenAI Function Calling schema ───\n tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema, # MCP 直接给 JSON Schema\n }\n } for t in mcp_tools]\n\n # ─── 3. 正常调豆包,tools 由 MCP 动态注入 ───\n resp = await client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,收到评测结果后温柔反馈。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n )\n\n # ─── 4. 折返跑:豆包选好工具后,直接走 MCP 调驰声 ───\n msg = resp.choices[0].message\n if msg.tool_calls:\n call = msg.tool_calls[0]\n result = await session.call_tool(\n call.function.name,\n arguments=__import__(\"json\").loads(call.function.arguments),\n )\n # 把 result 回填给豆包做第二趟 chat.completions 即可\n\nasyncio.run(main())`}\n

\n 想要更省心?直接用 官方 mcp python sdk、mcp-use、openai-agents,或火山官方 Arkitect 高代码 SDK,它们都把上面这段\"MCP → Function Calling\"的桥接封装好了。\n

\n
\n
\n\n \n 三种姿势走的是完全相同的 MCP 协议,能力完全等价。选型建议:产品经理 / 原型验证用姿势一(Coze 填表单);AI 客户端用户用姿势二(Cursor / Claude Desktop 填 mcp.json);后端生产服务用姿势三-B(MCP 客户端库自动发现工具,不要手写 tool schema)。\n \n
\n\n
\n\n {/* ══════ 架构说明 ══════ */}\n \n\n \n

驰声语音评测对外提供两条并行入口,底层指向同一个评测引擎,但面向不同的客户端环境,按能力选其一即可:

\n\n
\n
\n

\n \n MCP 模式(推荐首选)\n

\n
    \n
  • • JSON-RPC 2.0 · Streamable HTTP / stdio
  • \n
  • • 所有支持 MCP 的 IDE / 桌面 AI / Agent 框架 零代码即用
  • \n
  • • 工具列表自动注入,新增题型业务侧不用改
  • \n
  • • 本地代理 chivox-local-mcp 支持麦克风实时录音
  • \n
\n

典型客户端:Cursor / Claude Desktop / Coze / Dify / LangChain / 自研后端 Agent

\n
\n
\n

\n \n functioncalling 模式(非 MCP · cvx_fc)\n

\n
    \n
  • • OpenAI function-calling 风格 · 纯 REST + WebSocket
  • \n
  • • 不依赖任何 MCP SDK,普通 HTTP 客户端即可打
  • \n
  • • 内置 resume_token 断线续播、intermediate 中间结果、backpressure 反压
  • \n
  • • 为不能 / 不想引入 MCP 的客户端环境保留兜底通道
  • \n
\n

典型客户端:原生 Android / iOS / Flutter、微信 / 支付宝小程序、老版本 Java / PHP 后端

\n
\n
\n\n

怎么选?

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
你的客户端环境建议
Cursor / Claude Desktop / 各类 AI IDE 能装 MCPMCP 模式
Python / Node / Java 后端能引入 MCP SDKMCP 模式
Coze / Dify / n8n 等可视化平台MCP 模式
原生 Android / iOS App,想直接打 HTTP + WSfunctioncalling 模式
微信 / 支付宝 / 抖音小程序functioncalling 模式
老系统 / 封闭运行时,不想引入 MCP 依赖functioncalling 模式
\n
\n \n 同一个会话二选一、不要混用:MCP 的 /ws/audio/ 和 functioncalling 的 /ws/eval/ 属于不同的会话 ID 空间。\n \n
\n\n \n

MCP 模式下有两种部署形态,底层均走 JSON-RPC 2.0,区别只在客户端离服务端有没有一层本地代理:

\n\n

形态 A · 远程直连(零代码)

\n

适合 Cursor / Coze / Dify / n8n 等支持 Streamable HTTP 的客户端,无本地依赖。

\n
\n
\n

AI 客户端

\n

Cursor / Coze /
Dify / n8n …

\n
\n
\n

⇄

\n

Streamable HTTP
JSON-RPC 2.0

\n
\n
\n

驰声 MCP Server

\n

/mcp · /ws/audio
评测引擎

\n
\n
\n\n

形态 B · 本地代理(支持麦克风实时录音)

\n

适合 Claude Desktop / Claude Code 等以 stdio 挂载 MCP 的客户端,需要本地实时录音时走这条路径。

\n
\n
\n

AI 客户端

\n

Claude Desktop /
Claude Code

\n
\n
\n

⇄

\n

stdio

\n
\n
\n

chivox-local-mcp

\n

本地代理 · SoX 录音

\n
\n
\n

⇄

\n

HTTP / WS

\n
\n
\n

Remote Chivox

\n

MCP Server
评测引擎

\n
\n
\n\n

标准数据流

\n
    \n
  1. initialize → 协商协议版本与能力
  2. \n
  3. tools/list → 拉取 16 个评测工具的 JSON Schema
  4. \n
  5. 文件模式:tools/call → 服务端执行评测 → 返回 JSON-RPC 响应
  6. \n
  7. 实时模式:create_stream_session → 走 /ws/audio/{'{session_id}'} 推流 → stream_eval_result 收结构化评分
  8. \n
\n\n

原始 JSON-RPC 请求示例(自建客户端可直接抄)

\n

\n 如果你不使用官方 MCP SDK 而是直接通过 POST /mcp 自己拼 JSON-RPC 2.0 报文,最小可用的三条请求如下。所有请求均需携带 Authorization: Bearer <your_api_key>。\n

\n\n

① 初始化 · initialize

\n {`{\n \"jsonrpc\": \"2.0\",\n \"id\": 1,\n \"method\": \"initialize\",\n \"params\": {\n \"protocolVersion\": \"2024-11-05\",\n \"capabilities\": {},\n \"clientInfo\": { \"name\": \"my-client\", \"version\": \"1.0.0\" }\n }\n}`}\n

成功后服务端返回协议版本、服务端能力、服务端信息,此后方可调用其他方法。

\n\n

② 拉取工具清单 · tools/list

\n {`{\n \"jsonrpc\": \"2.0\",\n \"id\": 2,\n \"method\": \"tools/list\",\n \"params\": {}\n}`}\n

返回全部 16 个评测工具(英 10 + 中 6)+ 2 个流式工具,含名字、描述、参数 JSON Schema。客户端应缓存此响应,后续按需展示 / 桥接给 LLM。

\n\n

③ 调用工具 · tools/call

\n {`{\n \"jsonrpc\": \"2.0\",\n \"id\": 3,\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"en_word_eval\",\n \"arguments\": {\n \"ref_text\": \"hello\",\n \"audio_base64\": \"\",\n \"accent\": 2,\n \"rank\": 100\n }\n }\n}`}\n

\n 成功响应放在 result.content[0].text(JSON 字符串形式,内部就是评测结果结构);失败则返回 error.code + error.message。\n

\n\n \n 用 Python / TypeScript 官方 MCP SDK 的用户不需要关心以上 JSON-RPC 细节——SDK 已经封装好 session.initialize() / session.list_tools() / session.call_tool()。这里仅供裸协议实现或排障时参考。\n \n
\n\n \n

没有代理、没有 SDK,客户端 ↔ 服务端只有两条链路:一条 REST 管会话 / 文件评测,一条 WebSocket 推音频帧。

\n\n
\n
\n

客户端

\n

原生 App / 小程序 /
老版后端 / 纯前端

\n
\n
\n

⇄

\n

HTTP REST
/v1/call · /v1/functions

\n
\n
\n

cvx_fc 服务

\n

function-calling 网关
评测引擎

\n
\n
\n

⇄

\n

WebSocket
/ws/eval/{id}

\n
\n
\n

客户端推流

\n

麦克风 / 分片缓冲

\n
\n
\n\n

三条典型数据流

\n
\n
\n

a. 一次性文件评测

\n

POST /v1/call(audio_url 或 audio_base64) → 同步返回评分

\n
\n
\n

b. 流式实时评测

\n

POST /v1/call → start_stream_eval → 拿 ws_url → 连 /ws/eval/{id} → 推 PCM → 收 intermediate / backpressure → 发 stop → 收 result

\n
\n
\n

c. 断线恢复 + 兜底拉取

\n

网络断开 60 秒内 → 用 resume_token 重连续播;彻底失败 → POST /v1/call → get_stream_result 兜底

\n
\n
\n\n

特色能力

\n
    \n
  • resume_token — 网络抖动 60 秒内可无缝续播,服务端挂起会话状态
  • \n
  • intermediate 帧 — 边推边吐部分结果,前端可做实时波形 / 分数涂色
  • \n
  • backpressure 反馈 — 服务端主动下发 suggested_interval_ms,客户端按建议降速
  • \n
  • 结构化错误码 — SESSION_EXPIRED / INVALID_STATE / … 便于客户端写重试逻辑
  • \n
\n

详细的接入示例见下文 「接入 · 非 MCP 原生 REST」 大节。

\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
维度MCP 模式functioncalling(cvx_fc)
协议JSON-RPC 2.0REST + WebSocket
入口路径POST /mcpPOST /v1/call
列出工具tools/listGET /v1/functions
调用工具tools/callPOST /v1/call + name
流式音频 WS{'/ws/audio/{session_id}'}{'/ws/eval/{session_id}'}
本地 stdio 代理支持(chivox-local-mcp)不适用
断线重连客户端 SDK 自动重连resume_token(60s 挂起)
中间结果stream_eval 回调intermediate 帧
背压反馈—backpressure 帧
客户端依赖MCP SDK(官方 / 框架)仅 HTTP + WS 客户端
\n
\n
\n
\n\n {/* ══════ 快速开始 ══════ */}\n \n\n \n

chivox-local-mcp 是驰声语音评测的 MCP 本地代理,通过 Model Context Protocol 将远程驰声评测服务桥接到本地,让 AI 助手(Claude Desktop、Claude Code、Cursor 等)直接调用语音评测能力。

\n

它支持两种评测模式,覆盖从即时交互到批量处理的全部场景:

\n
\n
\n
\n \n 实时录音评测\n
\n

通过麦克风边录边评,音频以 WebSocket 流式推送,无需生成中间文件,延迟更低、体验更佳。

\n
\n
\n
\n \n 音频文件评测\n
\n

支持本地文件路径、Base64 编码、URL 三种输入,适合已有音频的批量评测场景。

\n
\n
\n 当前支持 16 种评测工具:英文 10 种(单词、句子、段落、纠音、自然拼读、口语选择、半开放题等)+ 中文 6 种(汉字、拼音、词句、段落、有限分支、AI Talk)。\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n
依赖版本说明
Node.js{'>'}= 18运行时必须
SoXany仅实时录音功能需要(处理麦克风音频流)
\n
\n

安装 SoX(仅在使用实时录音时需要):

\n {`# macOS\nbrew install sox\n\n# Ubuntu / Debian\nsudo apt-get install sox`}\n
\n\n \n

方式一:npm 全局安装(推荐)

\n {`npm install -g chivox-local-mcp`}\n\n

方式二:npx 免安装运行

\n {`MCP_REMOTE_URL=https://fc.cloud.chivox.com npx chivox-local-mcp`}\n\n

方式三:从源码构建

\n {`git clone https://git.chivox.com/CLOUD_DEV/cvx_local_mcp.git\ncd cvx_local_mcp\nbash scripts/build.sh`}\n
\n\n \n \n \n
\n\n {/* ══════ 接入 · 直接用(零代码) ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 不用写代码、不用装 SDK,只在客户端的「MCP 配置」或「扩展」里填一段 JSON / URL
  • \n
  • 保存后 LLM 自动发现 16 个评测工具,并在对话 / Agent 中自主调用
  • \n
  • 覆盖 IDE 编程助手、桌面 AI 客户端、企业 AI 工作台、可视化 Bot / 工作流平台四大生态
  • \n
\n
\n\n\n \n
    \n
  1. 打开 Cursor 设置(Cmd + ,)
  2. \n
  3. 左侧选择 MCP(或搜索 "MCP")
  4. \n
  5. 点击 Add new MCP server
  6. \n
  7. 填写配置并保存:
  8. \n
\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://mcp.cloud.chivox.com\"\n}`}\n Cursor 使用远程 Streamable HTTP 模式直连,无需安装本地代理。如需实时录音功能,请使用下方 Claude Desktop 的本地代理配置。\n
\n\n \n

编辑配置文件(macOS:~/Library/Application Support/Claude/claude_desktop_config.json):

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"chivox-local-mcp\",\n \"env\": {\n \"MCP_REMOTE_URL\": \"https://fc.cloud.chivox.com\",\n \"MCP_API_KEY\": \"your-api-key\"\n }\n }\n }\n}`}\n

如果是从源码构建:

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/cvx_local_mcp/dist/index.js\"],\n \"env\": {\n \"MCP_REMOTE_URL\": \"https://fc.cloud.chivox.com\"\n }\n }\n }\n}`}\n Claude Desktop 使用本地代理模式(stdio),支持实时录音评测。本地代理会自动桥接远程服务。\n
\n\n \n {`# npm 全局安装后\nclaude mcp add chivox -- env MCP_REMOTE_URL=https://fc.cloud.chivox.com chivox-local-mcp\n\n# 源码构建后\nclaude mcp add chivox -- env MCP_REMOTE_URL=https://fc.cloud.chivox.com node /path/to/cvx_local_mcp/dist/index.js`}\n \n\n \n

除了 Cursor 和 Claude Code,主流的 AI 编程 IDE 都原生支持 MCP。以下客户端使用完全一致的 Streamable HTTP 配置,区别只在配置入口:

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
客户端配置入口备注
Windsurf (Codeium)Settings → Cascade → MCP Servers直接贴下方 JSON
Zed~/.config/zed/settings.json 的 context_serversAssistant Panel 自动发现
Continue (VS Code / JetBrains)config.yaml 的 mcpServersv0.9+ 支持
通义灵码 / CodeGeeX / 文心快码插件设置 → MCP 服务2026 Q1 起陆续支持
Cline (原 Claude Dev)MCP Servers 面板 → 编辑配置VS Code 扩展
\n
\n {`{\n \"mcpServers\": {\n \"chivox-speech-eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://mcp.cloud.chivox.com\"\n }\n }\n}`}\n 所有 IDE 类客户端都走远程 Streamable HTTP,零本地依赖。需要实时录音才需切到 Claude Desktop 的本地代理模式。\n
\n\n \n

扣子(Coze)是字节跳动推出的 AI 应用开发平台,支持通过 MCP 扩展为 Agent 赋予外部工具能力。接入驰声语音评测后,你可以构建口语练习 Bot、发音诊断助手等应用。

\n

方式一:扣子空间 MCP 扩展(推荐)

\n
    \n
  1. 打开 扣子空间(space.coze.cn)
  2. \n
  3. 在对话框下方点击 「添加扩展」
  4. \n
  5. 选择 「自定义」 标签,点击添加新的 MCP 服务
  6. \n
  7. 填入以下配置信息:
  8. \n
\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
名称chivox-speech-eval
传输类型streamable-http
URLhttps://mcp.cloud.chivox.com
\n
\n
    \n
  1. 保存后,在对话中输入 「帮我评测这段英文发音」 即可触发 Agent 调用
  2. \n
\n 添加 MCP 扩展后,扣子空间的 Agent 会自动识别并调用评测工具。你可以在 Agent 的思考过程中看到具体的工具调用细节。\n\n

方式二:在 Coze 开发平台的 Bot 中使用

\n
    \n
  1. 进入 Coze 开发平台,创建或编辑 Bot
  2. \n
  3. 在 Bot 的 「插件」 或 「工具」 面板中,添加 MCP 工具
  4. \n
  5. 选择 Streamable HTTP 类型,填入 URL:https://mcp.cloud.chivox.com
  6. \n
  7. Bot 将自动发现所有可用的评测工具(如 evaluate_english_word 等)
  8. \n
  9. 在 Bot 的人设提示词中,添加语音评测相关的引导语
  10. \n
\n {`你是一位专业的英语口语教练。当用户上传音频并请求评测时:\n1. 使用 evaluate_english_word / evaluate_english_sentence 等工具进行评测\n2. 根据评测结果(overall、accuracy、fluency 等分数)给出专业分析\n3. 针对得分较低的维度提供具体改进建议\n4. 鼓励用户持续练习`}\n
\n\n \n

如果你需要在 Coze 工作流中集成语音评测能力,可以通过 HTTP Request 节点调用评测 API:

\n\n

步骤 1:上传音频

\n

在工作流中添加一个 HTTP Request 节点,配置如下:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
配置项值
方法POST
URLhttps://your-audio-host.com/upload
Content-Typeaudio/mp3
Body音频文件二进制数据
\n
\n

响应中获取 {'{{audioId}}'},传递给下一步。

\n\n

步骤 2:调用评测

\n

添加第二个 HTTP Request 节点,通过 MCP 接口调用评测工具:

\n {`{\n \"jsonrpc\": \"2.0\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"evaluate_english_sentence\",\n \"arguments\": {\n \"audioId\": \"{{audioId}}\",\n \"sentence\": \"{{ref_text}}\"\n }\n },\n \"id\": 1\n}`}\n\n

步骤 3:处理结果

\n

评测结果通过 JSON 格式返回,可使用 Coze 的 代码节点 或 LLM 节点 对结果进行解析和二次处理(如生成学习建议、计算进步趋势等)。

\n\n 工作流方式适合需要固定流程的场景(如批量评测、定时任务、与其他系统联动)。如果是交互式场景,推荐使用上方的 MCP 扩展方式,Agent 会自动选择合适的工具。\n\n
\n

完整工作流示意

\n
\n 用户输入音频\n →\n HTTP: 上传音频\n →\n HTTP: 调用评测\n →\n LLM: 分析结果\n →\n 输出反馈\n
\n
\n
\n\n \n

这一类是面向「上班族」的企业 / 日常 AI 助手,产品形态是个聊天框 + 插件市场 / 扩展面板。接入后,员工在 App 里打字「帮我评一下这段录音」就能自动触发驰声评测,不用写任何代码。

\n\n
\n
\n

豆包(Doubao)App / 桌面版

\n

字节跳动官方 AI 助手,2026 年起桌面版支持 MCP 扩展。

\n
    \n
  1. 桌面版设置 → 「智能体扩展」 → 添加 MCP 服务
  2. \n
  3. 类型选 streamable-http,URL 填 https://mcp.cloud.chivox.com
  4. \n
  5. 对话中直接说「帮我评测」即可自动调用
  6. \n
\n
\n\n
\n

飞书智能伙伴(My AI)

\n

飞书企业 AI,支持以 MCP / Function Calling 挂载外部工具给团队 Bot。

\n
    \n
  1. 飞书开发者后台 → 创建应用 → 「AI 能力 / 智能伙伴」
  2. \n
  3. 在「工具」中选 外部 MCP 服务,填入上方 URL
  4. \n
  5. 把智能伙伴拉进群聊,@ 它提交音频即可评测
  6. \n
\n
\n\n
\n

WorkBuddy / 企业智能助手

\n

字节 WorkBuddy、腾讯会议 AI、企业微信智能助手等企业 AI 工作台场景。

\n
    \n
  1. 在工作台的「技能 / 扩展」后台新增一个 MCP 连接器
  2. \n
  3. 传输协议选 Streamable HTTP,地址填 https://mcp.cloud.chivox.com
  4. \n
  5. 把技能发布到指定部门 / 群组,HR、培训、销售口语陪练场景即可直接用
  6. \n
\n
\n\n
\n

钉钉 AI 助理 / 通义千问 App

\n

阿里生态:钉钉 AI 助理支持自定义插件,通义 App 可通过「AI 工具箱」挂载 MCP。

\n
    \n
  1. 钉钉开发者后台 → AI 助理 → 「插件开发 / MCP 接入」
  2. \n
  3. 选 HTTP Streamable,填入驰声 MCP URL 并开启鉴权(可选)
  4. \n
  5. 在钉钉群 @AI 助理上传音频,自动返回评测卡片
  6. \n
\n
\n
\n\n 典型场景 · 小龙虾们的共同剧本:销售口语陪练 → 外语培训 → 主持 / 播音岗位考核 → K12 英语作业批改 → 客服话术复盘。这些「上班族 AI 工作台」接入驰声 MCP 后,员工 / 学员只要对着话筒说话,AI 就能自动打分并给出个性化改进建议,运营 / 培训 / 教研团队零开发即可上线。\n
\n\n \n

如果你需要把语音评测编排进多步业务流(例如:学员录音 → 评测 → 生成错题集 → 推送到 CRM),可视化工作流平台比聊天 Bot 更合适。

\n\n
\n
\n

Dify

\n

开源 LLMOps,v0.15+ 原生 MCP 工具。

\n
    \n
  • 「工具」→「自定义 MCP」→ 填 URL
  • \n
  • 在 Chatflow / Workflow 节点里直接拖用
  • \n
\n
\n
\n

n8n

\n

工作流自动化,用 MCP Client 节点。

\n
    \n
  • 添加 MCP Client 节点
  • \n
  • Transport 选 HTTP Stream,URL 贴驰声地址
  • \n
  • Tool 下拉自动列出 16 个评测能力
  • \n
\n
\n
\n

Flowise / LangFlow

\n

可视化 LangChain Agent 编排。

\n
    \n
  • 拖出 MCP Tool 节点
  • \n
  • 连到 AgentExecutor 即可
  • \n
\n
\n
\n\n 可视化平台的好处是流程可追溯、可回放,适合教育机构 / 培训部门做批量评测 + 报表导出;缺点是单步延迟略高于直接 MCP 调用,对延迟敏感的交互场景建议用 Cursor / Claude Desktop 直连。\n
\n\n \n

任何遵循 MCP 协议的客户端都可以接入,统一使用以下配置:

\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
传输类型streamable-http
URLhttps://mcp.cloud.chivox.com
鉴权(可选)Header:Authorization: Bearer <MCP_API_KEY>
\n
\n

还没找到你用的客户端?任何支持 Model Context Protocol 的终端都通用。找不到入口?下一小节「编程用 MCP」里用 SDK 直接接即可。

\n
\n
\n\n {/* ══════ 接入 · 编程用 MCP ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 你在写一段真正的后端服务:一个 Agent Worker、一个 API、一个自动化脚本
  • \n
  • 业务里的「语音评测」是其中一个步骤,需要由代码 决定何时调用、如何解析结果
  • \n
  • 四种主流写法:① 官方 MCP 客户端库 → ② Agent 框架自动桥接 → ③ 直调 chat.completions + tools → ④ 把 MCP Client 嵌进业务后端
  • \n
  • 如果客户端环境不能引入 MCP SDK(原生 App / 小程序 / 老系统),请跳转下一大节 「接入 · 非 MCP 原生 REST(cvx_fc)」
  • \n
\n

💡 强烈推荐①或②:驰声有 16 个评测工具,让 MCP 自动注入 tool schema,每新增一个题型不用改一行业务代码。

\n
\n\n \n

最底层、也最推荐的方式。由 Anthropic 官方维护,一次连接自动拿到全部工具的 JSON Schema,然后交给任意 LLM。

\n\n

Python:mcp

\n {`# pip install mcp openai\nimport asyncio, os\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nMCP_URL = \"https://mcp.cloud.chivox.com\"\nllm = OpenAI(api_key=os.getenv(\"DOUBAO_KEY\"),\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\") # 豆包 / DeepSeek / OpenAI 同构\n\nasync def main(audio_id: str, ref: str):\n async with streamablehttp_client(MCP_URL) as (reader, writer, _):\n async with ClientSession(reader, writer) as sess:\n await sess.initialize()\n\n tools = await sess.list_tools()\n openai_tools = [{\n \"type\": \"function\",\n \"function\": {\"name\": t.name, \"description\": t.description,\n \"parameters\": t.inputSchema},\n } for t in tools.tools]\n\n resp = llm.chat.completions.create(\n model=\"doubao-1-5-pro-32k\",\n messages=[{\"role\": \"user\",\n \"content\": f\"帮我评测 audioId={audio_id},参考文本:{ref}\"}],\n tools=openai_tools,\n )\n\n for call in resp.choices[0].message.tool_calls or []:\n result = await sess.call_tool(call.function.name,\n arguments=eval(call.function.arguments))\n print(call.function.name, \"→\", result.content[0].text[:200])\n\nasyncio.run(main(\"abc123\", \"I think therefore I am\"))`}\n\n

TypeScript / Node.js:@modelcontextprotocol/sdk

\n {`// npm i @modelcontextprotocol/sdk openai\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport OpenAI from \"openai\";\n\nconst mcp = new Client({ name: \"chivox-biz\", version: \"1.0.0\" });\nawait mcp.connect(new StreamableHTTPClientTransport(new URL(\"https://mcp.cloud.chivox.com\")));\n\nconst { tools } = await mcp.listTools();\nconst openai = new OpenAI({ apiKey: process.env.DEEPSEEK_KEY, baseURL: \"https://api.deepseek.com/v1\" });\n\nconst resp = await openai.chat.completions.create({\n model: \"deepseek-chat\",\n messages: [{ role: \"user\", content: \"评测 audioId=abc123, 参考 I think therefore I am\" }],\n tools: tools.map(t => ({ type: \"function\", function: {\n name: t.name, description: t.description, parameters: t.inputSchema\n }})),\n});\n\nfor (const call of resp.choices[0].message.tool_calls ?? []) {\n const r = await mcp.callTool({ name: call.function.name,\n arguments: JSON.parse(call.function.arguments) });\n console.log(call.function.name, r.content);\n}`}\n 这种写法 LLM 供应商可换(豆包 / DeepSeek / GPT / Qwen / Moonshot),工具自动更新(驰声新增题型无需改业务代码),适合生产后端。\n
\n\n \n

如果项目已经在用 Agent 框架,几行 adapter 就能把驰声 MCP 塞进去,框架本身会接管 tool-calling 循环、重试、日志。

\n\n
\n
\n

LangChain / LangGraph(Python)

\n {`# pip install langchain-mcp-adapters langgraph\nfrom langchain_mcp_adapters.client import MultiServerMCPClient\nfrom langgraph.prebuilt import create_react_agent\n\nclient = MultiServerMCPClient({\n \"chivox\": {\n \"transport\": \"streamable_http\",\n \"url\": \"https://mcp.cloud.chivox.com\",\n }\n})\ntools = await client.get_tools()\n\nagent = create_react_agent(\"openai:gpt-4o-mini\", tools)\nresult = await agent.ainvoke({\"messages\":\n [(\"user\", \"评测 audioId=abc123 参考 think\")]})\nprint(result[\"messages\"][-1].content)`}\n
\n\n
\n

Mastra(TypeScript)

\n {`// npm i @mastra/core @mastra/mcp\nimport { MCPClient } from \"@mastra/mcp\";\nimport { Agent } from \"@mastra/core/agent\";\nimport { openai } from \"@ai-sdk/openai\";\n\nconst mcp = new MCPClient({ servers: {\n chivox: { url: new URL(\"https://mcp.cloud.chivox.com\") }\n}});\n\nexport const speechCoach = new Agent({\n name: \"speech-coach\",\n instructions: \"你是口语教练,用 chivox 工具评测并给改进建议。\",\n model: openai(\"gpt-4o-mini\"),\n tools: await mcp.getTools(),\n});`}\n
\n\n
\n

OpenAI Agents SDK(Python)

\n {`# pip install openai-agents\nfrom agents import Agent, Runner\nfrom agents.mcp import MCPServerStreamableHttp\n\nchivox = MCPServerStreamableHttp(\n params={\"url\": \"https://mcp.cloud.chivox.com\"},\n name=\"chivox-speech-eval\",\n)\n\nasync with chivox:\n agent = Agent(name=\"coach\",\n instructions=\"专业口语教练\",\n mcp_servers=[chivox])\n r = await Runner.run(agent, \"评测 audioId=abc123\")\n print(r.final_output)`}\n
\n\n
\n

LlamaIndex / AutoGen / CrewAI

\n

这些框架都有官方或社区 MCP adapter,用法与上述类似:

\n
    \n
  • LlamaIndex:llama-index-tools-mcp
  • \n
  • AutoGen:autogen-ext[mcp]
  • \n
  • CrewAI:crewai-tools 的 MCPServerAdapter
  • \n
  • Spring AI(Java):spring-ai-mcp-client
  • \n
\n
\n
\n
\n\n \n

\n DeepSeek、GLM(智谱)、KIMI(Moonshot)、豆包(火山方舟)、千帆、DashScope 等若提供 OpenAI 兼容的 HTTP API,接入驰声 MCP 的套路一致:用 MCP 客户端拉取工具列表 → 转为{' '}\n tools → 模型决策 tool_calls → MCP 执行并回填 → 再让模型生成诊断话术。\n

\n
\n
\n ① MCP list_tools()\n →\n ② 转 OpenAI tools 格式\n →\n ③ LLM 决策 tool_calls\n →\n ④ MCP call_tool()\n →\n ⑤ 评测结果回填 → LLM 诊断\n
\n
\n 各厂商仅需替换 base_url 与 api_key,驰声 MCP 与 tools 桥接代码可原样复用。\n\n

先上传音频,拿到 audioId

\n

文件评测工具通常需要 audioId(或路径参数,视工具而定)。下面是用 HTTP 上传的最小示例:

\n {`import requests\n\nwith open('audio.mp3', 'rb') as f:\n r = requests.post(\n 'https://your-audio-host.com/upload',\n data=f,\n headers={'Content-Type': 'audio/mp3'}\n )\n\nresult = r.json()\nprint(f\"audioId: {result['audioId']}\")\nprint(f\"size: {result['size']} bytes\")\nprint(f\"expires: {result['expiresIn']}\")`}\n {`const fs = require('fs');\n\nconst audioData = fs.readFileSync('audio.mp3');\n\nconst res = await fetch('https://your-audio-host.com/upload', {\n method: 'POST',\n headers: { 'Content-Type': 'audio/mp3' },\n body: audioData,\n});\n\nconst result = await res.json();\nconsole.log('audioId:', result.audioId);`}\n\n

再以豆包为例:MCP 动态 tools + chat.completions 折返跑

\n

当你用的 LLM SDK 还没有原生 MCP 支持(比如老版本的火山方舟 / 百度千帆 / 通义 DashScope),退化方案是:用 MCP 客户端一次性拉到 tool schema,然后按 OpenAI Function Calling 格式喂给 LLM。

\n {`# 适用:豆包(火山方舟)/ DeepSeek / Qwen / Moonshot / GLM 等 OpenAI 兼容 API\n# 核心思路:MCP 列工具 → 转 OpenAI tools → LLM 决策 → MCP 执行 → 回填\n\nasync with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n\n # ① 用 MCP 拉到的 schema 自动转 OpenAI 格式\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 喂给豆包\n messages = [{\"role\": \"user\", \"content\": \"评测一下 audioId=abc123\"}]\n resp = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages, tools=oa_tools,\n )\n\n # ③ LLM 回 tool_calls → 折返跑到 MCP 执行\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for c in msg.tool_calls:\n result = await mcp.call_tool(\n c.function.name, arguments=json.loads(c.function.arguments))\n messages.append({\"role\": \"tool\", \"tool_call_id\": c.id,\n \"content\": result.content[0].text})\n # ④ 再喂一轮,让豆包根据评测结果产出自然语言诊断\n final = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages)\n print(final.choices[0].message.content)`}\n 千万别手写 tool schema!驰声共 16 个评测工具(英文 10 + 中文 6),每个工具参数较多,手写既容易错也难维护。一定用 MCP list_tools() 动态拿。\n
\n\n \n

大部分落地场景其实是:你已有一个业务后端(教育 SaaS / 培训系统 / 客服平台),只需要新增一个「语音评测」能力。推荐架构:

\n\n
\n
\n 前端录音 / 上传\n →\n 业务后端\n →\n MCP Client(常驻连接)\n →\n 驰声 MCP\n ↘\n LLM(诊断 / 出题)\n
\n
\n\n

FastAPI 示例(生产最小骨架)

\n {`from fastapi import FastAPI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\nfrom contextlib import asynccontextmanager\n\nmcp_session: ClientSession | None = None\n\n@asynccontextmanager\nasync def lifespan(app):\n global mcp_session\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as s:\n await s.initialize()\n mcp_session = s\n yield\n mcp_session = None\n\napp = FastAPI(lifespan=lifespan)\n\n@app.post(\"/api/evaluate\")\nasync def evaluate(audio_id: str, ref_text: str):\n # 直接选一个最合适的工具执行(不经 LLM,延迟最低)\n r = await mcp_session.call_tool(\"evaluate_english_sentence\",\n {\"audioId\": audio_id, \"sentence\": ref_text})\n return {\"result\": r.content[0].text}`}\n\n 关键优化:① MCP 连接在 lifespan 里做成长连接,不要每次请求都重连;② 对延迟敏感的场景可以「跳过 LLM 直接调 tool」,把 LLM 放到「生成诊断报告」那一步。\n
\n\n
\n

下面是 ① ~ ④ 中第③种「直调 chat.completions」按主流 LLM 厂商的细化写法

\n

各家 SDK / base_url / 鉴权写法略有差别,挑你当前用的那一家看即可;驰声 MCP 侧代码不用改。

\n
\n\n \n

\n DeepSeek 提供与 OpenAI 完全兼容的 API,当前最新模型为 DeepSeek-V3.2(2025 年 12 月发布,首个把\"思考 + 工具调用\"原生融合的模型)。\n 通过 deepseek-chat 进入非思考模式,\n 通过 deepseek-reasoner 进入思考模式,\n 两种模式均支持 Function Calling,128K 上下文。\n

\n\n

环境准备

\n {`DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# DeepSeek 客户端(OpenAI 兼容)\nclient = OpenAI(\n api_key=os.environ[\"DEEPSEEK_API_KEY\"],\n base_url=\"https://api.deepseek.com/v1\",\n)\n\nasync def evaluate_with_deepseek(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # ① 拉取驰声 MCP 工具列表\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 调用 DeepSeek,让它选择合适的评测工具\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段英文录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"deepseek-chat\", # 或 deepseek-reasoner\n messages=messages,\n tools=oa_tools,\n )\n\n # ③ 执行 tool_calls\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n # ④ 让 DeepSeek 根据评测结果生成自然语言诊断\n final = client.chat.completions.create(\n model=\"deepseek-chat\",\n messages=messages,\n )\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_deepseek(\"audio_abc123\", \"Hello, nice to meet you.\"))`}\n \n 选型建议(V3.2):日常评测诊断用 deepseek-chat,速度快、token 消耗低;\n 需要深度分析(错误归因 / 个性化练习路径)时用 deepseek-reasoner,\n V3.2 起思考模式也能在思维链中调用工具,可以一次性完成\"调评测 → 思考 → 出诊断\",无需再切回 V3 做工具调用。\n \n
\n\n \n

\n 智谱 AI 当前最新旗舰为 GLM-5 / GLM-5.1(2026 年 2 月发布,744B-A40B MoE,200K 上下文,对标 Claude Opus 4.5),\n 以及上一代 GLM-4.7、GLM-4.6。\n 此外保留 glm-4-flash(免费快速版)方便开发测试。\n 全部模型支持 OpenAI 兼容接口与原生 zhipuai SDK,原生 Function Calling。\n

\n\n

环境准备

\n {`ZHIPU_API_KEY=xxxxxxxx.xxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

方式一:OpenAI 兼容接口(推荐)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = OpenAI(\n api_key=os.environ[\"ZHIPU_API_KEY\"],\n base_url=\"https://open.bigmodel.cn/api/paas/v4/\",\n)\n\nasync def evaluate_with_glm(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"glm-4-flash\", # 免费快速版;生产推荐 glm-5 / glm-4.7\n messages=messages,\n tools=oa_tools,\n )\n\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n final = client.chat.completions.create(\n model=\"glm-4-flash\", messages=messages)\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_glm(\"audio_abc123\", \"How are you today?\"))`}\n\n

方式二:官方 zhipuai SDK

\n {`from zhipuai import ZhipuAI\n\nclient = ZhipuAI(api_key=os.environ[\"ZHIPU_API_KEY\"])\n\n# 其余逻辑与方式一相同,仅替换 client 实例\nresp = client.chat.completions.create(\n model=\"glm-5\", # 旗舰;也可用 glm-4.7 / glm-4-flash\n messages=messages,\n tools=oa_tools,\n)`}\n \n 选型建议:\n 开发联调用 glm-4-flash(免费);\n 在线辅导日常诊断用 glm-4.7 性价比最高;\n K12 / 复杂 Agent 编排(多步评测 + 个性化练习路径)用 glm-5 / glm-5.1,\n 200K 上下文、Agent 能力对标 Claude Opus 系列。\n \n
\n\n \n

\n Moonshot AI 当前最新旗舰是 Kimi K2.5(2026 年 1 月 27 日发布,MoE 架构、256K 上下文、原生多模态、Agent 集群协作)。\n 另外提供 kimi-k2-thinking(深度思考)、kimi-k2-turbo-preview(高速版)。\n 上一代 moonshot-v1-8k/32k/128k 仍然兼容,但推荐迁移到 kimi-k2.5。\n 全部模型 OpenAI 兼容,原生 Function Calling。\n

\n\n

环境准备

\n {`MOONSHOT_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# 中国大陆用 api.moonshot.cn;海外/国际版用 api.moonshot.ai\nclient = OpenAI(\n api_key=os.environ[\"MOONSHOT_API_KEY\"],\n base_url=\"https://api.moonshot.cn/v1\",\n)\n\nasync def evaluate_with_kimi(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段英文录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"kimi-k2.5\", # 旗舰;也可选 kimi-k2-turbo-preview / moonshot-v1-128k\n messages=messages,\n tools=oa_tools,\n )\n\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n final = client.chat.completions.create(\n model=\"kimi-k2.5\", messages=messages)\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_kimi(\"audio_abc123\", \"Nice to meet you.\"))`}\n \n Kimi K2.5 原生 256K 上下文 + Agent 集群协作,特别适合「多轮口语练习 + 历史分析 + 多步评测编排」场景:\n 把用户过去 30 次评测的完整 JSON 全部塞进 messages,让 K2.5 一次性生成跨多次练习的进步报告与个性化练习路径。\n 需要更深推理时使用 kimi-k2-thinking,\n 追求实时反馈用 kimi-k2-turbo-preview。\n \n
\n\n \n

\n 字节跳动 豆包 Seed 2.0(2026 年 2 月发布)是 ByteDance Seed 团队推出的新一代通用大模型,覆盖 Pro / Lite / Mini / Code 多种规格,\n 通过 火山方舟(Volcano Ark) 提供 OpenAI 兼容的 /api/v3/chat/completions 接口,\n 原生支持 Function Calling、JSON Schema 结构化输出、深度思考(Chain-of-Thought)模式,\n 接驰声 MCP 几乎无须改动业务代码。\n

\n\n \n 豆包 Seed 2.0 的优势在 深度思考 + 工具编排:让模型一次性规划\"先调 en.sent.score,看完弱项再调 en.word.score 进一步定位音素\",\n 适合做\"多步评测 + 自动纠音\"这类 Agent 场景。\n 默认开启思考模式,可通过 {'thinking: { type: \"disabled\" }'} 关闭以节省时延。\n \n\n

推荐版本

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
model规格推荐用途
doubao-seed-2-0-pro-260215Pro · 旗舰多步评测 + 深度诊断 + 复杂 Agent 编排
doubao-seed-2-0-lite-260215Lite · 平衡在线辅导单轮评测 + 自然语言反馈,性价比首选
doubao-seed-2-0-mini-260215Mini · 极小高并发 / 边缘部署 / 移动端实时反馈
doubao-seed-2-0-code-preview-260215Code · 预览代码生成 / 工具编排 DSL,对评测场景非主推
doubao-seed-1-8-2512281.8 · 深度思考支持 reasoning_effort 调档(minimal/low/medium/high),上一代深度思考强化版仍可用
doubao-seed-1-6-2510151.6 · 经典256K 上下文经典版,已上线项目可继续沿用
\n
\n\n

环境准备

\n {`# 火山方舟控制台 → API Key 管理\nARK_API_KEY=ak-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · 动态 tools + 折返跑)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# 火山方舟 OpenAI 兼容端点\nclient = OpenAI(\n api_key=os.environ[\"ARK_API_KEY\"],\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n)\n\nMODEL = \"doubao-seed-2-0-pro-260215\" # 也可换成 lite / mini\n\nasync def evaluate_with_doubao(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # ① 把驰声 16 个评测工具的 schema 动态注入豆包\n tools = (await mcp.list_tools()).tools\n ark_tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n },\n } for t in tools]\n\n messages = [\n {\"role\": \"system\",\n \"content\": \"你是一位专业的英语口语教练,会主动调用驰声评测工具获取真实分数。\"},\n {\"role\": \"user\",\n \"content\": f\"请评测这段录音,audio_id={audio_id},参考文本:{ref_text}。\"\n f\"先做句子级评测,弱项再追加单词级定位。\"},\n ]\n\n # ② 第一轮 —— 让豆包根据 prompt 自主选工具\n resp = client.chat.completions.create(\n model=MODEL,\n messages=messages,\n tools=ark_tools,\n tool_choice=\"auto\",\n # extra_body={\"thinking\": {\"type\": \"disabled\"}}, # 需要时可关思考\n )\n\n msg = resp.choices[0].message\n messages.append(msg)\n\n # ③ 折返跑:豆包可能一次发起多个 tool_calls,全部回填\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n # ④ 第二轮 —— 让豆包基于真实评测 JSON 输出诊断 / 练习建议\n final = client.chat.completions.create(\n model=MODEL,\n messages=messages,\n )\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_doubao(\n audio_id=\"audio_abc123\",\n ref_text=\"The quick brown fox jumps over the lazy dog.\",\n)))`}\n\n

深度思考模式(可选)

\n

\n 豆包 Seed 2.0 默认开启 thinking 模式,会在内部生成思维链再产出答案,\n 对\"多步评测编排 / 复杂诊断\"质量明显更好;但会增加 30%~80% 的端到端延迟。\n 在 extra_body 里可显式控制:\n

\n {`# 关闭思考(更快、适合实时反馈)\nclient.chat.completions.create(\n model=\"doubao-seed-2-0-lite-260215\",\n messages=messages,\n tools=ark_tools,\n extra_body={\"thinking\": {\"type\": \"disabled\"}},\n)\n\n# 开启思考(默认,适合 Pro 模型 + 多步 Agent)\nclient.chat.completions.create(\n model=\"doubao-seed-2-0-pro-260215\",\n messages=messages,\n tools=ark_tools,\n extra_body={\"thinking\": {\"type\": \"enabled\"}},\n)`}\n\n \n 选型建议:\n 课堂 / 培训类一对一辅导用 doubao-seed-2-0-lite + 关思考;\n K12 / 考试场景需要\"多题型联动 + 升级建议\"时用 doubao-seed-2-0-pro + 开思考;\n 移动端实时口语对话用 doubao-seed-2-0-mini 控制成本与时延。\n \n
\n\n \n

\n OpenAI 当前旗舰为 GPT-5.1(2025-11-13 发布),400K 上下文、128K 最大输出,\n 支持可调推理强度 reasoning_effort(none / low / medium / high)。\n 另有 gpt-5.1-chat-latest(ChatGPT 同款,128K 上下文,对话场景更优)和 gpt-5-mini(性价比版)。\n 全部模型原生支持 Function Calling 与 Structured Outputs。\n

\n\n

环境准备

\n {`OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · GPT-5.1 + 驰声 MCP)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = OpenAI(api_key=os.environ[\"OPENAI_API_KEY\"])\n\nasync def evaluate_with_gpt(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [\n {\"role\": \"system\",\n \"content\": \"你是英语口语教练,必须调用驰声评测工具拿真实分数后再回答。\"},\n {\"role\": \"user\",\n \"content\": f\"请评测:audioId={audio_id},参考文本:{ref_text}\"},\n ]\n\n resp = client.chat.completions.create(\n model=\"gpt-5.1\",\n messages=messages,\n tools=oa_tools,\n tool_choice=\"auto\",\n reasoning_effort=\"medium\", # GPT-5.1 新参数:none / low / medium / high\n )\n\n msg = resp.choices[0].message\n messages.append(msg)\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n final = client.chat.completions.create(\n model=\"gpt-5.1\", messages=messages)\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_gpt(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n \n 选型建议:\n 评测调用 + 诊断默认用 gpt-5.1(reasoning_effort="medium",质量与延迟平衡);\n 纯对话/课堂讲解用 gpt-5.1-chat-latest;\n 高并发批量评测降本用 gpt-5-mini。\n 深度推理 / 多步 Agent 编排把 reasoning_effort 调到 high。\n \n
\n\n \n

\n Anthropic 当前最新为 Claude Opus 4.7(旗舰)、Claude Sonnet 4.6(平衡)、Claude Haiku 4.5(高速)。\n Claude 用 Messages API(与 OpenAI Chat Completions 不同),工具协议是 tool_use / tool_result 块结构。\n 支持文本 + 视觉输入,工具 schema 用 input_schema 字段(与 OpenAI 的 parameters 等价)。\n

\n\n

环境准备

\n {`ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · 原生 Anthropic SDK + MCP 工具桥接)

\n {`# pip install anthropic mcp\nimport os, json, asyncio\nfrom anthropic import Anthropic\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = Anthropic(api_key=os.environ[\"ANTHROPIC_API_KEY\"])\n\nasync def evaluate_with_claude(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # 把驰声 MCP 工具转成 Anthropic 风格(用 input_schema 而非 parameters)\n tools = (await mcp.list_tools()).tools\n anth_tools = [{\n \"name\": t.name,\n \"description\": t.description,\n \"input_schema\": t.inputSchema,\n } for t in tools]\n\n messages = [{\"role\": \"user\",\n \"content\": f\"请评测这段录音 audioId={audio_id},参考文本:{ref_text}\"}]\n\n # 工具循环:Claude 可能多轮 tool_use,需逐轮回填\n while True:\n resp = client.messages.create(\n model=\"claude-opus-4-7\", # 或 claude-sonnet-4-6 / claude-haiku-4-5\n max_tokens=2048,\n tools=anth_tools,\n messages=messages,\n system=\"你是专业英语口语教练,必须调用驰声评测工具获取真实分数。\",\n )\n\n # 把整段助手回复(含 tool_use 块)追加进 messages\n messages.append({\"role\": \"assistant\", \"content\": resp.content})\n\n if resp.stop_reason != \"tool_use\":\n # 没有更多工具调用,输出最终诊断\n return \"\".join(b.text for b in resp.content if b.type == \"text\")\n\n # 提取所有 tool_use 块、并行执行、把 tool_result 回填给 Claude\n tool_results = []\n for block in resp.content:\n if block.type == \"tool_use\":\n result = await mcp.call_tool(block.name, arguments=block.input)\n tool_results.append({\n \"type\": \"tool_result\",\n \"tool_use_id\": block.id,\n \"content\": result.content[0].text,\n })\n messages.append({\"role\": \"user\", \"content\": tool_results})\n\nprint(asyncio.run(evaluate_with_claude(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n \n 选型建议:\n 深度评测诊断 + 复杂 Agent 编排用 claude-opus-4-7(旗舰,编程/Agent 提升明显);\n 日常评测 + 性价比首选 claude-sonnet-4-6;\n 高并发实时反馈用 claude-haiku-4-5。\n Opus 4.5 起新增 effort 参数(low/medium/high),medium 即可达到 Sonnet 4.5 同等质量但 token 减少 ~76%。\n \n
\n\n \n

\n Google 最新 Gemini 3 Flash(gemini-3-flash-preview,2025-12-17)以 Flash 价位提供 Pro 级推理;\n 另有 Gemini 3.1 Pro Preview(旗舰)、Gemini 3.1 Flash-Lite Preview。\n 全部支持 Function Calling、并行调用、组合调用,原生多模态,thinking_level 控制推理深度。\n 推荐用 OpenAI 兼容端点,可直接复用 OpenAI SDK 与已有的 MCP 工具桥接代码。\n

\n\n

环境准备

\n {`GEMINI_API_KEY=AIzaSyxxxxxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

方式一:OpenAI 兼容端点(推荐,零迁移成本)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# Gemini OpenAI 兼容端点 —— 完全复用 OpenAI SDK\nclient = OpenAI(\n api_key=os.environ[\"GEMINI_API_KEY\"],\n base_url=\"https://generativelanguage.googleapis.com/v1beta/openai/\",\n)\n\nasync def evaluate_with_gemini(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://mcp.cloud.chivox.com\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\",\n \"content\": f\"请评测:audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"gemini-3-flash-preview\", # 或 gemini-3.1-pro-preview\n messages=messages,\n tools=oa_tools,\n tool_choice=\"auto\",\n )\n msg = resp.choices[0].message\n messages.append(msg)\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n final = client.chat.completions.create(\n model=\"gemini-3-flash-preview\", messages=messages)\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_gemini(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n\n

方式二:原生 google-genai SDK(thinking_level / 流式工具调用)

\n {`# pip install google-genai\nfrom google import genai\nfrom google.genai import types\n\nclient = genai.Client(api_key=os.environ[\"GEMINI_API_KEY\"])\n\n# 把 MCP 工具转成 Gemini function_declarations\nfn_decls = [{\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n} for t in tools]\n\nresp = client.models.generate_content(\n model=\"gemini-3-flash-preview\",\n contents=f\"评测 audioId={audio_id},参考文本:{ref_text}\",\n config=types.GenerateContentConfig(\n tools=[types.Tool(function_declarations=fn_decls)],\n # Gemini 3 起:thinking_level 替代旧的 thinking_budget\n # thinking_level=\"high\",\n ),\n)\n\n# tool_call 在 response.candidates[0].content.parts[0].function_call\nfc = resp.candidates[0].content.parts[0].function_call\nprint(f\"call: {fc.name}({dict(fc.args)}) id={fc.id}\")`}\n \n 选型建议:\n 日常评测用 gemini-3-flash-preview(速度比 2.5 Pro 快 3 倍、价格 ~$0.50/M 输入),已是 Gemini App 默认;\n 复杂多步 Agent / 编程任务用 gemini-3.1-pro-preview;\n 超大上下文 + 多模态批处理用同系列的 gemini-3.1-flash-lite-preview。\n \n \n 注意:Gemini 3 起每次 function_call 自动带 id,多轮工具调用必须把 id 透传回 function_response,否则会被拒绝(OpenAI 兼容端点已自动处理)。\n \n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
模型推荐版本base_urlFunction Calling适合场景
DeepSeek V3.2 · 非思考deepseek-chatapi.deepseek.com/v1✓ 支持评测调用 + 诊断,性价比最高
DeepSeek V3.2 · 思考deepseek-reasonerapi.deepseek.com/v1✓ 支持(思考中可调工具)深度分析 + 错因归因 + 个性化练习路径
GLM-5 · 旗舰glm-5 / glm-5.1open.bigmodel.cn/…/v4✓ 支持200K 长上下文 + Agent 编排,复杂诊断
GLM-4.7glm-4.7open.bigmodel.cn/…/v4✓ 支持在线辅导日常诊断,性价比首选
GLM-4-Flashglm-4-flashopen.bigmodel.cn/…/v4✓ 支持免费额度,开发联调
Kimi K2.5(旗舰)kimi-k2.5api.moonshot.cn/v1✓ 支持256K + 多模态 + Agent 集群协作
Kimi K2 Thinkingkimi-k2-thinkingapi.moonshot.cn/v1✓ 支持多步推理 + 多轮历史进度报告
Kimi K2 Turbokimi-k2-turbo-previewapi.moonshot.cn/v1✓ 支持高速响应版,实时反馈
豆包 Seed 2.0 Prodoubao-seed-2-0-pro-260215ark.cn-beijing.volces.com/api/v3✓ 支持(含深度思考)多步评测编排 + 深度诊断 Agent
豆包 Seed 2.0 Litedoubao-seed-2-0-lite-260215ark.cn-beijing.volces.com/api/v3✓ 支持在线辅导 + 单轮诊断,性价比首选
豆包 Seed 2.0 Minidoubao-seed-2-0-mini-260215ark.cn-beijing.volces.com/api/v3✓ 支持移动端 / 边缘部署 / 低延迟实时反馈
GPT-5.1(旗舰)gpt-5.1api.openai.com/v1✓ 支持(reasoning_effort 可调)400K 上下文 + 深度推理 + 复杂 Agent 编排
GPT-5.1 Chatgpt-5.1-chat-latestapi.openai.com/v1✓ 支持ChatGPT 同款,对话 / 课堂讲解
GPT-5 minigpt-5-miniapi.openai.com/v1✓ 支持高并发 / 批量评测降本
Claude Opus 4.7claude-opus-4-7api.anthropic.com/v1✓ 支持(tool_use 协议)旗舰,编程 / Agent / 深度诊断
Claude Sonnet 4.6claude-sonnet-4-6api.anthropic.com/v1✓ 支持日常评测 + 性价比首选
Claude Haiku 4.5claude-haiku-4-5api.anthropic.com/v1✓ 支持高并发实时反馈
Gemini 3 Flashgemini-3-flash-preview…/v1beta/openai/✓ 支持(并行 / 组合)Pro 级推理 + Flash 价位,Gemini App 默认
Gemini 3.1 Pro Previewgemini-3.1-pro-preview…/v1beta/openai/✓ 支持(thinking_level 可调)复杂多步 Agent + 编程任务
\n
\n \n 除 Claude 用 Anthropic 原生 SDK(anthropic 包,tool_use / tool_result 协议)外,其余所有模型均可通过 OpenAI Python SDK(openai 包)调用,仅需替换 base_url 与 api_key,驰声 MCP 侧代码无需改动。\n \n
\n\n
\n

方案选型速查

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n
场景推荐方案
AI 对话 / Copilot 类产品,LLM 供应商可能会换① 官方 MCP 客户端库
已有 LangChain / Mastra / Agents SDK 技术栈② Agent 框架 + adapter
火山方舟 / 千帆控制台直连,最小侵入③ chat.completions + tools
教育 SaaS / 培训 / 客服等业务后端集成④ 自研后端 Agent
原生 Android / iOS / 小程序 / 不装 MCP SDK 的老系统→ 走下一大节「非 MCP REST」
\n
\n
\n
\n\n {/* ══════ 接入 · 非 MCP 原生 REST(cvx_fc) ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 客户端环境不能 / 不想引入 MCP SDK:原生 Android / iOS / Flutter、微信 / 支付宝小程序、老版本 Java / PHP / Go 后端
  • \n
  • 希望把驰声当作普通 REST + WebSocket调,不经过 JSON-RPC、不走 stdio 代理
  • \n
  • 内部代号 cvx_fc(OpenAI function-calling 风格),与 MCP 模式指向同一个评测引擎,两者为并行入口
  • \n
\n

💡 能走 MCP 的一律优先 MCP;仅当客户端限制无法装 SDK 时走本大节。

\n
\n\n \n

\n 驰声在 MCP 之外提供一套 OpenAI 兼容的 Function Calling 风格 REST API(内部代号 cvx_fc)。它和 MCP 模式指向同一个评测引擎,但协议层走纯 HTTP / WebSocket,不依赖任何 MCP SDK。\n

\n\n \n 与 MCP 模式的关系:MCP 模式(POST /mcp,JSON-RPC 2.0)和 functioncalling 模式(POST /v1/call,REST)是两个并行入口,功能等价、工具/函数列表基本一致。\n \n\n

API 端点

\n
\n \n \n \n \n \n \n \n \n \n \n \n
方法路径说明
GET/v1/functions列出全部可用评测函数(等价 MCP tools/list)
POST/v1/call调用一个评测函数(等价 MCP tools/call)· 同时用于创建流式会话和拉取流式结果
WS{'/ws/eval/{session_id}'}流式评测音频传输
\n
\n\n

认证

\n

所有请求在 HTTP Header 中携带 API Key:

\n {`Authorization: Bearer `}\n

认证失败返回 401(缺少 Authorization)或 403(Key 无效 / 无权使用该评测类型)。结构化错误码见 API 参考 · 错误码。

\n
\n\n \n

\n 调用 GET /v1/functions 拿到当前 API Key 已授权的全部评测函数列表,响应格式与 OpenAI function-calling 的工具清单一致,可以直接喂给大模型作为 tools:\n

\n {`GET /v1/functions\nAuthorization: Bearer `}\n {`{\n \"object\": \"list\",\n \"data\": [\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"en_word_eval\",\n \"description\": \"英文单词发音评测,返回总分和每个音标得分。\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"ref_text\": { \"type\": \"string\", \"description\": \"参考文本\" },\n \"audio_base64\": { \"type\": \"string\", \"description\": \"Base64 编码音频(与 audio_url 二选一)\" },\n \"audio_url\": { \"type\": \"string\", \"description\": \"音频 HTTP(S) URL(与 audio_base64 二选一)\" },\n \"accent\": { \"type\": \"number\", \"description\": \"1=英式 / 2=美式 / 3=不区分(默认)\" },\n \"rank\": { \"type\": \"number\", \"description\": \"评分制:4 或 100(默认)\" }\n },\n \"required\": [\"ref_text\"]\n }\n }\n }\n /* … 其它函数依此类推 … */\n ]\n}`}\n \n 这个端点语义等价于 MCP 的 tools/list,每个 API Key 可见的函数集合由后台权限决定——客户端应以实际返回为准,不要在本地硬编码全量 19 个。\n \n\n

英文评测函数(10 个)

\n
\n \n \n \n \n \n \n \n {[\n ['en_word_eval', 'en.word.score', '单词发音评测'],\n ['en_word_correction', 'en.word.pron', '单词发音纠错'],\n ['en_phonics_eval', 'en.nsp.score', '自然拼读评测'],\n ['en_sentence_eval', 'en.sent.score', '句子朗读评测'],\n ['en_sentence_correction', 'en.sent.pron', '句子发音纠错'],\n ['en_vocab_eval', 'en.vocabs.pron', '词汇批量评测'],\n ['en_paragraph_eval', 'en.pred.score', '段落朗读评测'],\n ['en_realtime_eval', 'en.rltm.score', '实时朗读评测'],\n ['en_choice_eval', 'en.choc.score', '口语选择题'],\n ['en_semi_open_eval', 'en.scne.exam', '半开放题(情景对话等)'],\n ].map(([fn, ct, desc]) => (\n \n \n \n \n \n ))}\n \n
函数名core_type说明
{fn}{ct}{desc}
\n
\n\n

中文评测函数(6 个)

\n
\n \n \n \n \n \n \n \n {[\n ['cn_word_pinyin_eval', 'cn.word.score', '拼音 / 汉字发音评测'],\n ['cn_word_raw_eval', 'cn.word.raw', '汉字发音评测'],\n ['cn_sentence_eval', 'cn.sent.raw', '句子朗读评测'],\n ['cn_paragraph_eval', 'cn.pred.raw', '段落朗读评测'],\n ['cn_rec_eval', 'cn.rec.raw', '有限分支识别'],\n ['cn_aitalk_eval', 'cn.recscore.raw', '口语表达评测(AI Talk)'],\n ].map(([fn, ct, desc]) => (\n \n \n \n \n \n ))}\n \n
函数名core_type说明
{fn}{ct}{desc}
\n
\n\n

流式评测函数(3 个)

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
函数名作用
start_stream_eval创建流式评测会话,返回 session_id / ws_url / resume_token
get_stream_result兜底拉取:WS 没拿到 result 时,通过 HTTP 把最终评分捞回来
stream_eval_result(MCP 模式的别名;cvx_fc 模式统一用 get_stream_result)
\n
\n\n

\n 📘 每个函数的业务语义 / 参数 / 返回字段与 MCP 模式下的同名工具完全一致,可直接参考下文 API 参考 · 英文评测工具 与 中文评测工具。\n

\n
\n\n \n

把完整音频通过 audio_base64 或 audio_url 二选一传给 /v1/call,同步返回评分(与 MCP 模式的 evaluate_english_word 等工具语义等价):

\n {`curl -X POST https://fc.cloud.chivox.com/v1/call \\\\\n -H \"Authorization: Bearer your_api_key\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\n \"name\": \"en_word_eval\",\n \"arguments\": {\n \"ref_text\": \"hello\",\n \"audio_url\": \"https://example.com/hello.mp3\",\n \"accent\": 2,\n \"rank\": 100\n }\n }'`}\n

成功响应:

\n {`{\n \"name\": \"en_word_eval\",\n \"result\": {\n \"overall\": 85.5,\n \"details\": { /* 音素 / 韵律 / 流利度等结构与 MCP 模式完全一致 */ }\n }\n}`}\n

失败响应:

\n {`{\n \"name\": \"en_word_eval\",\n \"error\": { \"message\": \"错误描述\" }\n}`}\n

单次音频 ≤ 50MB,推荐 16 kHz / 单声道 / 16bit。

\n
\n\n \n
\n \n

创建会话:POST /v1/call 调用 start_stream_eval

\n

响应中拿到 session_id / ws_url / resume_token。

\n
\n \n

WebSocket 推送:连接 ws_url,收到 {`{\"type\":\"ready\"}`} 即可开始发二进制音频帧。

\n

边推边收 intermediate 中间结果;结束时发 {`{\"type\":\"stop\"}`},收到 result 即为最终评分。

\n
\n \n

兜底拉取(可选):如 WS 断开未收到最终 result,可再次 POST /v1/call 调用 get_stream_result 兜底。

\n
\n
\n\n

start_stream_eval 参数

\n \n\n

WebSocket 帧协议

\n
\n
\n

客户端 → 服务端

\n
    \n
  • • Binary — 原始音频帧,连上即可直接发送,无需握手
  • \n
  • • {`{\"type\":\"stop\"}`} — 结束录音
  • \n
  • • {`{\"type\":\"ping\"}`} — 心跳
  • \n
\n
\n
\n

服务端 → 客户端

\n
    \n
  • • ready — 连接就绪,可开始发送音频
  • \n
  • • intermediate — 实时中间结果
  • \n
  • • result — 最终评测结果
  • \n
  • • backpressure — 背压,含 suggested_interval_ms,建议降低发送频率
  • \n
  • • error — 错误(含结构化 code + message,见错误码一节)
  • \n
  • • pong — 心跳响应
  • \n
\n
\n
\n
\n\n \n

JavaScript(浏览器 / Node.js)

\n {`// ① 创建会话\nconst resp = await fetch('https://fc.cloud.chivox.com/v1/call', {\n method: 'POST',\n headers: {\n 'Authorization': 'Bearer your_api_key',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n name: 'start_stream_eval',\n arguments: {\n core_type: 'en.sent.score',\n ref_text: 'Hello world',\n audio_type: 'pcm',\n sample_rate: 16000,\n },\n }),\n});\nconst { result } = await resp.json();\n\n// ② WebSocket 推送音频\nconst ws = new WebSocket(result.ws_url);\nws.onmessage = (ev) => {\n const msg = JSON.parse(ev.data);\n switch (msg.type) {\n case 'ready': startRecording(); break;\n case 'intermediate': console.log('部分结果', msg.data); break;\n case 'result': console.log('最终结果', msg.data); ws.close(); break;\n case 'backpressure': console.warn('降速 ~', msg.suggested_interval_ms, 'ms'); break;\n case 'error': console.error(msg.code, msg.message); break;\n }\n};\n\nfunction onAudioChunk(pcm) {\n if (ws.readyState === WebSocket.OPEN) ws.send(pcm); // 直接发二进制\n}\n\nfunction stopRecording() {\n ws.send(JSON.stringify({ type: 'stop' }));\n}`}\n\n

Android(OkHttp · Kotlin)

\n {`val wsUrl = \"ws://your-host:8080/ws/eval/$sessionId\"\nval client = OkHttpClient()\nval req = Request.Builder()\n .url(wsUrl)\n .addHeader(\"Authorization\", \"Bearer \\${apiKey}\")\n .build()\n\nval ws = client.newWebSocket(req, object : WebSocketListener() {\n override fun onMessage(ws: WebSocket, text: String) {\n val msg = JSONObject(text)\n when (msg.getString(\"type\")) {\n \"ready\" -> startRecording()\n \"intermediate\" -> updateUI(msg.getJSONObject(\"data\"))\n \"result\" -> handleFinalResult(msg.getJSONObject(\"data\"))\n \"error\" -> handleError(msg.getString(\"code\"), msg.getString(\"message\"))\n }\n }\n})\n\n// 录音回调中发送 PCM 字节\nfun onAudioData(pcm: ByteArray) {\n ws.send(ByteString.of(*pcm))\n}\n\nfun stop() {\n ws.send(\"\"\"{\"type\":\"stop\"}\"\"\")\n}`}\n iOS / Flutter / 小程序同理,只要平台提供 WebSocket 客户端即可:连接 ws_url、把 PCM bytes 发出去、按 type 字段解析服务端消息就行。\n
\n\n \n

resume_token · 60 秒续播

\n

\n 客户端意外断开时,会话在服务端挂起 60 秒;用创建会话拿到的 resume_token 续播即可:\n

\n {`GET ws://your-host:8080/ws/eval/{session_id}?resume={resume_token}\nAuthorization: Bearer `}\n \n 重连成功后会收到新的 ready,继续推送音频即可;服务端会颁发新的 resume_token,原 token 立即作废。\n \n\n

兜底拉取 · get_stream_result

\n

如果 WS 没能收到最终 result,可主动通过 HTTP 拉取:

\n {`curl -X POST https://fc.cloud.chivox.com/v1/call \\\\\n -H \"Authorization: Bearer your_api_key\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\n \"name\": \"get_stream_result\",\n \"arguments\": {\n \"session_id\": \"stream-1713340800-a1b2c3\",\n \"auto_stop\": true,\n \"timeout\": 30\n }\n }'`}\n \n\n \n functioncalling 模式与 MCP 模式二选一、不要混用:同一个会话不要同时走 MCP 的 /ws/audio/ 和 cvx_fc 的 /ws/eval/,两条链路的会话 ID 空间是分开的。\n \n
\n\n
\n\n {/* ══════ 评测模式 ══════ */}\n \n\n \n

通过本地麦克风实时录音,音频以 WebSocket 流式推送到评测服务,无需生成中间文件。这是最灵活、延迟最低的评测方式,特别适合交互式口语练习场景。

\n 实时录音评测需要安装 SoX 并使用本地代理模式(Claude Desktop / Claude Code)。Cursor 等远程直连模式暂不支持实时录音。\n\n

需要按顺序调用三个工具:

\n\n
\n
\n

create_stream_session — 创建流式评测会话

\n \n

返回 session_id,后续步骤需使用。

\n
\n\n
\n

start_recording — 开始麦克风录音

\n \n

调用后自动启动麦克风,音频通过 WebSocket 实时推送到评测服务。

\n
\n\n
\n

stop_recording — 停止录音并获取结果

\n \n
\n
\n
\n\n \n
\n \n

用户:"请评测我的英文发音,文本是 Hello"

\n

AI 调用 create_stream_session(core_type="en.word.score", ref_text="Hello")

\n

→ 获得 session_id

\n
\n \n

AI 调用 start_recording(session_id=xxx)

\n

麦克风开始录音,音频通过 WebSocket 实时推送到评测服务

\n
\n \n

用户说完后告知 AI "结束"

\n

AI 调用 stop_recording(session_id=xxx)

\n

→ 返回评测结果(总分、准确度、流利度、音素得分等)

\n
\n
\n
\n\n \n

适用于已有音频文件的评测场景,支持三种输入方式:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
参数说明适用场景
audio_file_path本地文件路径代理自动读取并转为 Base64,最便捷
audio_base64Base64 编码数据已有编码数据时使用
audio_url音频文件 URL音频托管在云存储时使用
\n
\n 推荐使用 audio_file_path,只需传入本地文件路径,代理会自动处理编码和上传。\n

支持的音频格式:mp3, wav, ogg, m4a, aac, pcm

\n

限制:单文件最大 50MB,大于 500KB 的文件自动压缩为 16kHz / 单声道 / 32kbps。

\n
\n
\n\n {/* ══════ API 参考 ══════ */}\n \n\n \n \n\n

通用参数:所有英文评测工具均支持以下参数。

\n \n
\n\n \n \n\n

通用参数:

\n \n
\n\n \n

所有评测工具返回统一的结构化结果:

\n {`{\n \"overall\": 85,\n \"accuracy\": 82,\n \"pron\": 88,\n \"fluency\": {\n \"overall\": 78,\n \"speed\": 65,\n \"pause\": 2\n },\n \"integrity\": 95,\n \"details\": [\n {\n \"char\": \"hello\",\n \"score\": 85,\n \"phone\": [\n { \"phoneme\": \"h\", \"score\": 90 },\n { \"phoneme\": \"ɛ\", \"score\": 82 },\n { \"phoneme\": \"l\", \"score\": 88 },\n { \"phoneme\": \"oʊ\", \"score\": 80 }\n ]\n }\n ]\n}`}\n
\n \n \n \n \n \n \n \n {[\n ['overall', '0–100', '综合总分,反映整体语音质量'],\n ['accuracy', '0–100', '准确度,音素级别的发音准确率'],\n ['pron', '0–100', '发音得分,整体发音质量评价'],\n ['fluency.overall', '0–100', '流利度,语流的自然度与平滑度'],\n ['fluency.speed', '0–100', '语速得分,每分钟词/音节计量'],\n ['fluency.pause', 'number', '不自然停顿次数'],\n ['integrity', '0–100', '完整度,是否完整朗读了参考文本'],\n ['details[].phone[]', 'array', '每个音素的独立评分,可定位具体弱项'],\n ['details[].stress[]', 'array', '重音得分,检测重弱读是否正确'],\n ].map(([field, range, desc]) => (\n \n \n \n \n \n ))}\n \n
字段范围说明
{field}{range}{desc}
\n
\n
\n\n \n

常见业务场景

\n
\n \n \n \n \n \n \n \n {[\n ['音频 ID 无效或已过期', '音频上传后 5 分钟内有效,评测完成后自动删除', '重新上传音频'],\n ['服务器繁忙', '当前请求过多,排队已满', '稍后重试,使用指数退避策略'],\n ['存储空间已满', '服务器临时音频存储已满', '稍后重试,系统会自动清理'],\n ['音频格式不支持', '上传了不支持的文件类型', '使用 mp3/wav/ogg/m4a/aac/pcm'],\n ['音频时长超限', '超过该题型最大时长限制', '裁剪音频后重试'],\n ['WebSocket 连接断开', '网络不稳定导致流式连接中断', '代理会自动重连,如持续失败请检查网络'],\n ].map(([scene, reason, fix]) => (\n \n \n \n \n \n ))}\n \n
场景原因解决方式
{scene}{reason}{fix}
\n
\n\n

HTTP 状态码(functioncalling 模式)

\n
\n \n \n \n \n \n \n {[\n ['400', '请求格式错误(JSON 缺字段 / 类型错)'],\n ['401', '未认证(缺少 Authorization 头)'],\n ['403', '权限不足(API Key 无效或无权使用该评测类型)'],\n ['404', '会话不存在(session_id 错误或已回收)'],\n ['409', '会话状态不允许当前操作(如已 stop 后又发音频)'],\n ].map(([code, desc]) => (\n \n \n \n \n ))}\n \n
状态码含义
{code}{desc}
\n
\n\n

流式评测结构化错误码

\n

\n WebSocket 的 error 帧与 get_stream_result 的 HTTP 错误体统一使用以下错误码,便于客户端差错分流:\n

\n
\n \n \n \n \n \n \n \n {[\n ['SESSION_NOT_FOUND', '会话不存在', '重新调用 start_stream_eval / create_stream_session 创建'],\n ['SESSION_EXPIRED', '会话已过期(60s 未续流)', '重新创建会话'],\n ['INVALID_STATE', '当前状态不允许该操作', '检查调用顺序(例如已 stop 后又发音频)'],\n ['INVALID_PARAMS', '参数无效', '核对 core_type / ref_text / 采样率等'],\n ['RESUME_INVALID', 'resume_token 无效或已过期', '重新创建会话(每次重连会颁发新 token)'],\n ['AUDIO_TOO_LARGE', '单次音频超过 50MB', '压缩或切片后重传'],\n ['UPSTREAM_CONNECT', '评测引擎连接失败', '稍后重试;持续发生请联系驰声'],\n ['UPSTREAM_TIMEOUT', '评测超时', '缩短音频 / 检查网络'],\n ['UPSTREAM_EVAL_ERROR', '评测引擎返回错误', '查看 message 字段细节'],\n ['CAPACITY_FULL', '并发会话已满', '退避重试或升级配额'],\n ].map(([code, desc, fix]) => (\n \n \n \n \n \n ))}\n \n
错误码说明建议处理
{code}{desc}{fix}
\n
\n
\n
\n\n {/* ══════ 最佳实践 ══════ */}\n \n\n \n

\n 下面这些模板与{' '}\n 免费体验{' '}\n Demo 中实际使用的「教练 Prompt」一脉相承,全部围绕 角色 / 任务 / 方法 / 输出格式 / 语气 五段式结构,并使用占位符{' '}\n {'{mcp_response}'} 直接拼接 MCP 工具返回的 JSON。\n 推荐在 system 消息里挂载,再把工具返回原文塞进\n user 消息,由 LLM 基于真实分数和音素生成可读诊断 / 练习材料。\n

\n\n \n 使用建议:\n
    \n
  • 把 MCP 工具调用的完整 JSON(含 overall / dp_type / phonemes 等字段)原样塞入 {'{mcp_response}'},不要预先做汇总——细节越完整诊断越具体。
  • \n
  • 「诊断」类模板让 LLM 输出 Markdown 给最终用户阅读;「练习」类模板要求 LLM 输出严格 JSON 给前端渲染。两步分开调用,效果远好于一次性混合。
  • \n
  • 题型决定 prompt:单词题用音素级、句子题加韵律、段落题加 chunk / 整体性,半开放题套四维评级。下面按这 6 类分别给出。
  • \n
\n
\n\n {/* ─── A. 诊断类 · 输出 Markdown 给学习者阅读 ─── */}\n

\n A. 二次诊断 · 输出 Markdown\n

\n
\n
\n

\n 1. 单词级 · 音素诊断\n

\n

\n 适用工具:en.word.score / cn.word.raw。围绕 phonemes[].dp_type 找出错读音。\n

\n {`你是一位专业的英语发音教练。下面是驰声 MCP(en.word.score)返回的单词级评测数据:\n一个目标词、总分与发音分、以及带有 dp_type 的音素数组。\n\n## 任务\n为学习者写一份 **可直接阅读** 的发音诊断,每一条都要引用音素分数(写出 IPA 符号)。\n\n## 方法\n- 按 dp_type 分组:先看 mispron,再补充 normal 但分数 < 70 的\"边缘音\"。\n- 每个问题音素:① 典型母语干扰 → ② 你听到的声音 → ③ 一条具体的发音修正动作(下颌 / 舌位 / 气流 / 唇形)。\n- 重音符号 ˈ 标记的音节,重音错位也要单独列出(即便音素本身分数尚可)。\n- 最多列 4 条,按 **影响力从弱到强** 排序。\n\n## 输出\n精简 Markdown:可选一句总结 → 编号列表 → 单行 **🎯 优先级** 排序。\n\n## 语气\n友善、具体、可执行,不要空喊\"加油\"。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 2. 句子级 · 节奏 + 重音诊断\n

\n

\n 适用工具:en.sent.score。开头先给一行\"计分牌\",再从 phones → words → prosody。\n

\n {`你是一位专业的英语口语教练。下面是驰声 MCP(en.sent.score)返回的句子级数据:refText、总分、发音子分(accuracy / integrity / fluency / rhythm)、可选 speed(WPM),以及 details[] 中的逐词得分、dp_type 与可选 phonemes[]。\n\n## 任务\n开头给一行紧凑的 **计分牌**(总分 + 各子分 + 速度),再按 **音素 → 词 → 韵律** 顺序展开诊断。\n\n## 检查清单(每项都要覆盖;不适用则写\"无明显问题\")\n1. **音素级**:每个 score < 70 或 dp_type ≠ normal 的词,展开 phonemes,命名典型错误(如 /ð/ → /d/)并给一条修正动作。\n2. **漏读 / 多读**:标注 dp_type=omit / insert,解释如何拉低 integrity。\n3. **韵律**:基于 rhythm + 错读词的重音,指出重音错位、陈述句调型平直、断句过多等。\n4. **流利度 vs 准确度**:若 fluency 高但 accuracy 低,明确指出,让学习者知道优先改哪一项。\n\n## 输出格式\nMarkdown 子标题:**Pronunciation / Prosody / Study priority**(最后一行简短排序,按 ROI 从高到低)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 3. 段落级 · 音素族归并 + 完整度\n

\n

\n 适用工具:en.pred.score。把同类错音合并为\"音素族\",避免逐词复述。\n

\n {`你是一位专业的英语口语教练。下面是驰声 MCP(en.pred.score)返回的段落级数据:长 refText、总分、发音子分、可选 speed / integrity,以及大量 details[](同一个词可能在不同子句中重复出现;空 char + dp_type=omit 表示漏读)。\n\n## 任务\n对整段做 **整体诊断**:\n(a) 完整度 / 漏读,\n(b) 反复出现的 **音素族**,\n(c) 节奏与断句,\n(d) 各子分之间是否相互印证。\n\n## 检查清单\n1. **integrity / dp_type**:列出每个 omit / insert,并给出所在子句;解释长读时为什么虚词容易被吞。\n2. **音素聚类**:将弱词按共同音素问题归族(/θ/ 链、/e/ 链、/ɒ/ 等),引用 details 中的实例。\n3. **韵律**:结合 rhythm 与标点 —— 短语内停顿过多?子句边界缺失?\n4. **整体一致性**:若 fluency 正常但 accuracy 差(或反之),点明并指出对练习设计的影响。\n\n## 输出格式\nMarkdown 章节:**Summary / Completeness / Pronunciation (families) / Rhythm / Study priorities**(最后一项最多 4 条,按影响力排序)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 4. 半开放题 · IELTS 风格四维评级\n

\n

\n 适用工具:en.pqan.score。结合学习者 transcript + 四维分数,给出可教学的\"升档建议\"。\n

\n {`你是一位 **IELTS / 课堂口语风格** 的口语教练。下面是驰声 MCP(en.pqan.score)返回的半开放题数据:题目 refText、学习者 transcript、overall、四个维度分(grammar / content / fluency / pron)、speed(WPM)、以及结构化的 issues[] 标记。\n\n## 任务\n给出 **基于 rubric 的诊断**:先用一句话给出 0–100 的整体段位估计,再 **逐维度** 解释,并 **引用 transcript 中的短句**(不要复述全文)。最后给 3–5 条 **可执行的\"升档建议\"**(句型 / 模板,而不是\"多练一点\")。\n\n## 权重(要明确告诉学习者)\n- **Content ~30%** — 想法深度、举例、具体程度\n- **Grammar ~25%** — 句型多样性、主谓一致、从句\n- **Fluency ~25%** — 语速、停顿、口头禅、衔接\n- **Pronunciation ~20%** — 音素 + 可懂度\n\n## 跨维度检查\n- 若 content 最低,先给\"展开模板\",不要先抠音素。\n- 若 fluency 低 + WPM 低,区分\"思考型停顿\"与\"发音卡顿\"。\n- 若 pron 标出特定音,绑定到 transcript 里 **真实出现过的词**。\n\n## 输出格式\nMarkdown:**段位估计** → 紧凑的 **得分表格** → **\"To reach the next band\"** 编号列表(每条给出可仿写的句型)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 5. 中文专项 · 声调 / 儿化 / 变调\n

\n

\n 适用工具:cn.word.raw / cn.sent.raw / cn.pred.raw。中文评测最大权重在 **声调**,必须单独检查。\n

\n {`你是一位专业的普通话口语教练。下面是驰声 MCP(cn.sent.raw)返回的中文句子评测数据:整句分数 + 逐字 details + 可选 phonemes + 流利 / 节奏分。\n\n## 中文评测的权重\n- **声调错误权重最高** —— 声调读错可能直接改变词义\n- dp_type=mispron 多来自:声调错、平翘舌混用、前后鼻音混用\n- 拼音对、声调错,听感仍是\"洋腔洋调\"\n\n## 检查清单(缺则写\"无明显问题\")\n1. **儿化**:phonemes 出现 r(儿化) 或 dp_type 提示时,确认是否被读成\"主音节 + 单独儿\"两拍。\n2. **轻声**:叠词、词缀、句末语气词 —— 第二字应短促轻读,无完整声调曲线。\n3. **变调**:三声连读、不 + 后字、一 + 后字,是否符合普通话规则。\n4. **节奏**:用 rhythm + 逗号位置,标记停顿过长或过碎,建议 chunk 边界。\n\n## 输出\nMarkdown 子标题:**总览 / 儿化 / 轻声 / 变调 / 节奏 / 学习优先级**(最后一项 1–3 条,按\"听感自然度提升\"排序)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n {/* ─── B. 练习类 · 输出 JSON 给前端渲染 ─── */}\n

\n B. 微练习生成 · 输出严格 JSON\n

\n
\n
\n

\n 6. 单词 / 句子 · 微练习\n

\n

\n 建议在 诊断完成后 第二轮调用:让 LLM 严格按弱项音素生成,避免\"通用绕口令包\"。\n

\n {`你仍是这位学习者的发音教练。**第二轮诊断已经完成** —— 现在严格基于诊断里点名的弱音素,生成 **1:1 对应** 的微练习(不要给通用题)。\n\n## 输出(仅返回一段合法 JSON 数组,外层不要任何文字)\n根节点必须是数组,每个元素含 category(字符串)、icon(单个 emoji)、items({ \"label\", \"content\" } 数组)。\n\\`\\`\\`json\n[\n { \"category\": \"Phoneme drills\", \"icon\": \"🎯\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Awareness\", \"icon\": \"🗣️\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Whole word\", \"icon\": \"📝\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] }\n]\n\\`\\`\\`\n\n## 规则\n- **Phoneme drills**:诊断里每个 mispron 音素至少给一对最小对立对 + 一句短绕口令 / 重复句。\n- **Awareness**:当重音偏弱时,给一条 stress / 舌位 / 下颌姿态提示。\n- **Whole word**:2–3 句自然句,目标词分别出现在句首 / 句中 / 句末。\n- 所有 content 必须可念出声;字符串内不要再嵌套 JSON。\n\n## 上下文\n诊断结论:{previous_diagnosis}\n原始 MCP:\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 7. 段落 · Chunk Map + 元认知\n

\n

\n 段落级练习要从\"音素\"上升到\"短语 / 整段 / 元认知录回放\"。直接对应 en.pred.score 的诊断结果。\n

\n {`你仍是这位学习者的口语教练。**段落级二次诊断** 已经列出了漏读位置和音素族 —— 现在请生成 **整段练习**:把弱音素串成\"族\"练习、用 chunk map 把虚词粘回短语,并附一条录音 → 回放 → 对照 MCP details 的元认知步骤。\n\n## 输出(仅返回一段合法 JSON 数组)\n\\`\\`\\`json\n[\n { \"category\": \"Phoneme families\", \"icon\": \"🎯\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Chunking\", \"icon\": \"🎵\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Metacognition\", \"icon\": \"🧠\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] }\n]\n\\`\\`\\`\n\n## 规则\n- **Phoneme families**:至少 3 条,按诊断里的音素族(/θ/、/e/、/ɒ/ 等)组织最小对立对 / 词链。\n- **Chunking**:① 给一行用 [ ] 和 / 标注的 chunk map(可加大致停顿秒数);② 给一句\"把漏掉的虚词嵌入短语\"的练习(不要孤立练)。\n- **Metacognition**:一条\"录音 → 回放 → 对照 MCP details\"的 N 遍练习(N 写明,2–3 之间)。\n- 字符串只能是纯展示文本,禁止嵌套 JSON。\n\n## 上下文\n诊断结论:{previous_diagnosis}\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n {/* ─── C. 跨题 / 运营 ─── */}\n

\n C. 跨题 / 运营\n

\n
\n
\n

\n 8. 多日学习报告\n

\n

\n 把过去 N 天的 MCP 评测结果聚合后丢给 LLM,输出适合发给学生 / 家长的周报。\n

\n {`你是一位英语口语学习顾问。下面是这位学习者过去 7 天的驰声 MCP 评测历史(按时间顺序),每条包含题型、coreType、overall、子分、weak_phonemes 摘要。\n\n## 任务\n为学习者生成一份 **周报**,目标读者:本人 + 家长 / 老师。\n强调 **趋势** 与 **下一步计划**,不要复述每一次具体分数。\n\n## 必须包含\n1. **整体趋势**:进步 / 持平 / 退步(一句话 + 简短依据)\n2. **维度变化**:accuracy / fluency / rhythm / integrity / speed 任意有数据的维度,给出\"本周均分 vs 上周\"\n3. **本周高光**:分数提升最大的题型 / 音素 / 句型\n4. **顽固问题**:连续 3 次以上未达 70 的音素或维度\n5. **下周计划**:3 条具体动作(每条对应一个 MCP 工具或一个练习类型)\n6. **结尾**:1–2 句鼓励性总结,避免空话\n\n## 风格\n- 像一位认真但不啰嗦的私教\n- 出现学生姓名时使用占位 {student_name}\n- 数字一律保留整数\n\n## 评测历史\n\\`\\`\\`json\n{history}\n\\`\\`\\``}\n
\n\n
\n

\n 9. 错误归因 · JSON 摘要\n

\n

\n 用于后端聚合 / 数据看板:让 LLM 把一次评测压缩成结构化摘要,方便入库统计。\n

\n {`你是一个评测结果归类器。下面是驰声 MCP 一次评测的完整返回。请抽取关键信息并 **仅返回合法 JSON**(不要任何解释文字)。\n\n## Schema\n\\`\\`\\`json\n{\n \"core_type\": \"string,例如 en.sent.score\",\n \"overall\": 0,\n \"sub_scores\": { \"accuracy\": 0, \"integrity\": 0, \"fluency\": 0, \"rhythm\": 0 },\n \"weak_phonemes\": [\n { \"ipa\": \"string\", \"avg_score\": 0, \"occur\": 0, \"example_word\": \"string\" }\n ],\n \"omissions\": [{ \"after\": \"string\", \"missing\": \"string\" }],\n \"stress_issues\": [{ \"word\": \"string\", \"expected\": \"string\", \"actual\": \"string\" }],\n \"primary_issue_tag\": \"phoneme|stress|fluency|integrity|content|none\",\n \"next_action_hint\": \"string,10 字以内,例如 \\\"练 /θ/ 对立对\\\"\"\n}\n\\`\\`\\`\n\n## 规则\n- weak_phonemes 只收 avg_score < 70 的项,最多 5 项,按 occur 降序。\n- 不要复述 refText,不要 markdown。\n- 字段缺失时使用 null 或空数组,不要省略 key。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n \n 怎么接到 MCP 工具调用?\n
\n 以「直调 chat.completions + 动态 tools」为例:第一轮 LLM 调出 en.sent.score 工具,把工具 result(即 tool 消息内容)原样填入上面任意「诊断」模板的{' '}\n {'{mcp_response}'},作为第二轮 user 消息发回;拿到诊断结论再走第三轮,套「微练习」模板得到 JSON。三轮调用即可串起 评测 → 诊断 → 练习 全链路。\n
\n
\n\n \n
    \n
  • 音频过期:上传后 5 分钟内有效。建议在上传后 3 分钟内完成评测。
  • \n
  • 服务繁忙:使用指数退避策略重试(1s → 2s → 4s),最多 3 次。
  • \n
  • 录音中断:WebSocket 断线后代理会自动重连。如持续失败,检查网络连接和 SoX 安装。
  • \n
\n
\n\n \n
    \n
  • 优先使用流式评测:实时录音模式跳过了文件上传环节,端到端延迟比文件评测低 30-50%。
  • \n
  • 音频压缩:文件评测时,上传前将音频转为 16kHz 单声道 mp3,可减少 60-80% 的上传体积。
  • \n
  • 选择合适的工具:单词评测比段落评测快 3-5 倍。如只需单词级分数,不要用句子评测。
  • \n
  • 本地文件路径最便捷:使用 audio_file_path 参数传入本地路径,代理自动处理编码,无需手动转 Base64。
  • \n
\n
\n
\n\n {/* ══════ 服务信息 ══════ */}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
端点方法说明
/uploadPOST音频文件上传(MCP 模式文件评测使用)
/mcpPOSTMCP 模式 · JSON-RPC(Streamable HTTP)
{'/ws/audio/{session_id}'}WSMCP 模式 · 流式音频 WebSocket
/v1/functionsGETfunctioncalling 模式 · 列出全部评测函数
/v1/callPOSTfunctioncalling 模式 · 一次性评测 / 创建流式会话 / 拉取流式结果
{'/ws/eval/{session_id}'}WSfunctioncalling 模式 · 流式音频 WebSocket
/healthGET健康检查
\n
\n
\n \n
\n \n \n \n \n \n \n \n {[\n ['存储限制', '500MB', '最大音频存储空间'],\n ['最大排队', '10', '等待处理的请求数'],\n ['最大并发', '3', '同时处理的评测数'],\n ['音频有效期', '5 分钟', '上传后未评测自动过期'],\n ['文件大小限制', '50MB', '单个音频文件最大'],\n ].map(([k, v, d]) => (\n \n ))}\n \n
配置项默认值说明
{k}{v}{d}
\n
\n

\n 上表为托管侧技术默认;计费与试用/商用调用配额、并发档位以{' '}\n \n 会员套餐\n \n 说明为准,与上表独立。\n

\n
\n \n \n 当前线上版本:v1.0.0(网站未正式上线)。以下变更项为开发阶段规划记录,以正式发布公告为准。\n \n
\n {[\n { ver: 'v1.0.0', date: 'TBD', desc: '当前线上版本(网站未正式上线)' },\n ].map(l => (\n
\n {l.ver}\n {l.date}\n {l.desc}\n
\n ))}\n
\n
\n
\n\n \n );\n}\n\nexport default function DocsPage() {\n const locale = useLocale();\n return locale.startsWith('zh') ? : ;\n}\n"}, "d5b192666f386dbc7610989f2c6eb696d348b5f9": {"t": 1785765789.6910784, "n": 190302, "h": "4c05f5a612d811d1", "c": "'use client';\n\nimport { useLocale } from 'next-intl';\nimport { Link } from '@/i18n/routing';\nimport { DocsShell, type NavGroup } from './docs-shell';\nimport {\n CodeBlock,\n DocSection,\n SubDoc,\n ParamTable,\n Callout,\n FlowStep,\n ToolTable,\n} from './docs-shared';\nimport { DocsEnglishBody } from './docs-content-en';\nimport {\n BookOpen,\n Code2,\n Zap,\n FileText,\n Terminal,\n Globe,\n Mic,\n MessageSquare,\n BarChart3,\n AlertTriangle,\n Radio,\n FolderOpen,\n Workflow,\n Sparkles,\n Plug,\n Bot,\n Building2,\n Check,\n Sparkle,\n Languages,\n GraduationCap,\n Notebook,\n Gauge,\n ListChecks,\n Network,\n} from 'lucide-react';\n\n/* ─── Navigation Structure ─── */\n\nconst NAV = [\n { id: 'concept', icon: Workflow, label: 'MCP 工作原理', children: [\n { id: 'why-mcp', label: '为什么需要 MCP' },\n { id: 'scenario-walkthrough', label: '场景走查 · 6 步' },\n { id: 'dev-responsibility', label: '开发者只做两件事' },\n { id: 'integration-paths', label: '三种接入姿势' },\n ]},\n { id: 'architecture', icon: Terminal, label: '架构说明', children: [\n { id: 'arch-overview', label: '两种接入模式总览' },\n { id: 'arch-mcp', label: 'MCP 模式架构' },\n { id: 'arch-rest', label: 'functioncalling 模式架构' },\n { id: 'transport', label: '传输协议对比' },\n ]},\n { id: 'quick-start', icon: Zap, label: '快速开始', children: [\n { id: 'overview', label: '概述' },\n { id: 'requirements', label: '系统要求' },\n { id: 'install', label: '安装方式' },\n { id: 'env-vars', label: '环境变量' },\n ]},\n { id: 'config', icon: Plug, label: '接入 · 直接用(零代码)', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: '扣子(Coze)' },\n { id: 'config-coze-workflow', label: 'Coze 工作流' },\n { id: 'config-ai-workspace', label: 'AI 工作台 · 豆包 / 飞书 / WorkBuddy / 钉钉' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: '其他 MCP 客户端' },\n ]},\n { id: 'config-code', icon: Code2, label: '接入 · 编程用 MCP(SDK / 代码)', children: [\n { id: 'code-mcp-sdk', label: '① 官方 MCP 客户端库' },\n { id: 'code-agent-frameworks', label: '② LangChain / Mastra / Agents SDK' },\n { id: 'code-function-calling', label: '③ 直调 chat.completions · 动态 tools' },\n { id: 'code-selfhosted-agent', label: '④ 自研后端 Agent' },\n { id: 'llm-deepseek', label: 'DeepSeek' },\n { id: 'llm-glm', label: 'GLM(智谱)' },\n { id: 'llm-kimi', label: 'KIMI(Moonshot)' },\n { id: 'llm-doubao', label: '豆包 Seed 2.0(火山方舟)' },\n { id: 'llm-openai', label: 'OpenAI(GPT-5.1)' },\n { id: 'llm-claude', label: 'Claude(Anthropic)' },\n { id: 'llm-gemini', label: 'Gemini(Google)' },\n { id: 'llm-comparison', label: '模型对比速查' },\n ]},\n { id: 'config-rest', icon: Network, label: '接入 · 非 MCP 原生 REST(cvx_fc)', children: [\n { id: 'rest-overview', label: 'functioncalling 模式总览' },\n { id: 'rest-catalog', label: '函数目录 · GET /v1/functions' },\n { id: 'rest-oneshot', label: '一次性文件评测' },\n { id: 'rest-streaming', label: '流式评测 · 三步骤' },\n { id: 'rest-examples', label: 'JS / Android 完整示例' },\n { id: 'rest-resume', label: '断线恢复 · 兜底拉取' },\n ]},\n { id: 'eval-modes', icon: Radio, label: '评测模式', children: [\n { id: 'stream-eval', label: '实时录音评测' },\n { id: 'stream-flow', label: '流式评测流程' },\n { id: 'file-eval', label: '音频文件评测' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API 参考', children: [\n { id: 'tools-en', label: '英文评测工具' },\n { id: 'tools-cn', label: '中文评测工具' },\n { id: 'result-fields', label: '评测结果字段' },\n { id: 'error-codes', label: '错误码' },\n ]},\n { id: 'best-practices', icon: FileText, label: '最佳实践', children: [\n { id: 'prompt-templates', label: 'Prompt 模板' },\n { id: 'error-handling', label: '错误处理' },\n { id: 'performance', label: '性能优化' },\n ]},\n { id: 'service-info', icon: Globe, label: '服务信息', children: [\n { id: 'endpoints', label: '服务端点' },\n { id: 'limits', label: '服务限制' },\n { id: 'changelog', label: '更新日志' },\n ]},\n];\n\nconst NAV_EN: NavGroup[] = [\n { id: 'concept', icon: Workflow, label: 'How MCP works', children: [\n { id: 'why-mcp', label: 'Why MCP' },\n { id: 'scenario-walkthrough', label: 'Scenario · 6 steps' },\n { id: 'dev-responsibility', label: 'Two developer tasks' },\n { id: 'integration-paths', label: 'Three integration styles' },\n ]},\n { id: 'architecture', icon: Terminal, label: 'Architecture', children: [\n { id: 'arch-overview', label: 'Two integration modes' },\n { id: 'arch-mcp', label: 'MCP mode architecture' },\n { id: 'arch-rest', label: 'Function-calling architecture' },\n { id: 'transport', label: 'Transport comparison' },\n ]},\n { id: 'quick-start', icon: Zap, label: 'Quick start', children: [\n { id: 'overview', label: 'Overview' },\n { id: 'requirements', label: 'Requirements' },\n { id: 'install', label: 'Install' },\n { id: 'env-vars', label: 'Environment' },\n ]},\n { id: 'config', icon: Plug, label: 'Zero-code clients', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: 'Coze' },\n { id: 'config-coze-workflow', label: 'Coze workflows' },\n { id: 'config-ai-workspace', label: 'Enterprise AI workspaces' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: 'Other MCP clients' },\n ]},\n { id: 'config-code', icon: Code2, label: 'MCP · SDK / code integration', children: [\n { id: 'code-mcp-sdk', label: '① Official MCP SDK' },\n { id: 'code-agent-frameworks', label: '② Agent frameworks' },\n { id: 'code-function-calling', label: '③ chat.completions · dynamic tools' },\n { id: 'code-selfhosted-agent', label: '④ Custom backend agent' },\n { id: 'llm-deepseek', label: 'DeepSeek' },\n { id: 'llm-glm', label: 'GLM (Zhipu)' },\n { id: 'llm-kimi', label: 'KIMI (Moonshot)' },\n { id: 'llm-doubao', label: 'Doubao Seed 2.0 (Volcano Ark)' },\n { id: 'llm-qwen', label: 'Qwen (Alibaba)' },\n { id: 'llm-openai', label: 'OpenAI (GPT-5.1)' },\n { id: 'llm-claude', label: 'Claude (Anthropic)' },\n { id: 'llm-gemini', label: 'Gemini (Google)' },\n { id: 'llm-comparison', label: 'Model comparison' },\n ]},\n { id: 'config-rest', icon: Network, label: 'Non-MCP REST (cvx_fc)', children: [\n { id: 'rest-overview', label: 'Function-calling overview' },\n { id: 'rest-catalog', label: 'Function catalog · GET /v1/functions' },\n { id: 'rest-oneshot', label: 'One-shot file eval' },\n { id: 'rest-streaming', label: 'Streaming · 3 steps' },\n { id: 'rest-examples', label: 'JS / Android samples' },\n { id: 'rest-resume', label: 'Resume & fallback' },\n ]},\n { id: 'eval-modes', icon: Radio, label: 'Evaluation modes', children: [\n { id: 'stream-eval', label: 'Streaming mic' },\n { id: 'stream-flow', label: 'Streaming flow' },\n { id: 'file-eval', label: 'Audio files' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API reference', children: [\n { id: 'tools-en', label: 'English tools' },\n { id: 'tools-cn', label: 'Chinese tools' },\n { id: 'result-fields', label: 'Result fields' },\n { id: 'error-codes', label: 'Errors' },\n ]},\n { id: 'best-practices', icon: FileText, label: 'Best practices', children: [\n { id: 'prompt-templates', label: 'Prompt templates' },\n { id: 'error-handling', label: 'Errors & retries' },\n { id: 'performance', label: 'Performance' },\n ]},\n { id: 'service-info', icon: Globe, label: 'Service info', children: [\n { id: 'endpoints', label: 'Endpoints' },\n { id: 'limits', label: 'Limits' },\n { id: 'changelog', label: 'Changelog' },\n ]},\n];\n\n/* ─── Page(英文 / 中文拆成两个组件,避免切换语言时 Hooks 数量变化导致白屏)─── */\n\nfunction DocsPageEn() {\n return (\n \n \n \n );\n}\n\nfunction DocsPageZh() {\n return (\n \n {/* ══════ MCP 工作原理 ══════ */}\n \n\n \n

\n 大模型(GPT / Claude / Gemini / 通义千问 等)本质上是文字大脑:它擅长读和写,但天生听不到音频、打不开你的数据库、调不通第三方 API。\n

\n

\n MCP(Model Context Protocol)是一套由 Anthropic 主导、业界共同推进的开放协议,它像一根\"对讲机\":让大模型可以在需要时主动去调用外部能力(工具、数据源、服务),然后把结果接回来继续对话。\n

\n
\n
\n
\n \n 没有 MCP 的做法\n
\n
    \n
  • · 研究评测服务的 REST 文档
  • \n
  • · 自己写鉴权 / 上传 / 轮询代码
  • \n
  • · 把结果序列化后塞进 prompt
  • \n
  • · 每换一个大模型都得重写一遍
  • \n
\n
\n
\n
\n \n 用驰声 MCP 之后\n
\n
    \n
  • · 填一行 MCP Server 地址
  • \n
  • · 大模型自动发现&调用评测工具
  • \n
  • · 换任何支持 MCP 的大模型都能用
  • \n
  • · 不写一行调用代码
  • \n
\n
\n
\n \n MCP 让\"接入语音评测\"从一个\"后端工程\"变成了一个\"配置项\"。这也是为什么 Cursor、Claude Desktop、Dify、Coze、字节豆包、飞书智能助手都已经原生支持 MCP。\n \n
\n\n \n

\n 想象一个具体场景:一位开发者用 Claude 做了一款 「AI 雅思口语陪练」小程序,接入驰声语音评测 MCP。当用户发来一段录音,整个链路是这样的:\n

\n
\n \n

配置阶段(开发者 · 一次性)

\n

在 AI 后端的配置文件里填一行驰声 MCP Server 地址。大模型启动时自动发现:「我多了一个叫语音评测的工具」。

\n
\n \n

接收用户指令(终端用户)

\n

小程序用户发来一段自我介绍录音:「帮我听听,发音哪里有问题?」后端把「文字 + 录音链接」打包给大模型。

\n
\n \n

大模型自主思考(LLM · 最核心的魔法)

\n
\n 「用户让我听发音。」
\n 「但我只是文字大脑,我听不到。」
\n 「等等 —— 开发者给了我一个叫 chivox_voice_eval 的 MCP 工具!」\n
\n
\n \n

MCP 协议 · 自动调用(LLM → 驰声)

\n

大模型自动按 MCP 标准构造 tools/call 请求,把录音链接和参考文本发到驰声服务。开发者不需要写任何调用代码。

\n
\n \n

驰声服务处理(评测引擎)

\n

驰声对音频进行考试级打分,把结构化结果通过 MCP 原路返回:overall 85、/θ/ 音发音错误、流利度 88。

\n
\n \n

大模型整合并输出反馈(LLM)

\n

大模型把冷冰冰的分数翻译成温柔反馈:

\n
\n 「你的自我介绍很棒!综合 85 分 🎉 不过 think 这个词的 /θ/ 咬舌音不太标准,我们一起来练一下……」\n
\n
\n
\n \n 整条链路里,MCP 只出现在 ① 和 ④:① 让开发者一次性告诉大模型「你多了一个工具」,④ 让大模型可以自动调用它。这两步的标准化,就是 MCP 的全部价值。\n \n
\n\n \n

听起来复杂,但对开发者来说只需要两件事:

\n
\n
\n
\n 1\n 填一次 MCP 配置\n
\n

\n 在 AI 后端的配置里填入驰声 MCP Server 地址和 API Key,就这一次,以后新加评测能力完全免开发。\n

\n {`{\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"apiKey\": \"sk-••••••••••\"\n }\n}`}\n
\n
\n
\n 2\n 写一段 System Prompt\n
\n

\n 告诉大模型这个工具是做什么的、什么时候调用、结果怎么转成用户友好的反馈。\n

\n {`你是一位英语口语教练。\n当用户发来录音时:\n1. 调用 chivox_voice_eval 评分\n2. 聚焦 <70 分的音素家族\n3. 用高情商话术给出练习建议`}\n
\n
\n

\n 其余所有事情 —— 音频上传、鉴权、工具发现、调用时机、返回格式、结果整合 —— 都由 MCP 协议和大模型自己搞定。\n

\n
\n\n \n

根据你的技术栈,有三种等价的接入方式,底层都走完全相同的 MCP 协议:

\n\n {/* ── 姿势一:可视化 ── */}\n
\n
\n \n

姿势一 · 可视化拖拽(扣子 / Coze / 飞书智能助手)

\n
\n

\n 适合产品经理、运营、不写后端代码的开发者。整个过程像在手机上装 App。\n

\n
    \n
  1. 找到入口:在扣子平台的 「插件 / 工具」 配置区,点击「添加 MCP 服务」。
  2. \n
  3. 填两个字段(这也是你未来会从驰声这边拿到的):\n
    \n \n \n \n \n \n
    服务器地址https://speech-eval.site/mcp
    鉴权密钥sk-•••••••••• (由驰声分配,用于计费与识别)
    \n
    \n
  4. \n
  5. 平台自动发现能力:扣子会访问你填的地址,读取 MCP Server 自描述的\"说明书\"。瞬间明白:「这是个语音评测工具,需要传音频,会返发音分」。
  6. \n
  7. 右侧测试:在平台的聊天框里发一段语音,大模型就会自动调用工具。整个过程不需要写一行代码。
  8. \n
\n
\n\n {/* ── 姿势二:代码框架 ── */}\n
\n
\n \n

姿势二 · 代码框架配置(Dify / LangChain / 自研后端)

\n
\n

\n 适合做独立 APP / 小程序、用 Dify 或 LangChain 写 Agent 的极客开发者。核心就是往配置文件里加一段 JSON。\n

\n
    \n
  1. 打开配置文件(项目根目录下的 mcp.json 或框架指定的配置路径)。
  2. \n
  3. 在 mcpServers 下增加一个节点:\n {`{\n \"mcpServers\": {\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"env\": {\n \"API_KEY\": \"你的专属密钥\"\n }\n }\n }\n}`}\n
  4. \n
  5. 重启后端服务。大模型的底层调度器会在启动时自动连上驰声 MCP Server,把 16 种评测工具注册成随时待命的 tools。
  6. \n
  7. 触发调用:用户发来录音后,大模型看到 system prompt 的引导,自动选择合适的工具(单词/句子/段落/半开放)调用。
  8. \n
\n
\n\n {/* ── 姿势三:Function Calling 直连(分 A / B 两种做法) ── */}\n
\n
\n \n

姿势三 · 原生 Function Calling(豆包 / DeepSeek / OpenAI 兼容 API)

\n
\n

\n 适合不用任何 Agent 框架、直接调用 LLM API 的后端开发者。豆包 1.5+ / DeepSeek / GPT / Qwen 等模型都走标准 chat.completions 的 tools 参数。这里又分 A / B 两种做法,B 才是生产推荐。\n

\n\n \n 常见疑问:\"要不要手写一个 tool 定义?\"
\n — 姿势一 / 二不用(Coze、Dify、火山方舟控制台、Claude Desktop 会自动从 MCP Server 拉工具列表)。
\n — 姿势三看你选 A 还是 B:A 要手写,B 用 MCP 客户端库自动拉。\n
\n\n {/* ── 3-A:手写 tool schema ── */}\n
\n
\n

3-A · 手写 tool schema(最快验证,不推荐生产)

\n 快速 Demo\n
\n

\n 自己写一段 JSON Schema 告诉豆包\"有个工具叫 xxx,参数长这样\",豆包返回 tool_call 后你再手动去调驰声 MCP。缺点:驰声有 16 个评测工具,你每加一个题型都要改代码。\n

\n {`import os, json\nfrom openai import OpenAI\n\nclient = OpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv('ARK_API_KEY'),\n)\n\n# ─── 手写一段 tool schema(不推荐:16 个工具就要写 16 段)───\ntools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": \"en_word_eval\",\n \"description\": \"英语单词发音评测。当用户让你评价英语发音并提供录音链接时调用。\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"audio_url\": {\"type\": \"string\", \"description\": \"录音 URL\"},\n \"reference_text\": {\"type\": \"string\", \"description\": \"参考文本,如 Apple\"},\n },\n \"required\": [\"audio_url\", \"reference_text\"]\n }\n }\n}]\n\nresp = client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,拿到评测结果后温柔地反馈,不要直接报分数。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n)\n\nmsg = resp.choices[0].message\nif msg.tool_calls:\n args = json.loads(msg.tool_calls[0].function.arguments)\n # ↓↓↓ 这里手动调驰声 MCP,再把结果回填给豆包做第二趟 ↓↓↓\n # result = requests.post(\"https://speech-eval.site/mcp\", json={...})`}\n
\n\n {/* ── 3-B:MCP 自动发现 ── */}\n
\n
\n

\n 3-B · 用 MCP 客户端库自动发现 \n

\n 生产推荐\n
\n

\n 启动时连上驰声 MCP Server,调一次 tools/list,把 16 个评测工具自动转成 Function Calling 的 tools 格式。驰声加新工具,你代码不用改。这才是 MCP 协议的真正价值。\n

\n {`import asyncio, os\nfrom openai import AsyncOpenAI\nfrom mcp import ClientSession\nfrom mcp.client.streamable_http import streamablehttp_client\n\nclient = AsyncOpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv(\"ARK_API_KEY\"),\n)\n\nasync def main():\n # ─── 1. 连驰声 MCP Server,自动拉取全部 16 个工具 ───\n async with streamablehttp_client(\n \"https://speech-eval.site/mcp\",\n headers={\"Authorization\": f\"Bearer {os.getenv('CHIVOX_KEY')}\"},\n ) as (read, write, _):\n async with ClientSession(read, write) as session:\n await session.initialize()\n mcp_tools = (await session.list_tools()).tools # ← 一行拿到全部工具\n\n # ─── 2. MCP schema → OpenAI Function Calling schema ───\n tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema, # MCP 直接给 JSON Schema\n }\n } for t in mcp_tools]\n\n # ─── 3. 正常调豆包,tools 由 MCP 动态注入 ───\n resp = await client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,收到评测结果后温柔反馈。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n )\n\n # ─── 4. 折返跑:豆包选好工具后,直接走 MCP 调驰声 ───\n msg = resp.choices[0].message\n if msg.tool_calls:\n call = msg.tool_calls[0]\n result = await session.call_tool(\n call.function.name,\n arguments=__import__(\"json\").loads(call.function.arguments),\n )\n # 把 result 回填给豆包做第二趟 chat.completions 即可\n\nasyncio.run(main())`}\n

\n 想要更省心?直接用 官方 mcp python sdk、mcp-use、openai-agents,或火山官方 Arkitect 高代码 SDK,它们都把上面这段\"MCP → Function Calling\"的桥接封装好了。\n

\n
\n
\n\n \n 三种姿势走的是完全相同的 MCP 协议,能力完全等价。选型建议:产品经理 / 原型验证用姿势一(Coze 填表单);AI 客户端用户用姿势二(Cursor / Claude Desktop 填 mcp.json);后端生产服务用姿势三-B(MCP 客户端库自动发现工具,不要手写 tool schema)。\n \n
\n\n
\n\n {/* ══════ 架构说明 ══════ */}\n \n\n \n

驰声语音评测对外提供两条并行入口,底层指向同一个评测引擎,但面向不同的客户端环境,按能力选其一即可:

\n\n
\n
\n

\n \n MCP 模式(推荐首选)\n

\n
    \n
  • • JSON-RPC 2.0 · Streamable HTTP / stdio
  • \n
  • • 所有支持 MCP 的 IDE / 桌面 AI / Agent 框架 零代码即用
  • \n
  • • 工具列表自动注入,新增题型业务侧不用改
  • \n
  • • 本地代理 chivox-local-mcp 支持麦克风实时录音
  • \n
\n

典型客户端:Cursor / Claude Desktop / Coze / Dify / LangChain / 自研后端 Agent

\n
\n
\n

\n \n functioncalling 模式(非 MCP · cvx_fc)\n

\n
    \n
  • • OpenAI function-calling 风格 · 纯 REST + WebSocket
  • \n
  • • 不依赖任何 MCP SDK,普通 HTTP 客户端即可打
  • \n
  • • 内置 resume_token 断线续播、intermediate 中间结果、backpressure 反压
  • \n
  • • 为不能 / 不想引入 MCP 的客户端环境保留兜底通道
  • \n
\n

典型客户端:原生 Android / iOS / Flutter、微信 / 支付宝小程序、老版本 Java / PHP 后端

\n
\n
\n\n

怎么选?

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
你的客户端环境建议
Cursor / Claude Desktop / 各类 AI IDE 能装 MCPMCP 模式
Python / Node / Java 后端能引入 MCP SDKMCP 模式
Coze / Dify / n8n 等可视化平台MCP 模式
原生 Android / iOS App,想直接打 HTTP + WSfunctioncalling 模式
微信 / 支付宝 / 抖音小程序functioncalling 模式
老系统 / 封闭运行时,不想引入 MCP 依赖functioncalling 模式
\n
\n \n 同一个会话二选一、不要混用:MCP 的 /ws/audio/ 和 functioncalling 的 /ws/eval/ 属于不同的会话 ID 空间。\n \n
\n\n \n

MCP 模式下有两种部署形态,底层均走 JSON-RPC 2.0,区别只在客户端离服务端有没有一层本地代理:

\n\n

形态 A · 远程直连(零代码)

\n

适合 Cursor / Coze / Dify / n8n 等支持 Streamable HTTP 的客户端,无本地依赖。

\n
\n
\n

AI 客户端

\n

Cursor / Coze /
Dify / n8n …

\n
\n
\n

⇄

\n

Streamable HTTP
JSON-RPC 2.0

\n
\n
\n

驰声 MCP Server

\n

/mcp · /ws/audio
评测引擎

\n
\n
\n\n

形态 B · 本地代理(支持麦克风实时录音)

\n

适合 Claude Desktop / Claude Code 等以 stdio 挂载 MCP 的客户端,需要本地实时录音时走这条路径。

\n
\n
\n

AI 客户端

\n

Claude Desktop /
Claude Code

\n
\n
\n

⇄

\n

stdio

\n
\n
\n

chivox-local-mcp

\n

本地代理 · SoX 录音

\n
\n
\n

⇄

\n

HTTP / WS

\n
\n
\n

Remote Chivox

\n

MCP Server
评测引擎

\n
\n
\n\n

标准数据流

\n
    \n
  1. initialize → 协商协议版本与能力
  2. \n
  3. tools/list → 拉取 16 个评测工具的 JSON Schema
  4. \n
  5. 文件模式:tools/call → 服务端执行评测 → 返回 JSON-RPC 响应
  6. \n
  7. 实时模式:create_stream_session → 走 /ws/audio/{'{session_id}'} 推流 → stream_eval_result 收结构化评分
  8. \n
\n\n

原始 JSON-RPC 请求示例(自建客户端可直接抄)

\n

\n 如果你不使用官方 MCP SDK 而是直接通过 POST /mcp 自己拼 JSON-RPC 2.0 报文,最小可用的三条请求如下。所有请求均需携带 Authorization: Bearer <your_api_key>。\n

\n\n

① 初始化 · initialize

\n {`{\n \"jsonrpc\": \"2.0\",\n \"id\": 1,\n \"method\": \"initialize\",\n \"params\": {\n \"protocolVersion\": \"2024-11-05\",\n \"capabilities\": {},\n \"clientInfo\": { \"name\": \"my-client\", \"version\": \"1.0.0\" }\n }\n}`}\n

成功后服务端返回协议版本、服务端能力、服务端信息,此后方可调用其他方法。

\n\n

② 拉取工具清单 · tools/list

\n {`{\n \"jsonrpc\": \"2.0\",\n \"id\": 2,\n \"method\": \"tools/list\",\n \"params\": {}\n}`}\n

返回全部 16 个评测工具(英 10 + 中 6)+ 2 个流式工具,含名字、描述、参数 JSON Schema。客户端应缓存此响应,后续按需展示 / 桥接给 LLM。

\n\n

③ 调用工具 · tools/call

\n {`{\n \"jsonrpc\": \"2.0\",\n \"id\": 3,\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"en_word_eval\",\n \"arguments\": {\n \"ref_text\": \"hello\",\n \"audio_base64\": \"\",\n \"accent\": 2,\n \"rank\": 100\n }\n }\n}`}\n

\n 成功响应放在 result.content[0].text(JSON 字符串形式,内部就是评测结果结构);失败则返回 error.code + error.message。\n

\n\n \n 用 Python / TypeScript 官方 MCP SDK 的用户不需要关心以上 JSON-RPC 细节——SDK 已经封装好 session.initialize() / session.list_tools() / session.call_tool()。这里仅供裸协议实现或排障时参考。\n \n
\n\n \n

没有代理、没有 SDK,客户端 ↔ 服务端只有两条链路:一条 REST 管会话 / 文件评测,一条 WebSocket 推音频帧。

\n\n
\n
\n

客户端

\n

原生 App / 小程序 /
老版后端 / 纯前端

\n
\n
\n

⇄

\n

HTTP REST
/v1/call · /v1/functions

\n
\n
\n

cvx_fc 服务

\n

function-calling 网关
评测引擎

\n
\n
\n

⇄

\n

WebSocket
/ws/eval/{id}

\n
\n
\n

客户端推流

\n

麦克风 / 分片缓冲

\n
\n
\n\n

三条典型数据流

\n
\n
\n

a. 一次性文件评测

\n

POST /v1/call(audio_url 或 audio_base64) → 同步返回评分

\n
\n
\n

b. 流式实时评测

\n

POST /v1/call → start_stream_eval → 拿 ws_url → 连 /ws/eval/{id} → 推 PCM → 收 intermediate / backpressure → 发 stop → 收 result

\n
\n
\n

c. 断线恢复 + 兜底拉取

\n

网络断开 60 秒内 → 用 resume_token 重连续播;彻底失败 → POST /v1/call → get_stream_result 兜底

\n
\n
\n\n

特色能力

\n
    \n
  • resume_token — 网络抖动 60 秒内可无缝续播,服务端挂起会话状态
  • \n
  • intermediate 帧 — 边推边吐部分结果,前端可做实时波形 / 分数涂色
  • \n
  • backpressure 反馈 — 服务端主动下发 suggested_interval_ms,客户端按建议降速
  • \n
  • 结构化错误码 — SESSION_EXPIRED / INVALID_STATE / … 便于客户端写重试逻辑
  • \n
\n

详细的接入示例见下文 「接入 · 非 MCP 原生 REST」 大节。

\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
维度MCP 模式functioncalling(cvx_fc)
协议JSON-RPC 2.0REST + WebSocket
入口路径POST /mcpPOST /v1/call
列出工具tools/listGET /v1/functions
调用工具tools/callPOST /v1/call + name
流式音频 WS{'/ws/audio/{session_id}'}{'/ws/eval/{session_id}'}
本地 stdio 代理支持(chivox-local-mcp)不适用
断线重连客户端 SDK 自动重连resume_token(60s 挂起)
中间结果stream_eval 回调intermediate 帧
背压反馈—backpressure 帧
客户端依赖MCP SDK(官方 / 框架)仅 HTTP + WS 客户端
\n
\n
\n
\n\n {/* ══════ 快速开始 ══════ */}\n \n\n \n

chivox-local-mcp 是驰声语音评测的 MCP 本地代理,通过 Model Context Protocol 将远程驰声评测服务桥接到本地,让 AI 助手(Claude Desktop、Claude Code、Cursor 等)直接调用语音评测能力。

\n

它支持两种评测模式,覆盖从即时交互到批量处理的全部场景:

\n
\n
\n
\n \n 实时录音评测\n
\n

通过麦克风边录边评,音频以 WebSocket 流式推送,无需生成中间文件,延迟更低、体验更佳。

\n
\n
\n
\n \n 音频文件评测\n
\n

支持本地文件路径、Base64 编码、URL 三种输入,适合已有音频的批量评测场景。

\n
\n
\n 当前支持 16 种评测工具:英文 10 种(单词、句子、段落、纠音、自然拼读、口语选择、半开放题等)+ 中文 6 种(汉字、拼音、词句、段落、有限分支、AI Talk)。\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n
依赖版本说明
Node.js{'>'}= 18运行时必须
SoXany仅实时录音功能需要(处理麦克风音频流)
\n
\n

安装 SoX(仅在使用实时录音时需要):

\n {`# macOS\nbrew install sox\n\n# Ubuntu / Debian\nsudo apt-get install sox`}\n
\n\n \n

方式一:npm 全局安装(推荐)

\n {`npm install -g chivox-local-mcp`}\n\n

方式二:npx 免安装运行

\n {`MCP_REMOTE_URL=http://your-server:8080 npx chivox-local-mcp`}\n\n

方式三:从源码构建

\n {`git clone https://git.chivox.com/CLOUD_DEV/cvx_local_mcp.git\ncd cvx_local_mcp\nbash scripts/build.sh`}\n
\n\n \n \n \n
\n\n {/* ══════ 接入 · 直接用(零代码) ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 不用写代码、不用装 SDK,只在客户端的「MCP 配置」或「扩展」里填一段 JSON / URL
  • \n
  • 保存后 LLM 自动发现 16 个评测工具,并在对话 / Agent 中自主调用
  • \n
  • 覆盖 IDE 编程助手、桌面 AI 客户端、企业 AI 工作台、可视化 Bot / 工作流平台四大生态
  • \n
\n
\n\n\n \n
    \n
  1. 打开 Cursor 设置(Cmd + ,)
  2. \n
  3. 左侧选择 MCP(或搜索 "MCP")
  4. \n
  5. 点击 Add new MCP server
  6. \n
  7. 填写配置并保存:
  8. \n
\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n}`}\n Cursor 使用远程 Streamable HTTP 模式直连,无需安装本地代理。如需实时录音功能,请使用下方 Claude Desktop 的本地代理配置。\n
\n\n \n

编辑配置文件(macOS:~/Library/Application Support/Claude/claude_desktop_config.json):

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"chivox-local-mcp\",\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\",\n \"MCP_API_KEY\": \"your-api-key\"\n }\n }\n }\n}`}\n

如果是从源码构建:

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/cvx_local_mcp/dist/index.js\"],\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\"\n }\n }\n }\n}`}\n Claude Desktop 使用本地代理模式(stdio),支持实时录音评测。本地代理会自动桥接远程服务。\n
\n\n \n {`# npm 全局安装后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 chivox-local-mcp\n\n# 源码构建后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 node /path/to/cvx_local_mcp/dist/index.js`}\n \n\n \n

除了 Cursor 和 Claude Code,主流的 AI 编程 IDE 都原生支持 MCP。以下客户端使用完全一致的 Streamable HTTP 配置,区别只在配置入口:

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
客户端配置入口备注
Windsurf (Codeium)Settings → Cascade → MCP Servers直接贴下方 JSON
Zed~/.config/zed/settings.json 的 context_serversAssistant Panel 自动发现
Continue (VS Code / JetBrains)config.yaml 的 mcpServersv0.9+ 支持
通义灵码 / CodeGeeX / 文心快码插件设置 → MCP 服务2026 Q1 起陆续支持
Cline (原 Claude Dev)MCP Servers 面板 → 编辑配置VS Code 扩展
\n
\n {`{\n \"mcpServers\": {\n \"chivox-speech-eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n }\n }\n}`}\n 所有 IDE 类客户端都走远程 Streamable HTTP,零本地依赖。需要实时录音才需切到 Claude Desktop 的本地代理模式。\n
\n\n \n

扣子(Coze)是字节跳动推出的 AI 应用开发平台,支持通过 MCP 扩展为 Agent 赋予外部工具能力。接入驰声语音评测后,你可以构建口语练习 Bot、发音诊断助手等应用。

\n

方式一:扣子空间 MCP 扩展(推荐)

\n
    \n
  1. 打开 扣子空间(space.coze.cn)
  2. \n
  3. 在对话框下方点击 「添加扩展」
  4. \n
  5. 选择 「自定义」 标签,点击添加新的 MCP 服务
  6. \n
  7. 填入以下配置信息:
  8. \n
\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
名称chivox-speech-eval
传输类型streamable-http
URLhttps://speech-eval.site/mcp
\n
\n
    \n
  1. 保存后,在对话中输入 「帮我评测这段英文发音」 即可触发 Agent 调用
  2. \n
\n 添加 MCP 扩展后,扣子空间的 Agent 会自动识别并调用评测工具。你可以在 Agent 的思考过程中看到具体的工具调用细节。\n\n

方式二:在 Coze 开发平台的 Bot 中使用

\n
    \n
  1. 进入 Coze 开发平台,创建或编辑 Bot
  2. \n
  3. 在 Bot 的 「插件」 或 「工具」 面板中,添加 MCP 工具
  4. \n
  5. 选择 Streamable HTTP 类型,填入 URL:https://speech-eval.site/mcp
  6. \n
  7. Bot 将自动发现所有可用的评测工具(如 evaluate_english_word 等)
  8. \n
  9. 在 Bot 的人设提示词中,添加语音评测相关的引导语
  10. \n
\n {`你是一位专业的英语口语教练。当用户上传音频并请求评测时:\n1. 使用 evaluate_english_word / evaluate_english_sentence 等工具进行评测\n2. 根据评测结果(overall、accuracy、fluency 等分数)给出专业分析\n3. 针对得分较低的维度提供具体改进建议\n4. 鼓励用户持续练习`}\n
\n\n \n

如果你需要在 Coze 工作流中集成语音评测能力,可以通过 HTTP Request 节点调用评测 API:

\n\n

步骤 1:上传音频

\n

在工作流中添加一个 HTTP Request 节点,配置如下:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
配置项值
方法POST
URLhttps://speech-eval.site/upload
Content-Typeaudio/mp3
Body音频文件二进制数据
\n
\n

响应中获取 {'{{audioId}}'},传递给下一步。

\n\n

步骤 2:调用评测

\n

添加第二个 HTTP Request 节点,通过 MCP 接口调用评测工具:

\n {`{\n \"jsonrpc\": \"2.0\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"evaluate_english_sentence\",\n \"arguments\": {\n \"audioId\": \"{{audioId}}\",\n \"sentence\": \"{{ref_text}}\"\n }\n },\n \"id\": 1\n}`}\n\n

步骤 3:处理结果

\n

评测结果通过 JSON 格式返回,可使用 Coze 的 代码节点 或 LLM 节点 对结果进行解析和二次处理(如生成学习建议、计算进步趋势等)。

\n\n 工作流方式适合需要固定流程的场景(如批量评测、定时任务、与其他系统联动)。如果是交互式场景,推荐使用上方的 MCP 扩展方式,Agent 会自动选择合适的工具。\n\n
\n

完整工作流示意

\n
\n 用户输入音频\n →\n HTTP: 上传音频\n →\n HTTP: 调用评测\n →\n LLM: 分析结果\n →\n 输出反馈\n
\n
\n
\n\n \n

这一类是面向「上班族」的企业 / 日常 AI 助手,产品形态是个聊天框 + 插件市场 / 扩展面板。接入后,员工在 App 里打字「帮我评一下这段录音」就能自动触发驰声评测,不用写任何代码。

\n\n
\n
\n

豆包(Doubao)App / 桌面版

\n

字节跳动官方 AI 助手,2026 年起桌面版支持 MCP 扩展。

\n
    \n
  1. 桌面版设置 → 「智能体扩展」 → 添加 MCP 服务
  2. \n
  3. 类型选 streamable-http,URL 填 https://speech-eval.site/mcp
  4. \n
  5. 对话中直接说「帮我评测」即可自动调用
  6. \n
\n
\n\n
\n

飞书智能伙伴(My AI)

\n

飞书企业 AI,支持以 MCP / Function Calling 挂载外部工具给团队 Bot。

\n
    \n
  1. 飞书开发者后台 → 创建应用 → 「AI 能力 / 智能伙伴」
  2. \n
  3. 在「工具」中选 外部 MCP 服务,填入上方 URL
  4. \n
  5. 把智能伙伴拉进群聊,@ 它提交音频即可评测
  6. \n
\n
\n\n
\n

WorkBuddy / 企业智能助手

\n

字节 WorkBuddy、腾讯会议 AI、企业微信智能助手等企业 AI 工作台场景。

\n
    \n
  1. 在工作台的「技能 / 扩展」后台新增一个 MCP 连接器
  2. \n
  3. 传输协议选 Streamable HTTP,地址填 https://speech-eval.site/mcp
  4. \n
  5. 把技能发布到指定部门 / 群组,HR、培训、销售口语陪练场景即可直接用
  6. \n
\n
\n\n
\n

钉钉 AI 助理 / 通义千问 App

\n

阿里生态:钉钉 AI 助理支持自定义插件,通义 App 可通过「AI 工具箱」挂载 MCP。

\n
    \n
  1. 钉钉开发者后台 → AI 助理 → 「插件开发 / MCP 接入」
  2. \n
  3. 选 HTTP Streamable,填入驰声 MCP URL 并开启鉴权(可选)
  4. \n
  5. 在钉钉群 @AI 助理上传音频,自动返回评测卡片
  6. \n
\n
\n
\n\n 典型场景 · 小龙虾们的共同剧本:销售口语陪练 → 外语培训 → 主持 / 播音岗位考核 → K12 英语作业批改 → 客服话术复盘。这些「上班族 AI 工作台」接入驰声 MCP 后,员工 / 学员只要对着话筒说话,AI 就能自动打分并给出个性化改进建议,运营 / 培训 / 教研团队零开发即可上线。\n
\n\n \n

如果你需要把语音评测编排进多步业务流(例如:学员录音 → 评测 → 生成错题集 → 推送到 CRM),可视化工作流平台比聊天 Bot 更合适。

\n\n
\n
\n

Dify

\n

开源 LLMOps,v0.15+ 原生 MCP 工具。

\n
    \n
  • 「工具」→「自定义 MCP」→ 填 URL
  • \n
  • 在 Chatflow / Workflow 节点里直接拖用
  • \n
\n
\n
\n

n8n

\n

工作流自动化,用 MCP Client 节点。

\n
    \n
  • 添加 MCP Client 节点
  • \n
  • Transport 选 HTTP Stream,URL 贴驰声地址
  • \n
  • Tool 下拉自动列出 16 个评测能力
  • \n
\n
\n
\n

Flowise / LangFlow

\n

可视化 LangChain Agent 编排。

\n
    \n
  • 拖出 MCP Tool 节点
  • \n
  • 连到 AgentExecutor 即可
  • \n
\n
\n
\n\n 可视化平台的好处是流程可追溯、可回放,适合教育机构 / 培训部门做批量评测 + 报表导出;缺点是单步延迟略高于直接 MCP 调用,对延迟敏感的交互场景建议用 Cursor / Claude Desktop 直连。\n
\n\n \n

任何遵循 MCP 协议的客户端都可以接入,统一使用以下配置:

\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
传输类型streamable-http
URLhttps://speech-eval.site/mcp
鉴权(可选)Header:Authorization: Bearer <MCP_API_KEY>
\n
\n

还没找到你用的客户端?任何支持 Model Context Protocol 的终端都通用。找不到入口?下一小节「编程用 MCP」里用 SDK 直接接即可。

\n
\n
\n\n {/* ══════ 接入 · 编程用 MCP ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 你在写一段真正的后端服务:一个 Agent Worker、一个 API、一个自动化脚本
  • \n
  • 业务里的「语音评测」是其中一个步骤,需要由代码 决定何时调用、如何解析结果
  • \n
  • 四种主流写法:① 官方 MCP 客户端库 → ② Agent 框架自动桥接 → ③ 直调 chat.completions + tools → ④ 把 MCP Client 嵌进业务后端
  • \n
  • 如果客户端环境不能引入 MCP SDK(原生 App / 小程序 / 老系统),请跳转下一大节 「接入 · 非 MCP 原生 REST(cvx_fc)」
  • \n
\n

💡 强烈推荐①或②:驰声有 16 个评测工具,让 MCP 自动注入 tool schema,每新增一个题型不用改一行业务代码。

\n
\n\n \n

最底层、也最推荐的方式。由 Anthropic 官方维护,一次连接自动拿到全部工具的 JSON Schema,然后交给任意 LLM。

\n\n

Python:mcp

\n {`# pip install mcp openai\nimport asyncio, os\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nMCP_URL = \"https://speech-eval.site/mcp\"\nllm = OpenAI(api_key=os.getenv(\"DOUBAO_KEY\"),\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\") # 豆包 / DeepSeek / OpenAI 同构\n\nasync def main(audio_id: str, ref: str):\n async with streamablehttp_client(MCP_URL) as (reader, writer, _):\n async with ClientSession(reader, writer) as sess:\n await sess.initialize()\n\n tools = await sess.list_tools()\n openai_tools = [{\n \"type\": \"function\",\n \"function\": {\"name\": t.name, \"description\": t.description,\n \"parameters\": t.inputSchema},\n } for t in tools.tools]\n\n resp = llm.chat.completions.create(\n model=\"doubao-1-5-pro-32k\",\n messages=[{\"role\": \"user\",\n \"content\": f\"帮我评测 audioId={audio_id},参考文本:{ref}\"}],\n tools=openai_tools,\n )\n\n for call in resp.choices[0].message.tool_calls or []:\n result = await sess.call_tool(call.function.name,\n arguments=eval(call.function.arguments))\n print(call.function.name, \"→\", result.content[0].text[:200])\n\nasyncio.run(main(\"abc123\", \"I think therefore I am\"))`}\n\n

TypeScript / Node.js:@modelcontextprotocol/sdk

\n {`// npm i @modelcontextprotocol/sdk openai\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport OpenAI from \"openai\";\n\nconst mcp = new Client({ name: \"chivox-biz\", version: \"1.0.0\" });\nawait mcp.connect(new StreamableHTTPClientTransport(new URL(\"https://speech-eval.site/mcp\")));\n\nconst { tools } = await mcp.listTools();\nconst openai = new OpenAI({ apiKey: process.env.DEEPSEEK_KEY, baseURL: \"https://api.deepseek.com/v1\" });\n\nconst resp = await openai.chat.completions.create({\n model: \"deepseek-chat\",\n messages: [{ role: \"user\", content: \"评测 audioId=abc123, 参考 I think therefore I am\" }],\n tools: tools.map(t => ({ type: \"function\", function: {\n name: t.name, description: t.description, parameters: t.inputSchema\n }})),\n});\n\nfor (const call of resp.choices[0].message.tool_calls ?? []) {\n const r = await mcp.callTool({ name: call.function.name,\n arguments: JSON.parse(call.function.arguments) });\n console.log(call.function.name, r.content);\n}`}\n 这种写法 LLM 供应商可换(豆包 / DeepSeek / GPT / Qwen / Moonshot),工具自动更新(驰声新增题型无需改业务代码),适合生产后端。\n
\n\n \n

如果项目已经在用 Agent 框架,几行 adapter 就能把驰声 MCP 塞进去,框架本身会接管 tool-calling 循环、重试、日志。

\n\n
\n
\n

LangChain / LangGraph(Python)

\n {`# pip install langchain-mcp-adapters langgraph\nfrom langchain_mcp_adapters.client import MultiServerMCPClient\nfrom langgraph.prebuilt import create_react_agent\n\nclient = MultiServerMCPClient({\n \"chivox\": {\n \"transport\": \"streamable_http\",\n \"url\": \"https://speech-eval.site/mcp\",\n }\n})\ntools = await client.get_tools()\n\nagent = create_react_agent(\"openai:gpt-4o-mini\", tools)\nresult = await agent.ainvoke({\"messages\":\n [(\"user\", \"评测 audioId=abc123 参考 think\")]})\nprint(result[\"messages\"][-1].content)`}\n
\n\n
\n

Mastra(TypeScript)

\n {`// npm i @mastra/core @mastra/mcp\nimport { MCPClient } from \"@mastra/mcp\";\nimport { Agent } from \"@mastra/core/agent\";\nimport { openai } from \"@ai-sdk/openai\";\n\nconst mcp = new MCPClient({ servers: {\n chivox: { url: new URL(\"https://speech-eval.site/mcp\") }\n}});\n\nexport const speechCoach = new Agent({\n name: \"speech-coach\",\n instructions: \"你是口语教练,用 chivox 工具评测并给改进建议。\",\n model: openai(\"gpt-4o-mini\"),\n tools: await mcp.getTools(),\n});`}\n
\n\n
\n

OpenAI Agents SDK(Python)

\n {`# pip install openai-agents\nfrom agents import Agent, Runner\nfrom agents.mcp import MCPServerStreamableHttp\n\nchivox = MCPServerStreamableHttp(\n params={\"url\": \"https://speech-eval.site/mcp\"},\n name=\"chivox-speech-eval\",\n)\n\nasync with chivox:\n agent = Agent(name=\"coach\",\n instructions=\"专业口语教练\",\n mcp_servers=[chivox])\n r = await Runner.run(agent, \"评测 audioId=abc123\")\n print(r.final_output)`}\n
\n\n
\n

LlamaIndex / AutoGen / CrewAI

\n

这些框架都有官方或社区 MCP adapter,用法与上述类似:

\n
    \n
  • LlamaIndex:llama-index-tools-mcp
  • \n
  • AutoGen:autogen-ext[mcp]
  • \n
  • CrewAI:crewai-tools 的 MCPServerAdapter
  • \n
  • Spring AI(Java):spring-ai-mcp-client
  • \n
\n
\n
\n
\n\n \n

\n DeepSeek、GLM(智谱)、KIMI(Moonshot)、豆包(火山方舟)、千帆、DashScope 等若提供 OpenAI 兼容的 HTTP API,接入驰声 MCP 的套路一致:用 MCP 客户端拉取工具列表 → 转为{' '}\n tools → 模型决策 tool_calls → MCP 执行并回填 → 再让模型生成诊断话术。\n

\n
\n
\n ① MCP list_tools()\n →\n ② 转 OpenAI tools 格式\n →\n ③ LLM 决策 tool_calls\n →\n ④ MCP call_tool()\n →\n ⑤ 评测结果回填 → LLM 诊断\n
\n
\n 各厂商仅需替换 base_url 与 api_key,驰声 MCP 与 tools 桥接代码可原样复用。\n\n

先上传音频,拿到 audioId

\n

文件评测工具通常需要 audioId(或路径参数,视工具而定)。下面是用 HTTP 上传的最小示例:

\n {`import requests\n\nwith open('audio.mp3', 'rb') as f:\n r = requests.post(\n 'https://speech-eval.site/upload',\n data=f,\n headers={'Content-Type': 'audio/mp3'}\n )\n\nresult = r.json()\nprint(f\"audioId: {result['audioId']}\")\nprint(f\"size: {result['size']} bytes\")\nprint(f\"expires: {result['expiresIn']}\")`}\n {`const fs = require('fs');\n\nconst audioData = fs.readFileSync('audio.mp3');\n\nconst res = await fetch('https://speech-eval.site/upload', {\n method: 'POST',\n headers: { 'Content-Type': 'audio/mp3' },\n body: audioData,\n});\n\nconst result = await res.json();\nconsole.log('audioId:', result.audioId);`}\n\n

再以豆包为例:MCP 动态 tools + chat.completions 折返跑

\n

当你用的 LLM SDK 还没有原生 MCP 支持(比如老版本的火山方舟 / 百度千帆 / 通义 DashScope),退化方案是:用 MCP 客户端一次性拉到 tool schema,然后按 OpenAI Function Calling 格式喂给 LLM。

\n {`# 适用:豆包(火山方舟)/ DeepSeek / Qwen / Moonshot / GLM 等 OpenAI 兼容 API\n# 核心思路:MCP 列工具 → 转 OpenAI tools → LLM 决策 → MCP 执行 → 回填\n\nasync with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n\n # ① 用 MCP 拉到的 schema 自动转 OpenAI 格式\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 喂给豆包\n messages = [{\"role\": \"user\", \"content\": \"评测一下 audioId=abc123\"}]\n resp = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages, tools=oa_tools,\n )\n\n # ③ LLM 回 tool_calls → 折返跑到 MCP 执行\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for c in msg.tool_calls:\n result = await mcp.call_tool(\n c.function.name, arguments=json.loads(c.function.arguments))\n messages.append({\"role\": \"tool\", \"tool_call_id\": c.id,\n \"content\": result.content[0].text})\n # ④ 再喂一轮,让豆包根据评测结果产出自然语言诊断\n final = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages)\n print(final.choices[0].message.content)`}\n 千万别手写 tool schema!驰声共 16 个评测工具(英文 10 + 中文 6),每个工具参数较多,手写既容易错也难维护。一定用 MCP list_tools() 动态拿。\n
\n\n \n

大部分落地场景其实是:你已有一个业务后端(教育 SaaS / 培训系统 / 客服平台),只需要新增一个「语音评测」能力。推荐架构:

\n\n
\n
\n 前端录音 / 上传\n →\n 业务后端\n →\n MCP Client(常驻连接)\n →\n 驰声 MCP\n ↘\n LLM(诊断 / 出题)\n
\n
\n\n

FastAPI 示例(生产最小骨架)

\n {`from fastapi import FastAPI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\nfrom contextlib import asynccontextmanager\n\nmcp_session: ClientSession | None = None\n\n@asynccontextmanager\nasync def lifespan(app):\n global mcp_session\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as s:\n await s.initialize()\n mcp_session = s\n yield\n mcp_session = None\n\napp = FastAPI(lifespan=lifespan)\n\n@app.post(\"/api/evaluate\")\nasync def evaluate(audio_id: str, ref_text: str):\n # 直接选一个最合适的工具执行(不经 LLM,延迟最低)\n r = await mcp_session.call_tool(\"evaluate_english_sentence\",\n {\"audioId\": audio_id, \"sentence\": ref_text})\n return {\"result\": r.content[0].text}`}\n\n 关键优化:① MCP 连接在 lifespan 里做成长连接,不要每次请求都重连;② 对延迟敏感的场景可以「跳过 LLM 直接调 tool」,把 LLM 放到「生成诊断报告」那一步。\n
\n\n
\n

下面是 ① ~ ④ 中第③种「直调 chat.completions」按主流 LLM 厂商的细化写法

\n

各家 SDK / base_url / 鉴权写法略有差别,挑你当前用的那一家看即可;驰声 MCP 侧代码不用改。

\n
\n\n \n

\n DeepSeek 提供与 OpenAI 完全兼容的 API,当前最新模型为 DeepSeek-V3.2(2025 年 12 月发布,首个把\"思考 + 工具调用\"原生融合的模型)。\n 通过 deepseek-chat 进入非思考模式,\n 通过 deepseek-reasoner 进入思考模式,\n 两种模式均支持 Function Calling,128K 上下文。\n

\n\n

环境准备

\n {`DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# DeepSeek 客户端(OpenAI 兼容)\nclient = OpenAI(\n api_key=os.environ[\"DEEPSEEK_API_KEY\"],\n base_url=\"https://api.deepseek.com/v1\",\n)\n\nasync def evaluate_with_deepseek(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # ① 拉取驰声 MCP 工具列表\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 调用 DeepSeek,让它选择合适的评测工具\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段英文录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"deepseek-chat\", # 或 deepseek-reasoner\n messages=messages,\n tools=oa_tools,\n )\n\n # ③ 执行 tool_calls\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n # ④ 让 DeepSeek 根据评测结果生成自然语言诊断\n final = client.chat.completions.create(\n model=\"deepseek-chat\",\n messages=messages,\n )\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_deepseek(\"audio_abc123\", \"Hello, nice to meet you.\"))`}\n \n 选型建议(V3.2):日常评测诊断用 deepseek-chat,速度快、token 消耗低;\n 需要深度分析(错误归因 / 个性化练习路径)时用 deepseek-reasoner,\n V3.2 起思考模式也能在思维链中调用工具,可以一次性完成\"调评测 → 思考 → 出诊断\",无需再切回 V3 做工具调用。\n \n
\n\n \n

\n 智谱 AI 当前最新旗舰为 GLM-5 / GLM-5.1(2026 年 2 月发布,744B-A40B MoE,200K 上下文,对标 Claude Opus 4.5),\n 以及上一代 GLM-4.7、GLM-4.6。\n 此外保留 glm-4-flash(免费快速版)方便开发测试。\n 全部模型支持 OpenAI 兼容接口与原生 zhipuai SDK,原生 Function Calling。\n

\n\n

环境准备

\n {`ZHIPU_API_KEY=xxxxxxxx.xxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

方式一:OpenAI 兼容接口(推荐)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = OpenAI(\n api_key=os.environ[\"ZHIPU_API_KEY\"],\n base_url=\"https://open.bigmodel.cn/api/paas/v4/\",\n)\n\nasync def evaluate_with_glm(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"glm-4-flash\", # 免费快速版;生产推荐 glm-5 / glm-4.7\n messages=messages,\n tools=oa_tools,\n )\n\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n final = client.chat.completions.create(\n model=\"glm-4-flash\", messages=messages)\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_glm(\"audio_abc123\", \"How are you today?\"))`}\n\n

方式二:官方 zhipuai SDK

\n {`from zhipuai import ZhipuAI\n\nclient = ZhipuAI(api_key=os.environ[\"ZHIPU_API_KEY\"])\n\n# 其余逻辑与方式一相同,仅替换 client 实例\nresp = client.chat.completions.create(\n model=\"glm-5\", # 旗舰;也可用 glm-4.7 / glm-4-flash\n messages=messages,\n tools=oa_tools,\n)`}\n \n 选型建议:\n 开发联调用 glm-4-flash(免费);\n 在线辅导日常诊断用 glm-4.7 性价比最高;\n K12 / 复杂 Agent 编排(多步评测 + 个性化练习路径)用 glm-5 / glm-5.1,\n 200K 上下文、Agent 能力对标 Claude Opus 系列。\n \n
\n\n \n

\n Moonshot AI 当前最新旗舰是 Kimi K2.5(2026 年 1 月 27 日发布,MoE 架构、256K 上下文、原生多模态、Agent 集群协作)。\n 另外提供 kimi-k2-thinking(深度思考)、kimi-k2-turbo-preview(高速版)。\n 上一代 moonshot-v1-8k/32k/128k 仍然兼容,但推荐迁移到 kimi-k2.5。\n 全部模型 OpenAI 兼容,原生 Function Calling。\n

\n\n

环境准备

\n {`MOONSHOT_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# 中国大陆用 api.moonshot.cn;海外/国际版用 api.moonshot.ai\nclient = OpenAI(\n api_key=os.environ[\"MOONSHOT_API_KEY\"],\n base_url=\"https://api.moonshot.cn/v1\",\n)\n\nasync def evaluate_with_kimi(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段英文录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"kimi-k2.5\", # 旗舰;也可选 kimi-k2-turbo-preview / moonshot-v1-128k\n messages=messages,\n tools=oa_tools,\n )\n\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n final = client.chat.completions.create(\n model=\"kimi-k2.5\", messages=messages)\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_kimi(\"audio_abc123\", \"Nice to meet you.\"))`}\n \n Kimi K2.5 原生 256K 上下文 + Agent 集群协作,特别适合「多轮口语练习 + 历史分析 + 多步评测编排」场景:\n 把用户过去 30 次评测的完整 JSON 全部塞进 messages,让 K2.5 一次性生成跨多次练习的进步报告与个性化练习路径。\n 需要更深推理时使用 kimi-k2-thinking,\n 追求实时反馈用 kimi-k2-turbo-preview。\n \n
\n\n \n

\n 字节跳动 豆包 Seed 2.0(2026 年 2 月发布)是 ByteDance Seed 团队推出的新一代通用大模型,覆盖 Pro / Lite / Mini / Code 多种规格,\n 通过 火山方舟(Volcano Ark) 提供 OpenAI 兼容的 /api/v3/chat/completions 接口,\n 原生支持 Function Calling、JSON Schema 结构化输出、深度思考(Chain-of-Thought)模式,\n 接驰声 MCP 几乎无须改动业务代码。\n

\n\n \n 豆包 Seed 2.0 的优势在 深度思考 + 工具编排:让模型一次性规划\"先调 en.sent.score,看完弱项再调 en.word.score 进一步定位音素\",\n 适合做\"多步评测 + 自动纠音\"这类 Agent 场景。\n 默认开启思考模式,可通过 {'thinking: { type: \"disabled\" }'} 关闭以节省时延。\n \n\n

推荐版本

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
model规格推荐用途
doubao-seed-2-0-pro-260215Pro · 旗舰多步评测 + 深度诊断 + 复杂 Agent 编排
doubao-seed-2-0-lite-260215Lite · 平衡在线辅导单轮评测 + 自然语言反馈,性价比首选
doubao-seed-2-0-mini-260215Mini · 极小高并发 / 边缘部署 / 移动端实时反馈
doubao-seed-2-0-code-preview-260215Code · 预览代码生成 / 工具编排 DSL,对评测场景非主推
doubao-seed-1-8-2512281.8 · 深度思考支持 reasoning_effort 调档(minimal/low/medium/high),上一代深度思考强化版仍可用
doubao-seed-1-6-2510151.6 · 经典256K 上下文经典版,已上线项目可继续沿用
\n
\n\n

环境准备

\n {`# 火山方舟控制台 → API Key 管理\nARK_API_KEY=ak-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · 动态 tools + 折返跑)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# 火山方舟 OpenAI 兼容端点\nclient = OpenAI(\n api_key=os.environ[\"ARK_API_KEY\"],\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n)\n\nMODEL = \"doubao-seed-2-0-pro-260215\" # 也可换成 lite / mini\n\nasync def evaluate_with_doubao(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # ① 把驰声 16 个评测工具的 schema 动态注入豆包\n tools = (await mcp.list_tools()).tools\n ark_tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n },\n } for t in tools]\n\n messages = [\n {\"role\": \"system\",\n \"content\": \"你是一位专业的英语口语教练,会主动调用驰声评测工具获取真实分数。\"},\n {\"role\": \"user\",\n \"content\": f\"请评测这段录音,audio_id={audio_id},参考文本:{ref_text}。\"\n f\"先做句子级评测,弱项再追加单词级定位。\"},\n ]\n\n # ② 第一轮 —— 让豆包根据 prompt 自主选工具\n resp = client.chat.completions.create(\n model=MODEL,\n messages=messages,\n tools=ark_tools,\n tool_choice=\"auto\",\n # extra_body={\"thinking\": {\"type\": \"disabled\"}}, # 需要时可关思考\n )\n\n msg = resp.choices[0].message\n messages.append(msg)\n\n # ③ 折返跑:豆包可能一次发起多个 tool_calls,全部回填\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n # ④ 第二轮 —— 让豆包基于真实评测 JSON 输出诊断 / 练习建议\n final = client.chat.completions.create(\n model=MODEL,\n messages=messages,\n )\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_doubao(\n audio_id=\"audio_abc123\",\n ref_text=\"The quick brown fox jumps over the lazy dog.\",\n)))`}\n\n

深度思考模式(可选)

\n

\n 豆包 Seed 2.0 默认开启 thinking 模式,会在内部生成思维链再产出答案,\n 对\"多步评测编排 / 复杂诊断\"质量明显更好;但会增加 30%~80% 的端到端延迟。\n 在 extra_body 里可显式控制:\n

\n {`# 关闭思考(更快、适合实时反馈)\nclient.chat.completions.create(\n model=\"doubao-seed-2-0-lite-260215\",\n messages=messages,\n tools=ark_tools,\n extra_body={\"thinking\": {\"type\": \"disabled\"}},\n)\n\n# 开启思考(默认,适合 Pro 模型 + 多步 Agent)\nclient.chat.completions.create(\n model=\"doubao-seed-2-0-pro-260215\",\n messages=messages,\n tools=ark_tools,\n extra_body={\"thinking\": {\"type\": \"enabled\"}},\n)`}\n\n \n 选型建议:\n 课堂 / 培训类一对一辅导用 doubao-seed-2-0-lite + 关思考;\n K12 / 考试场景需要\"多题型联动 + 升级建议\"时用 doubao-seed-2-0-pro + 开思考;\n 移动端实时口语对话用 doubao-seed-2-0-mini 控制成本与时延。\n \n
\n\n \n

\n OpenAI 当前旗舰为 GPT-5.1(2025-11-13 发布),400K 上下文、128K 最大输出,\n 支持可调推理强度 reasoning_effort(none / low / medium / high)。\n 另有 gpt-5.1-chat-latest(ChatGPT 同款,128K 上下文,对话场景更优)和 gpt-5-mini(性价比版)。\n 全部模型原生支持 Function Calling 与 Structured Outputs。\n

\n\n

环境准备

\n {`OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · GPT-5.1 + 驰声 MCP)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = OpenAI(api_key=os.environ[\"OPENAI_API_KEY\"])\n\nasync def evaluate_with_gpt(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [\n {\"role\": \"system\",\n \"content\": \"你是英语口语教练,必须调用驰声评测工具拿真实分数后再回答。\"},\n {\"role\": \"user\",\n \"content\": f\"请评测:audioId={audio_id},参考文本:{ref_text}\"},\n ]\n\n resp = client.chat.completions.create(\n model=\"gpt-5.1\",\n messages=messages,\n tools=oa_tools,\n tool_choice=\"auto\",\n reasoning_effort=\"medium\", # GPT-5.1 新参数:none / low / medium / high\n )\n\n msg = resp.choices[0].message\n messages.append(msg)\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n final = client.chat.completions.create(\n model=\"gpt-5.1\", messages=messages)\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_gpt(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n \n 选型建议:\n 评测调用 + 诊断默认用 gpt-5.1(reasoning_effort="medium",质量与延迟平衡);\n 纯对话/课堂讲解用 gpt-5.1-chat-latest;\n 高并发批量评测降本用 gpt-5-mini。\n 深度推理 / 多步 Agent 编排把 reasoning_effort 调到 high。\n \n
\n\n \n

\n Anthropic 当前最新为 Claude Opus 4.7(旗舰)、Claude Sonnet 4.6(平衡)、Claude Haiku 4.5(高速)。\n Claude 用 Messages API(与 OpenAI Chat Completions 不同),工具协议是 tool_use / tool_result 块结构。\n 支持文本 + 视觉输入,工具 schema 用 input_schema 字段(与 OpenAI 的 parameters 等价)。\n

\n\n

环境准备

\n {`ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · 原生 Anthropic SDK + MCP 工具桥接)

\n {`# pip install anthropic mcp\nimport os, json, asyncio\nfrom anthropic import Anthropic\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = Anthropic(api_key=os.environ[\"ANTHROPIC_API_KEY\"])\n\nasync def evaluate_with_claude(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # 把驰声 MCP 工具转成 Anthropic 风格(用 input_schema 而非 parameters)\n tools = (await mcp.list_tools()).tools\n anth_tools = [{\n \"name\": t.name,\n \"description\": t.description,\n \"input_schema\": t.inputSchema,\n } for t in tools]\n\n messages = [{\"role\": \"user\",\n \"content\": f\"请评测这段录音 audioId={audio_id},参考文本:{ref_text}\"}]\n\n # 工具循环:Claude 可能多轮 tool_use,需逐轮回填\n while True:\n resp = client.messages.create(\n model=\"claude-opus-4-7\", # 或 claude-sonnet-4-6 / claude-haiku-4-5\n max_tokens=2048,\n tools=anth_tools,\n messages=messages,\n system=\"你是专业英语口语教练,必须调用驰声评测工具获取真实分数。\",\n )\n\n # 把整段助手回复(含 tool_use 块)追加进 messages\n messages.append({\"role\": \"assistant\", \"content\": resp.content})\n\n if resp.stop_reason != \"tool_use\":\n # 没有更多工具调用,输出最终诊断\n return \"\".join(b.text for b in resp.content if b.type == \"text\")\n\n # 提取所有 tool_use 块、并行执行、把 tool_result 回填给 Claude\n tool_results = []\n for block in resp.content:\n if block.type == \"tool_use\":\n result = await mcp.call_tool(block.name, arguments=block.input)\n tool_results.append({\n \"type\": \"tool_result\",\n \"tool_use_id\": block.id,\n \"content\": result.content[0].text,\n })\n messages.append({\"role\": \"user\", \"content\": tool_results})\n\nprint(asyncio.run(evaluate_with_claude(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n \n 选型建议:\n 深度评测诊断 + 复杂 Agent 编排用 claude-opus-4-7(旗舰,编程/Agent 提升明显);\n 日常评测 + 性价比首选 claude-sonnet-4-6;\n 高并发实时反馈用 claude-haiku-4-5。\n Opus 4.5 起新增 effort 参数(low/medium/high),medium 即可达到 Sonnet 4.5 同等质量但 token 减少 ~76%。\n \n
\n\n \n

\n Google 最新 Gemini 3 Flash(gemini-3-flash-preview,2025-12-17)以 Flash 价位提供 Pro 级推理;\n 另有 Gemini 3.1 Pro Preview(旗舰)、Gemini 3.1 Flash-Lite Preview。\n 全部支持 Function Calling、并行调用、组合调用,原生多模态,thinking_level 控制推理深度。\n 推荐用 OpenAI 兼容端点,可直接复用 OpenAI SDK 与已有的 MCP 工具桥接代码。\n

\n\n

环境准备

\n {`GEMINI_API_KEY=AIzaSyxxxxxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

方式一:OpenAI 兼容端点(推荐,零迁移成本)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# Gemini OpenAI 兼容端点 —— 完全复用 OpenAI SDK\nclient = OpenAI(\n api_key=os.environ[\"GEMINI_API_KEY\"],\n base_url=\"https://generativelanguage.googleapis.com/v1beta/openai/\",\n)\n\nasync def evaluate_with_gemini(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\",\n \"content\": f\"请评测:audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"gemini-3-flash-preview\", # 或 gemini-3.1-pro-preview\n messages=messages,\n tools=oa_tools,\n tool_choice=\"auto\",\n )\n msg = resp.choices[0].message\n messages.append(msg)\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n final = client.chat.completions.create(\n model=\"gemini-3-flash-preview\", messages=messages)\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_gemini(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n\n

方式二:原生 google-genai SDK(thinking_level / 流式工具调用)

\n {`# pip install google-genai\nfrom google import genai\nfrom google.genai import types\n\nclient = genai.Client(api_key=os.environ[\"GEMINI_API_KEY\"])\n\n# 把 MCP 工具转成 Gemini function_declarations\nfn_decls = [{\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n} for t in tools]\n\nresp = client.models.generate_content(\n model=\"gemini-3-flash-preview\",\n contents=f\"评测 audioId={audio_id},参考文本:{ref_text}\",\n config=types.GenerateContentConfig(\n tools=[types.Tool(function_declarations=fn_decls)],\n # Gemini 3 起:thinking_level 替代旧的 thinking_budget\n # thinking_level=\"high\",\n ),\n)\n\n# tool_call 在 response.candidates[0].content.parts[0].function_call\nfc = resp.candidates[0].content.parts[0].function_call\nprint(f\"call: {fc.name}({dict(fc.args)}) id={fc.id}\")`}\n \n 选型建议:\n 日常评测用 gemini-3-flash-preview(速度比 2.5 Pro 快 3 倍、价格 ~$0.50/M 输入),已是 Gemini App 默认;\n 复杂多步 Agent / 编程任务用 gemini-3.1-pro-preview;\n 超大上下文 + 多模态批处理用同系列的 gemini-3.1-flash-lite-preview。\n \n \n 注意:Gemini 3 起每次 function_call 自动带 id,多轮工具调用必须把 id 透传回 function_response,否则会被拒绝(OpenAI 兼容端点已自动处理)。\n \n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
模型推荐版本base_urlFunction Calling适合场景
DeepSeek V3.2 · 非思考deepseek-chatapi.deepseek.com/v1✓ 支持评测调用 + 诊断,性价比最高
DeepSeek V3.2 · 思考deepseek-reasonerapi.deepseek.com/v1✓ 支持(思考中可调工具)深度分析 + 错因归因 + 个性化练习路径
GLM-5 · 旗舰glm-5 / glm-5.1open.bigmodel.cn/…/v4✓ 支持200K 长上下文 + Agent 编排,复杂诊断
GLM-4.7glm-4.7open.bigmodel.cn/…/v4✓ 支持在线辅导日常诊断,性价比首选
GLM-4-Flashglm-4-flashopen.bigmodel.cn/…/v4✓ 支持免费额度,开发联调
Kimi K2.5(旗舰)kimi-k2.5api.moonshot.cn/v1✓ 支持256K + 多模态 + Agent 集群协作
Kimi K2 Thinkingkimi-k2-thinkingapi.moonshot.cn/v1✓ 支持多步推理 + 多轮历史进度报告
Kimi K2 Turbokimi-k2-turbo-previewapi.moonshot.cn/v1✓ 支持高速响应版,实时反馈
豆包 Seed 2.0 Prodoubao-seed-2-0-pro-260215ark.cn-beijing.volces.com/api/v3✓ 支持(含深度思考)多步评测编排 + 深度诊断 Agent
豆包 Seed 2.0 Litedoubao-seed-2-0-lite-260215ark.cn-beijing.volces.com/api/v3✓ 支持在线辅导 + 单轮诊断,性价比首选
豆包 Seed 2.0 Minidoubao-seed-2-0-mini-260215ark.cn-beijing.volces.com/api/v3✓ 支持移动端 / 边缘部署 / 低延迟实时反馈
GPT-5.1(旗舰)gpt-5.1api.openai.com/v1✓ 支持(reasoning_effort 可调)400K 上下文 + 深度推理 + 复杂 Agent 编排
GPT-5.1 Chatgpt-5.1-chat-latestapi.openai.com/v1✓ 支持ChatGPT 同款,对话 / 课堂讲解
GPT-5 minigpt-5-miniapi.openai.com/v1✓ 支持高并发 / 批量评测降本
Claude Opus 4.7claude-opus-4-7api.anthropic.com/v1✓ 支持(tool_use 协议)旗舰,编程 / Agent / 深度诊断
Claude Sonnet 4.6claude-sonnet-4-6api.anthropic.com/v1✓ 支持日常评测 + 性价比首选
Claude Haiku 4.5claude-haiku-4-5api.anthropic.com/v1✓ 支持高并发实时反馈
Gemini 3 Flashgemini-3-flash-preview…/v1beta/openai/✓ 支持(并行 / 组合)Pro 级推理 + Flash 价位,Gemini App 默认
Gemini 3.1 Pro Previewgemini-3.1-pro-preview…/v1beta/openai/✓ 支持(thinking_level 可调)复杂多步 Agent + 编程任务
\n
\n \n 除 Claude 用 Anthropic 原生 SDK(anthropic 包,tool_use / tool_result 协议)外,其余所有模型均可通过 OpenAI Python SDK(openai 包)调用,仅需替换 base_url 与 api_key,驰声 MCP 侧代码无需改动。\n \n
\n\n
\n

方案选型速查

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n
场景推荐方案
AI 对话 / Copilot 类产品,LLM 供应商可能会换① 官方 MCP 客户端库
已有 LangChain / Mastra / Agents SDK 技术栈② Agent 框架 + adapter
火山方舟 / 千帆控制台直连,最小侵入③ chat.completions + tools
教育 SaaS / 培训 / 客服等业务后端集成④ 自研后端 Agent
原生 Android / iOS / 小程序 / 不装 MCP SDK 的老系统→ 走下一大节「非 MCP REST」
\n
\n
\n
\n\n {/* ══════ 接入 · 非 MCP 原生 REST(cvx_fc) ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 客户端环境不能 / 不想引入 MCP SDK:原生 Android / iOS / Flutter、微信 / 支付宝小程序、老版本 Java / PHP / Go 后端
  • \n
  • 希望把驰声当作普通 REST + WebSocket调,不经过 JSON-RPC、不走 stdio 代理
  • \n
  • 内部代号 cvx_fc(OpenAI function-calling 风格),与 MCP 模式指向同一个评测引擎,两者为并行入口
  • \n
\n

💡 能走 MCP 的一律优先 MCP;仅当客户端限制无法装 SDK 时走本大节。

\n
\n\n \n

\n 驰声在 MCP 之外提供一套 OpenAI 兼容的 Function Calling 风格 REST API(内部代号 cvx_fc)。它和 MCP 模式指向同一个评测引擎,但协议层走纯 HTTP / WebSocket,不依赖任何 MCP SDK。\n

\n\n \n 与 MCP 模式的关系:MCP 模式(POST /mcp,JSON-RPC 2.0)和 functioncalling 模式(POST /v1/call,REST)是两个并行入口,功能等价、工具/函数列表基本一致。\n \n\n

API 端点

\n
\n \n \n \n \n \n \n \n \n \n \n \n
方法路径说明
GET/v1/functions列出全部可用评测函数(等价 MCP tools/list)
POST/v1/call调用一个评测函数(等价 MCP tools/call)· 同时用于创建流式会话和拉取流式结果
WS{'/ws/eval/{session_id}'}流式评测音频传输
\n
\n\n

认证

\n

所有请求在 HTTP Header 中携带 API Key:

\n {`Authorization: Bearer `}\n

认证失败返回 401(缺少 Authorization)或 403(Key 无效 / 无权使用该评测类型)。结构化错误码见 API 参考 · 错误码。

\n
\n\n \n

\n 调用 GET /v1/functions 拿到当前 API Key 已授权的全部评测函数列表,响应格式与 OpenAI function-calling 的工具清单一致,可以直接喂给大模型作为 tools:\n

\n {`GET /v1/functions\nAuthorization: Bearer `}\n {`{\n \"object\": \"list\",\n \"data\": [\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"en_word_eval\",\n \"description\": \"英文单词发音评测,返回总分和每个音标得分。\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"ref_text\": { \"type\": \"string\", \"description\": \"参考文本\" },\n \"audio_base64\": { \"type\": \"string\", \"description\": \"Base64 编码音频(与 audio_url 二选一)\" },\n \"audio_url\": { \"type\": \"string\", \"description\": \"音频 HTTP(S) URL(与 audio_base64 二选一)\" },\n \"accent\": { \"type\": \"number\", \"description\": \"1=英式 / 2=美式 / 3=不区分(默认)\" },\n \"rank\": { \"type\": \"number\", \"description\": \"评分制:4 或 100(默认)\" }\n },\n \"required\": [\"ref_text\"]\n }\n }\n }\n /* … 其它函数依此类推 … */\n ]\n}`}\n \n 这个端点语义等价于 MCP 的 tools/list,每个 API Key 可见的函数集合由后台权限决定——客户端应以实际返回为准,不要在本地硬编码全量 19 个。\n \n\n

英文评测函数(10 个)

\n
\n \n \n \n \n \n \n \n {[\n ['en_word_eval', 'en.word.score', '单词发音评测'],\n ['en_word_correction', 'en.word.pron', '单词发音纠错'],\n ['en_phonics_eval', 'en.nsp.score', '自然拼读评测'],\n ['en_sentence_eval', 'en.sent.score', '句子朗读评测'],\n ['en_sentence_correction', 'en.sent.pron', '句子发音纠错'],\n ['en_vocab_eval', 'en.vocabs.pron', '词汇批量评测'],\n ['en_paragraph_eval', 'en.pred.score', '段落朗读评测'],\n ['en_realtime_eval', 'en.rltm.score', '实时朗读评测'],\n ['en_choice_eval', 'en.choc.score', '口语选择题'],\n ['en_semi_open_eval', 'en.scne.exam', '半开放题(情景对话等)'],\n ].map(([fn, ct, desc]) => (\n \n \n \n \n \n ))}\n \n
函数名core_type说明
{fn}{ct}{desc}
\n
\n\n

中文评测函数(6 个)

\n
\n \n \n \n \n \n \n \n {[\n ['cn_word_pinyin_eval', 'cn.word.score', '拼音 / 汉字发音评测'],\n ['cn_word_raw_eval', 'cn.word.raw', '汉字发音评测'],\n ['cn_sentence_eval', 'cn.sent.raw', '句子朗读评测'],\n ['cn_paragraph_eval', 'cn.pred.raw', '段落朗读评测'],\n ['cn_rec_eval', 'cn.rec.raw', '有限分支识别'],\n ['cn_aitalk_eval', 'cn.recscore.raw', '口语表达评测(AI Talk)'],\n ].map(([fn, ct, desc]) => (\n \n \n \n \n \n ))}\n \n
函数名core_type说明
{fn}{ct}{desc}
\n
\n\n

流式评测函数(3 个)

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
函数名作用
start_stream_eval创建流式评测会话,返回 session_id / ws_url / resume_token
get_stream_result兜底拉取:WS 没拿到 result 时,通过 HTTP 把最终评分捞回来
stream_eval_result(MCP 模式的别名;cvx_fc 模式统一用 get_stream_result)
\n
\n\n

\n 📘 每个函数的业务语义 / 参数 / 返回字段与 MCP 模式下的同名工具完全一致,可直接参考下文 API 参考 · 英文评测工具 与 中文评测工具。\n

\n
\n\n \n

把完整音频通过 audio_base64 或 audio_url 二选一传给 /v1/call,同步返回评分(与 MCP 模式的 evaluate_english_word 等工具语义等价):

\n {`curl -X POST http://your-host:8080/v1/call \\\\\n -H \"Authorization: Bearer your_api_key\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\n \"name\": \"en_word_eval\",\n \"arguments\": {\n \"ref_text\": \"hello\",\n \"audio_url\": \"https://example.com/hello.mp3\",\n \"accent\": 2,\n \"rank\": 100\n }\n }'`}\n

成功响应:

\n {`{\n \"name\": \"en_word_eval\",\n \"result\": {\n \"overall\": 85.5,\n \"details\": { /* 音素 / 韵律 / 流利度等结构与 MCP 模式完全一致 */ }\n }\n}`}\n

失败响应:

\n {`{\n \"name\": \"en_word_eval\",\n \"error\": { \"message\": \"错误描述\" }\n}`}\n

单次音频 ≤ 50MB,推荐 16 kHz / 单声道 / 16bit。

\n
\n\n \n
\n \n

创建会话:POST /v1/call 调用 start_stream_eval

\n

响应中拿到 session_id / ws_url / resume_token。

\n
\n \n

WebSocket 推送:连接 ws_url,收到 {`{\"type\":\"ready\"}`} 即可开始发二进制音频帧。

\n

边推边收 intermediate 中间结果;结束时发 {`{\"type\":\"stop\"}`},收到 result 即为最终评分。

\n
\n \n

兜底拉取(可选):如 WS 断开未收到最终 result,可再次 POST /v1/call 调用 get_stream_result 兜底。

\n
\n
\n\n

start_stream_eval 参数

\n \n\n

WebSocket 帧协议

\n
\n
\n

客户端 → 服务端

\n
    \n
  • • Binary — 原始音频帧,连上即可直接发送,无需握手
  • \n
  • • {`{\"type\":\"stop\"}`} — 结束录音
  • \n
  • • {`{\"type\":\"ping\"}`} — 心跳
  • \n
\n
\n
\n

服务端 → 客户端

\n
    \n
  • • ready — 连接就绪,可开始发送音频
  • \n
  • • intermediate — 实时中间结果
  • \n
  • • result — 最终评测结果
  • \n
  • • backpressure — 背压,含 suggested_interval_ms,建议降低发送频率
  • \n
  • • error — 错误(含结构化 code + message,见错误码一节)
  • \n
  • • pong — 心跳响应
  • \n
\n
\n
\n
\n\n \n

JavaScript(浏览器 / Node.js)

\n {`// ① 创建会话\nconst resp = await fetch('http://your-host:8080/v1/call', {\n method: 'POST',\n headers: {\n 'Authorization': 'Bearer your_api_key',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n name: 'start_stream_eval',\n arguments: {\n core_type: 'en.sent.score',\n ref_text: 'Hello world',\n audio_type: 'pcm',\n sample_rate: 16000,\n },\n }),\n});\nconst { result } = await resp.json();\n\n// ② WebSocket 推送音频\nconst ws = new WebSocket(result.ws_url);\nws.onmessage = (ev) => {\n const msg = JSON.parse(ev.data);\n switch (msg.type) {\n case 'ready': startRecording(); break;\n case 'intermediate': console.log('部分结果', msg.data); break;\n case 'result': console.log('最终结果', msg.data); ws.close(); break;\n case 'backpressure': console.warn('降速 ~', msg.suggested_interval_ms, 'ms'); break;\n case 'error': console.error(msg.code, msg.message); break;\n }\n};\n\nfunction onAudioChunk(pcm) {\n if (ws.readyState === WebSocket.OPEN) ws.send(pcm); // 直接发二进制\n}\n\nfunction stopRecording() {\n ws.send(JSON.stringify({ type: 'stop' }));\n}`}\n\n

Android(OkHttp · Kotlin)

\n {`val wsUrl = \"ws://your-host:8080/ws/eval/$sessionId\"\nval client = OkHttpClient()\nval req = Request.Builder()\n .url(wsUrl)\n .addHeader(\"Authorization\", \"Bearer \\${apiKey}\")\n .build()\n\nval ws = client.newWebSocket(req, object : WebSocketListener() {\n override fun onMessage(ws: WebSocket, text: String) {\n val msg = JSONObject(text)\n when (msg.getString(\"type\")) {\n \"ready\" -> startRecording()\n \"intermediate\" -> updateUI(msg.getJSONObject(\"data\"))\n \"result\" -> handleFinalResult(msg.getJSONObject(\"data\"))\n \"error\" -> handleError(msg.getString(\"code\"), msg.getString(\"message\"))\n }\n }\n})\n\n// 录音回调中发送 PCM 字节\nfun onAudioData(pcm: ByteArray) {\n ws.send(ByteString.of(*pcm))\n}\n\nfun stop() {\n ws.send(\"\"\"{\"type\":\"stop\"}\"\"\")\n}`}\n iOS / Flutter / 小程序同理,只要平台提供 WebSocket 客户端即可:连接 ws_url、把 PCM bytes 发出去、按 type 字段解析服务端消息就行。\n
\n\n \n

resume_token · 60 秒续播

\n

\n 客户端意外断开时,会话在服务端挂起 60 秒;用创建会话拿到的 resume_token 续播即可:\n

\n {`GET ws://your-host:8080/ws/eval/{session_id}?resume={resume_token}\nAuthorization: Bearer `}\n \n 重连成功后会收到新的 ready,继续推送音频即可;服务端会颁发新的 resume_token,原 token 立即作废。\n \n\n

兜底拉取 · get_stream_result

\n

如果 WS 没能收到最终 result,可主动通过 HTTP 拉取:

\n {`curl -X POST http://your-host:8080/v1/call \\\\\n -H \"Authorization: Bearer your_api_key\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\n \"name\": \"get_stream_result\",\n \"arguments\": {\n \"session_id\": \"stream-1713340800-a1b2c3\",\n \"auto_stop\": true,\n \"timeout\": 30\n }\n }'`}\n \n\n \n functioncalling 模式与 MCP 模式二选一、不要混用:同一个会话不要同时走 MCP 的 /ws/audio/ 和 cvx_fc 的 /ws/eval/,两条链路的会话 ID 空间是分开的。\n \n
\n\n
\n\n {/* ══════ 评测模式 ══════ */}\n \n\n \n

通过本地麦克风实时录音,音频以 WebSocket 流式推送到评测服务,无需生成中间文件。这是最灵活、延迟最低的评测方式,特别适合交互式口语练习场景。

\n 实时录音评测需要安装 SoX 并使用本地代理模式(Claude Desktop / Claude Code)。Cursor 等远程直连模式暂不支持实时录音。\n\n

需要按顺序调用三个工具:

\n\n
\n
\n

create_stream_session — 创建流式评测会话

\n \n

返回 session_id,后续步骤需使用。

\n
\n\n
\n

start_recording — 开始麦克风录音

\n \n

调用后自动启动麦克风,音频通过 WebSocket 实时推送到评测服务。

\n
\n\n
\n

stop_recording — 停止录音并获取结果

\n \n
\n
\n
\n\n \n
\n \n

用户:"请评测我的英文发音,文本是 Hello"

\n

AI 调用 create_stream_session(core_type="en.word.score", ref_text="Hello")

\n

→ 获得 session_id

\n
\n \n

AI 调用 start_recording(session_id=xxx)

\n

麦克风开始录音,音频通过 WebSocket 实时推送到评测服务

\n
\n \n

用户说完后告知 AI "结束"

\n

AI 调用 stop_recording(session_id=xxx)

\n

→ 返回评测结果(总分、准确度、流利度、音素得分等)

\n
\n
\n
\n\n \n

适用于已有音频文件的评测场景,支持三种输入方式:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
参数说明适用场景
audio_file_path本地文件路径代理自动读取并转为 Base64,最便捷
audio_base64Base64 编码数据已有编码数据时使用
audio_url音频文件 URL音频托管在云存储时使用
\n
\n 推荐使用 audio_file_path,只需传入本地文件路径,代理会自动处理编码和上传。\n

支持的音频格式:mp3, wav, ogg, m4a, aac, pcm

\n

限制:单文件最大 50MB,大于 500KB 的文件自动压缩为 16kHz / 单声道 / 32kbps。

\n
\n
\n\n {/* ══════ API 参考 ══════ */}\n \n\n \n \n\n

通用参数:所有英文评测工具均支持以下参数。

\n \n
\n\n \n \n\n

通用参数:

\n \n
\n\n \n

所有评测工具返回统一的结构化结果:

\n {`{\n \"overall\": 85,\n \"accuracy\": 82,\n \"pron\": 88,\n \"fluency\": {\n \"overall\": 78,\n \"speed\": 65,\n \"pause\": 2\n },\n \"integrity\": 95,\n \"details\": [\n {\n \"char\": \"hello\",\n \"score\": 85,\n \"phone\": [\n { \"phoneme\": \"h\", \"score\": 90 },\n { \"phoneme\": \"ɛ\", \"score\": 82 },\n { \"phoneme\": \"l\", \"score\": 88 },\n { \"phoneme\": \"oʊ\", \"score\": 80 }\n ]\n }\n ]\n}`}\n
\n \n \n \n \n \n \n \n {[\n ['overall', '0–100', '综合总分,反映整体语音质量'],\n ['accuracy', '0–100', '准确度,音素级别的发音准确率'],\n ['pron', '0–100', '发音得分,整体发音质量评价'],\n ['fluency.overall', '0–100', '流利度,语流的自然度与平滑度'],\n ['fluency.speed', '0–100', '语速得分,每分钟词/音节计量'],\n ['fluency.pause', 'number', '不自然停顿次数'],\n ['integrity', '0–100', '完整度,是否完整朗读了参考文本'],\n ['details[].phone[]', 'array', '每个音素的独立评分,可定位具体弱项'],\n ['details[].stress[]', 'array', '重音得分,检测重弱读是否正确'],\n ].map(([field, range, desc]) => (\n \n \n \n \n \n ))}\n \n
字段范围说明
{field}{range}{desc}
\n
\n
\n\n \n

常见业务场景

\n
\n \n \n \n \n \n \n \n {[\n ['音频 ID 无效或已过期', '音频上传后 5 分钟内有效,评测完成后自动删除', '重新上传音频'],\n ['服务器繁忙', '当前请求过多,排队已满', '稍后重试,使用指数退避策略'],\n ['存储空间已满', '服务器临时音频存储已满', '稍后重试,系统会自动清理'],\n ['音频格式不支持', '上传了不支持的文件类型', '使用 mp3/wav/ogg/m4a/aac/pcm'],\n ['音频时长超限', '超过该题型最大时长限制', '裁剪音频后重试'],\n ['WebSocket 连接断开', '网络不稳定导致流式连接中断', '代理会自动重连,如持续失败请检查网络'],\n ].map(([scene, reason, fix]) => (\n \n \n \n \n \n ))}\n \n
场景原因解决方式
{scene}{reason}{fix}
\n
\n\n

HTTP 状态码(functioncalling 模式)

\n
\n \n \n \n \n \n \n {[\n ['400', '请求格式错误(JSON 缺字段 / 类型错)'],\n ['401', '未认证(缺少 Authorization 头)'],\n ['403', '权限不足(API Key 无效或无权使用该评测类型)'],\n ['404', '会话不存在(session_id 错误或已回收)'],\n ['409', '会话状态不允许当前操作(如已 stop 后又发音频)'],\n ].map(([code, desc]) => (\n \n \n \n \n ))}\n \n
状态码含义
{code}{desc}
\n
\n\n

流式评测结构化错误码

\n

\n WebSocket 的 error 帧与 get_stream_result 的 HTTP 错误体统一使用以下错误码,便于客户端差错分流:\n

\n
\n \n \n \n \n \n \n \n {[\n ['SESSION_NOT_FOUND', '会话不存在', '重新调用 start_stream_eval / create_stream_session 创建'],\n ['SESSION_EXPIRED', '会话已过期(60s 未续流)', '重新创建会话'],\n ['INVALID_STATE', '当前状态不允许该操作', '检查调用顺序(例如已 stop 后又发音频)'],\n ['INVALID_PARAMS', '参数无效', '核对 core_type / ref_text / 采样率等'],\n ['RESUME_INVALID', 'resume_token 无效或已过期', '重新创建会话(每次重连会颁发新 token)'],\n ['AUDIO_TOO_LARGE', '单次音频超过 50MB', '压缩或切片后重传'],\n ['UPSTREAM_CONNECT', '评测引擎连接失败', '稍后重试;持续发生请联系驰声'],\n ['UPSTREAM_TIMEOUT', '评测超时', '缩短音频 / 检查网络'],\n ['UPSTREAM_EVAL_ERROR', '评测引擎返回错误', '查看 message 字段细节'],\n ['CAPACITY_FULL', '并发会话已满', '退避重试或升级配额'],\n ].map(([code, desc, fix]) => (\n \n \n \n \n \n ))}\n \n
错误码说明建议处理
{code}{desc}{fix}
\n
\n
\n
\n\n {/* ══════ 最佳实践 ══════ */}\n \n\n \n

\n 下面这些模板与{' '}\n 免费体验{' '}\n Demo 中实际使用的「教练 Prompt」一脉相承,全部围绕 角色 / 任务 / 方法 / 输出格式 / 语气 五段式结构,并使用占位符{' '}\n {'{mcp_response}'} 直接拼接 MCP 工具返回的 JSON。\n 推荐在 system 消息里挂载,再把工具返回原文塞进\n user 消息,由 LLM 基于真实分数和音素生成可读诊断 / 练习材料。\n

\n\n \n 使用建议:\n
    \n
  • 把 MCP 工具调用的完整 JSON(含 overall / dp_type / phonemes 等字段)原样塞入 {'{mcp_response}'},不要预先做汇总——细节越完整诊断越具体。
  • \n
  • 「诊断」类模板让 LLM 输出 Markdown 给最终用户阅读;「练习」类模板要求 LLM 输出严格 JSON 给前端渲染。两步分开调用,效果远好于一次性混合。
  • \n
  • 题型决定 prompt:单词题用音素级、句子题加韵律、段落题加 chunk / 整体性,半开放题套四维评级。下面按这 6 类分别给出。
  • \n
\n
\n\n {/* ─── A. 诊断类 · 输出 Markdown 给学习者阅读 ─── */}\n

\n A. 二次诊断 · 输出 Markdown\n

\n
\n
\n

\n 1. 单词级 · 音素诊断\n

\n

\n 适用工具:en.word.score / cn.word.raw。围绕 phonemes[].dp_type 找出错读音。\n

\n {`你是一位专业的英语发音教练。下面是驰声 MCP(en.word.score)返回的单词级评测数据:\n一个目标词、总分与发音分、以及带有 dp_type 的音素数组。\n\n## 任务\n为学习者写一份 **可直接阅读** 的发音诊断,每一条都要引用音素分数(写出 IPA 符号)。\n\n## 方法\n- 按 dp_type 分组:先看 mispron,再补充 normal 但分数 < 70 的\"边缘音\"。\n- 每个问题音素:① 典型母语干扰 → ② 你听到的声音 → ③ 一条具体的发音修正动作(下颌 / 舌位 / 气流 / 唇形)。\n- 重音符号 ˈ 标记的音节,重音错位也要单独列出(即便音素本身分数尚可)。\n- 最多列 4 条,按 **影响力从弱到强** 排序。\n\n## 输出\n精简 Markdown:可选一句总结 → 编号列表 → 单行 **🎯 优先级** 排序。\n\n## 语气\n友善、具体、可执行,不要空喊\"加油\"。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 2. 句子级 · 节奏 + 重音诊断\n

\n

\n 适用工具:en.sent.score。开头先给一行\"计分牌\",再从 phones → words → prosody。\n

\n {`你是一位专业的英语口语教练。下面是驰声 MCP(en.sent.score)返回的句子级数据:refText、总分、发音子分(accuracy / integrity / fluency / rhythm)、可选 speed(WPM),以及 details[] 中的逐词得分、dp_type 与可选 phonemes[]。\n\n## 任务\n开头给一行紧凑的 **计分牌**(总分 + 各子分 + 速度),再按 **音素 → 词 → 韵律** 顺序展开诊断。\n\n## 检查清单(每项都要覆盖;不适用则写\"无明显问题\")\n1. **音素级**:每个 score < 70 或 dp_type ≠ normal 的词,展开 phonemes,命名典型错误(如 /ð/ → /d/)并给一条修正动作。\n2. **漏读 / 多读**:标注 dp_type=omit / insert,解释如何拉低 integrity。\n3. **韵律**:基于 rhythm + 错读词的重音,指出重音错位、陈述句调型平直、断句过多等。\n4. **流利度 vs 准确度**:若 fluency 高但 accuracy 低,明确指出,让学习者知道优先改哪一项。\n\n## 输出格式\nMarkdown 子标题:**Pronunciation / Prosody / Study priority**(最后一行简短排序,按 ROI 从高到低)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 3. 段落级 · 音素族归并 + 完整度\n

\n

\n 适用工具:en.pred.score。把同类错音合并为\"音素族\",避免逐词复述。\n

\n {`你是一位专业的英语口语教练。下面是驰声 MCP(en.pred.score)返回的段落级数据:长 refText、总分、发音子分、可选 speed / integrity,以及大量 details[](同一个词可能在不同子句中重复出现;空 char + dp_type=omit 表示漏读)。\n\n## 任务\n对整段做 **整体诊断**:\n(a) 完整度 / 漏读,\n(b) 反复出现的 **音素族**,\n(c) 节奏与断句,\n(d) 各子分之间是否相互印证。\n\n## 检查清单\n1. **integrity / dp_type**:列出每个 omit / insert,并给出所在子句;解释长读时为什么虚词容易被吞。\n2. **音素聚类**:将弱词按共同音素问题归族(/θ/ 链、/e/ 链、/ɒ/ 等),引用 details 中的实例。\n3. **韵律**:结合 rhythm 与标点 —— 短语内停顿过多?子句边界缺失?\n4. **整体一致性**:若 fluency 正常但 accuracy 差(或反之),点明并指出对练习设计的影响。\n\n## 输出格式\nMarkdown 章节:**Summary / Completeness / Pronunciation (families) / Rhythm / Study priorities**(最后一项最多 4 条,按影响力排序)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 4. 半开放题 · IELTS 风格四维评级\n

\n

\n 适用工具:en.pqan.score。结合学习者 transcript + 四维分数,给出可教学的\"升档建议\"。\n

\n {`你是一位 **IELTS / 课堂口语风格** 的口语教练。下面是驰声 MCP(en.pqan.score)返回的半开放题数据:题目 refText、学习者 transcript、overall、四个维度分(grammar / content / fluency / pron)、speed(WPM)、以及结构化的 issues[] 标记。\n\n## 任务\n给出 **基于 rubric 的诊断**:先用一句话给出 0–100 的整体段位估计,再 **逐维度** 解释,并 **引用 transcript 中的短句**(不要复述全文)。最后给 3–5 条 **可执行的\"升档建议\"**(句型 / 模板,而不是\"多练一点\")。\n\n## 权重(要明确告诉学习者)\n- **Content ~30%** — 想法深度、举例、具体程度\n- **Grammar ~25%** — 句型多样性、主谓一致、从句\n- **Fluency ~25%** — 语速、停顿、口头禅、衔接\n- **Pronunciation ~20%** — 音素 + 可懂度\n\n## 跨维度检查\n- 若 content 最低,先给\"展开模板\",不要先抠音素。\n- 若 fluency 低 + WPM 低,区分\"思考型停顿\"与\"发音卡顿\"。\n- 若 pron 标出特定音,绑定到 transcript 里 **真实出现过的词**。\n\n## 输出格式\nMarkdown:**段位估计** → 紧凑的 **得分表格** → **\"To reach the next band\"** 编号列表(每条给出可仿写的句型)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 5. 中文专项 · 声调 / 儿化 / 变调\n

\n

\n 适用工具:cn.word.raw / cn.sent.raw / cn.pred.raw。中文评测最大权重在 **声调**,必须单独检查。\n

\n {`你是一位专业的普通话口语教练。下面是驰声 MCP(cn.sent.raw)返回的中文句子评测数据:整句分数 + 逐字 details + 可选 phonemes + 流利 / 节奏分。\n\n## 中文评测的权重\n- **声调错误权重最高** —— 声调读错可能直接改变词义\n- dp_type=mispron 多来自:声调错、平翘舌混用、前后鼻音混用\n- 拼音对、声调错,听感仍是\"洋腔洋调\"\n\n## 检查清单(缺则写\"无明显问题\")\n1. **儿化**:phonemes 出现 r(儿化) 或 dp_type 提示时,确认是否被读成\"主音节 + 单独儿\"两拍。\n2. **轻声**:叠词、词缀、句末语气词 —— 第二字应短促轻读,无完整声调曲线。\n3. **变调**:三声连读、不 + 后字、一 + 后字,是否符合普通话规则。\n4. **节奏**:用 rhythm + 逗号位置,标记停顿过长或过碎,建议 chunk 边界。\n\n## 输出\nMarkdown 子标题:**总览 / 儿化 / 轻声 / 变调 / 节奏 / 学习优先级**(最后一项 1–3 条,按\"听感自然度提升\"排序)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n {/* ─── B. 练习类 · 输出 JSON 给前端渲染 ─── */}\n

\n B. 微练习生成 · 输出严格 JSON\n

\n
\n
\n

\n 6. 单词 / 句子 · 微练习\n

\n

\n 建议在 诊断完成后 第二轮调用:让 LLM 严格按弱项音素生成,避免\"通用绕口令包\"。\n

\n {`你仍是这位学习者的发音教练。**第二轮诊断已经完成** —— 现在严格基于诊断里点名的弱音素,生成 **1:1 对应** 的微练习(不要给通用题)。\n\n## 输出(仅返回一段合法 JSON 数组,外层不要任何文字)\n根节点必须是数组,每个元素含 category(字符串)、icon(单个 emoji)、items({ \"label\", \"content\" } 数组)。\n\\`\\`\\`json\n[\n { \"category\": \"Phoneme drills\", \"icon\": \"🎯\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Awareness\", \"icon\": \"🗣️\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Whole word\", \"icon\": \"📝\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] }\n]\n\\`\\`\\`\n\n## 规则\n- **Phoneme drills**:诊断里每个 mispron 音素至少给一对最小对立对 + 一句短绕口令 / 重复句。\n- **Awareness**:当重音偏弱时,给一条 stress / 舌位 / 下颌姿态提示。\n- **Whole word**:2–3 句自然句,目标词分别出现在句首 / 句中 / 句末。\n- 所有 content 必须可念出声;字符串内不要再嵌套 JSON。\n\n## 上下文\n诊断结论:{previous_diagnosis}\n原始 MCP:\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 7. 段落 · Chunk Map + 元认知\n

\n

\n 段落级练习要从\"音素\"上升到\"短语 / 整段 / 元认知录回放\"。直接对应 en.pred.score 的诊断结果。\n

\n {`你仍是这位学习者的口语教练。**段落级二次诊断** 已经列出了漏读位置和音素族 —— 现在请生成 **整段练习**:把弱音素串成\"族\"练习、用 chunk map 把虚词粘回短语,并附一条录音 → 回放 → 对照 MCP details 的元认知步骤。\n\n## 输出(仅返回一段合法 JSON 数组)\n\\`\\`\\`json\n[\n { \"category\": \"Phoneme families\", \"icon\": \"🎯\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Chunking\", \"icon\": \"🎵\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Metacognition\", \"icon\": \"🧠\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] }\n]\n\\`\\`\\`\n\n## 规则\n- **Phoneme families**:至少 3 条,按诊断里的音素族(/θ/、/e/、/ɒ/ 等)组织最小对立对 / 词链。\n- **Chunking**:① 给一行用 [ ] 和 / 标注的 chunk map(可加大致停顿秒数);② 给一句\"把漏掉的虚词嵌入短语\"的练习(不要孤立练)。\n- **Metacognition**:一条\"录音 → 回放 → 对照 MCP details\"的 N 遍练习(N 写明,2–3 之间)。\n- 字符串只能是纯展示文本,禁止嵌套 JSON。\n\n## 上下文\n诊断结论:{previous_diagnosis}\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n {/* ─── C. 跨题 / 运营 ─── */}\n

\n C. 跨题 / 运营\n

\n
\n
\n

\n 8. 多日学习报告\n

\n

\n 把过去 N 天的 MCP 评测结果聚合后丢给 LLM,输出适合发给学生 / 家长的周报。\n

\n {`你是一位英语口语学习顾问。下面是这位学习者过去 7 天的驰声 MCP 评测历史(按时间顺序),每条包含题型、coreType、overall、子分、weak_phonemes 摘要。\n\n## 任务\n为学习者生成一份 **周报**,目标读者:本人 + 家长 / 老师。\n强调 **趋势** 与 **下一步计划**,不要复述每一次具体分数。\n\n## 必须包含\n1. **整体趋势**:进步 / 持平 / 退步(一句话 + 简短依据)\n2. **维度变化**:accuracy / fluency / rhythm / integrity / speed 任意有数据的维度,给出\"本周均分 vs 上周\"\n3. **本周高光**:分数提升最大的题型 / 音素 / 句型\n4. **顽固问题**:连续 3 次以上未达 70 的音素或维度\n5. **下周计划**:3 条具体动作(每条对应一个 MCP 工具或一个练习类型)\n6. **结尾**:1–2 句鼓励性总结,避免空话\n\n## 风格\n- 像一位认真但不啰嗦的私教\n- 出现学生姓名时使用占位 {student_name}\n- 数字一律保留整数\n\n## 评测历史\n\\`\\`\\`json\n{history}\n\\`\\`\\``}\n
\n\n
\n

\n 9. 错误归因 · JSON 摘要\n

\n

\n 用于后端聚合 / 数据看板:让 LLM 把一次评测压缩成结构化摘要,方便入库统计。\n

\n {`你是一个评测结果归类器。下面是驰声 MCP 一次评测的完整返回。请抽取关键信息并 **仅返回合法 JSON**(不要任何解释文字)。\n\n## Schema\n\\`\\`\\`json\n{\n \"core_type\": \"string,例如 en.sent.score\",\n \"overall\": 0,\n \"sub_scores\": { \"accuracy\": 0, \"integrity\": 0, \"fluency\": 0, \"rhythm\": 0 },\n \"weak_phonemes\": [\n { \"ipa\": \"string\", \"avg_score\": 0, \"occur\": 0, \"example_word\": \"string\" }\n ],\n \"omissions\": [{ \"after\": \"string\", \"missing\": \"string\" }],\n \"stress_issues\": [{ \"word\": \"string\", \"expected\": \"string\", \"actual\": \"string\" }],\n \"primary_issue_tag\": \"phoneme|stress|fluency|integrity|content|none\",\n \"next_action_hint\": \"string,10 字以内,例如 \\\"练 /θ/ 对立对\\\"\"\n}\n\\`\\`\\`\n\n## 规则\n- weak_phonemes 只收 avg_score < 70 的项,最多 5 项,按 occur 降序。\n- 不要复述 refText,不要 markdown。\n- 字段缺失时使用 null 或空数组,不要省略 key。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n \n 怎么接到 MCP 工具调用?\n
\n 以「直调 chat.completions + 动态 tools」为例:第一轮 LLM 调出 en.sent.score 工具,把工具 result(即 tool 消息内容)原样填入上面任意「诊断」模板的{' '}\n {'{mcp_response}'},作为第二轮 user 消息发回;拿到诊断结论再走第三轮,套「微练习」模板得到 JSON。三轮调用即可串起 评测 → 诊断 → 练习 全链路。\n
\n
\n\n \n
    \n
  • 音频过期:上传后 5 分钟内有效。建议在上传后 3 分钟内完成评测。
  • \n
  • 服务繁忙:使用指数退避策略重试(1s → 2s → 4s),最多 3 次。
  • \n
  • 录音中断:WebSocket 断线后代理会自动重连。如持续失败,检查网络连接和 SoX 安装。
  • \n
\n
\n\n \n
    \n
  • 优先使用流式评测:实时录音模式跳过了文件上传环节,端到端延迟比文件评测低 30-50%。
  • \n
  • 音频压缩:文件评测时,上传前将音频转为 16kHz 单声道 mp3,可减少 60-80% 的上传体积。
  • \n
  • 选择合适的工具:单词评测比段落评测快 3-5 倍。如只需单词级分数,不要用句子评测。
  • \n
  • 本地文件路径最便捷:使用 audio_file_path 参数传入本地路径,代理自动处理编码,无需手动转 Base64。
  • \n
\n
\n
\n\n {/* ══════ 服务信息 ══════ */}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
端点方法说明
/uploadPOST音频文件上传(MCP 模式文件评测使用)
/mcpPOSTMCP 模式 · JSON-RPC(Streamable HTTP)
{'/ws/audio/{session_id}'}WSMCP 模式 · 流式音频 WebSocket
/v1/functionsGETfunctioncalling 模式 · 列出全部评测函数
/v1/callPOSTfunctioncalling 模式 · 一次性评测 / 创建流式会话 / 拉取流式结果
{'/ws/eval/{session_id}'}WSfunctioncalling 模式 · 流式音频 WebSocket
/healthGET健康检查
\n
\n
\n \n
\n \n \n \n \n \n \n \n {[\n ['存储限制', '500MB', '最大音频存储空间'],\n ['最大排队', '10', '等待处理的请求数'],\n ['最大并发', '3', '同时处理的评测数'],\n ['音频有效期', '5 分钟', '上传后未评测自动过期'],\n ['文件大小限制', '50MB', '单个音频文件最大'],\n ].map(([k, v, d]) => (\n \n ))}\n \n
配置项默认值说明
{k}{v}{d}
\n
\n

\n 上表为托管侧技术默认;计费与试用/商用调用配额、并发档位以{' '}\n \n 会员套餐\n \n 说明为准,与上表独立。\n

\n
\n \n \n 当前线上版本:v1.0.0(网站未正式上线)。以下变更项为开发阶段规划记录,以正式发布公告为准。\n \n
\n {[\n { ver: 'v1.0.0', date: 'TBD', desc: '当前线上版本(网站未正式上线)' },\n ].map(l => (\n
\n {l.ver}\n {l.date}\n {l.desc}\n
\n ))}\n
\n
\n
\n\n \n );\n}\n\nexport default function DocsPage() {\n const locale = useLocale();\n return locale.startsWith('zh') ? : ;\n}\n"}, "ce93676d08f8657f4a01a76b1f6a83340d025909": {"t": 1785765791.3998358, "n": 146308, "h": "46965a277b762163", "c": "'use client';\n\nimport { useLocale } from 'next-intl';\nimport { Link } from '@/i18n/routing';\nimport { DocsShell, type NavGroup } from './docs-shell';\nimport {\n CodeBlock,\n DocSection,\n SubDoc,\n ParamTable,\n Callout,\n FlowStep,\n ToolTable,\n} from './docs-shared';\nimport { DocsEnglishBody } from './docs-content-en';\nimport {\n BookOpen,\n Code2,\n Zap,\n FileText,\n Terminal,\n Globe,\n Mic,\n MessageSquare,\n BarChart3,\n AlertTriangle,\n Radio,\n FolderOpen,\n Workflow,\n Sparkles,\n Plug,\n Bot,\n Building2,\n Check,\n Sparkle,\n Languages,\n GraduationCap,\n Notebook,\n Gauge,\n ListChecks,\n} from 'lucide-react';\n\n/* ─── Navigation Structure ─── */\n\nconst NAV = [\n { id: 'concept', icon: Workflow, label: 'MCP 工作原理', children: [\n { id: 'why-mcp', label: '为什么需要 MCP' },\n { id: 'scenario-walkthrough', label: '场景走查 · 6 步' },\n { id: 'dev-responsibility', label: '开发者只做两件事' },\n { id: 'integration-paths', label: '三种接入姿势' },\n ]},\n { id: 'architecture', icon: Terminal, label: '架构说明', children: [\n { id: 'arch-diagram', label: '架构图' },\n { id: 'transport', label: '传输协议' },\n ]},\n { id: 'quick-start', icon: Zap, label: '快速开始', children: [\n { id: 'overview', label: '概述' },\n { id: 'requirements', label: '系统要求' },\n { id: 'install', label: '安装方式' },\n { id: 'env-vars', label: '环境变量' },\n ]},\n { id: 'config', icon: Plug, label: '接入 · 直接用(零代码)', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: '扣子(Coze)' },\n { id: 'config-coze-workflow', label: 'Coze 工作流' },\n { id: 'config-ai-workspace', label: 'AI 工作台 · 豆包 / 飞书 / WorkBuddy / 钉钉' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: '其他 MCP 客户端' },\n ]},\n { id: 'config-code', icon: Code2, label: '接入 · 编程用(SDK / 代码)', children: [\n { id: 'code-mcp-sdk', label: '官方 MCP 客户端库' },\n { id: 'code-agent-frameworks', label: 'LangChain / Mastra / Agents SDK' },\n { id: 'code-function-calling', label: '直调 chat.completions · 上传与动态 tools' },\n { id: 'llm-deepseek', label: 'DeepSeek' },\n { id: 'llm-glm', label: 'GLM(智谱)' },\n { id: 'llm-kimi', label: 'KIMI(Moonshot)' },\n { id: 'llm-doubao', label: '豆包 Seed 2.0(火山方舟)' },\n { id: 'llm-openai', label: 'OpenAI(GPT-5.1)' },\n { id: 'llm-claude', label: 'Claude(Anthropic)' },\n { id: 'llm-gemini', label: 'Gemini(Google)' },\n { id: 'llm-comparison', label: '模型对比速查' },\n { id: 'code-selfhosted-agent', label: '自研后端 Agent' },\n ]},\n { id: 'eval-modes', icon: Radio, label: '评测模式', children: [\n { id: 'stream-eval', label: '实时录音评测' },\n { id: 'stream-flow', label: '流式评测流程' },\n { id: 'file-eval', label: '音频文件评测' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API 参考', children: [\n { id: 'tools-en', label: '英文评测工具' },\n { id: 'tools-cn', label: '中文评测工具' },\n { id: 'result-fields', label: '评测结果字段' },\n { id: 'error-codes', label: '错误码' },\n ]},\n { id: 'best-practices', icon: FileText, label: '最佳实践', children: [\n { id: 'prompt-templates', label: 'Prompt 模板' },\n { id: 'error-handling', label: '错误处理' },\n { id: 'performance', label: '性能优化' },\n ]},\n { id: 'service-info', icon: Globe, label: '服务信息', children: [\n { id: 'endpoints', label: '服务端点' },\n { id: 'limits', label: '服务限制' },\n { id: 'changelog', label: '更新日志' },\n ]},\n];\n\nconst NAV_EN: NavGroup[] = [\n { id: 'concept', icon: Workflow, label: 'How MCP works', children: [\n { id: 'why-mcp', label: 'Why MCP' },\n { id: 'scenario-walkthrough', label: 'Scenario · 6 steps' },\n { id: 'dev-responsibility', label: 'Two developer tasks' },\n { id: 'integration-paths', label: 'Three integration styles' },\n ]},\n { id: 'architecture', icon: Terminal, label: 'Architecture', children: [\n { id: 'arch-diagram', label: 'Diagram' },\n { id: 'transport', label: 'Transports' },\n ]},\n { id: 'quick-start', icon: Zap, label: 'Quick start', children: [\n { id: 'overview', label: 'Overview' },\n { id: 'requirements', label: 'Requirements' },\n { id: 'install', label: 'Install' },\n { id: 'env-vars', label: 'Environment' },\n ]},\n { id: 'config', icon: Plug, label: 'Zero-code clients', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: 'Coze' },\n { id: 'config-coze-workflow', label: 'Coze workflows' },\n { id: 'config-ai-workspace', label: 'Enterprise AI workspaces' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: 'Other MCP clients' },\n ]},\n { id: 'config-code', icon: Code2, label: 'SDK / code integration', children: [\n { id: 'code-mcp-sdk', label: 'Official MCP SDK' },\n { id: 'code-agent-frameworks', label: 'Agent frameworks' },\n { id: 'code-function-calling', label: 'chat.completions · upload & tools' },\n { id: 'llm-deepseek', label: 'DeepSeek' },\n { id: 'llm-glm', label: 'GLM (Zhipu)' },\n { id: 'llm-kimi', label: 'KIMI (Moonshot)' },\n { id: 'llm-doubao', label: 'Doubao Seed 2.0 (Volcano Ark)' },\n { id: 'llm-qwen', label: 'Qwen (Alibaba)' },\n { id: 'llm-openai', label: 'OpenAI (GPT-5.1)' },\n { id: 'llm-claude', label: 'Claude (Anthropic)' },\n { id: 'llm-gemini', label: 'Gemini (Google)' },\n { id: 'llm-comparison', label: 'Model comparison' },\n { id: 'code-selfhosted-agent', label: 'Custom backend' },\n ]},\n { id: 'eval-modes', icon: Radio, label: 'Evaluation modes', children: [\n { id: 'stream-eval', label: 'Streaming mic' },\n { id: 'stream-flow', label: 'Streaming flow' },\n { id: 'file-eval', label: 'Audio files' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API reference', children: [\n { id: 'tools-en', label: 'English tools' },\n { id: 'tools-cn', label: 'Chinese tools' },\n { id: 'result-fields', label: 'Result fields' },\n { id: 'error-codes', label: 'Errors' },\n ]},\n { id: 'best-practices', icon: FileText, label: 'Best practices', children: [\n { id: 'prompt-templates', label: 'Prompt templates' },\n { id: 'error-handling', label: 'Errors & retries' },\n { id: 'performance', label: 'Performance' },\n ]},\n { id: 'service-info', icon: Globe, label: 'Service info', children: [\n { id: 'endpoints', label: 'Endpoints' },\n { id: 'limits', label: 'Limits' },\n { id: 'changelog', label: 'Changelog' },\n ]},\n];\n\n/* ─── Page(英文 / 中文拆成两个组件,避免切换语言时 Hooks 数量变化导致白屏)─── */\n\nfunction DocsPageEn() {\n return (\n \n \n \n );\n}\n\nfunction DocsPageZh() {\n return (\n \n {/* ══════ MCP 工作原理 ══════ */}\n \n\n \n

\n 大模型(GPT / Claude / Gemini / 通义千问 等)本质上是文字大脑:它擅长读和写,但天生听不到音频、打不开你的数据库、调不通第三方 API。\n

\n

\n MCP(Model Context Protocol)是一套由 Anthropic 主导、业界共同推进的开放协议,它像一根\"对讲机\":让大模型可以在需要时主动去调用外部能力(工具、数据源、服务),然后把结果接回来继续对话。\n

\n
\n
\n
\n \n 没有 MCP 的做法\n
\n
    \n
  • · 研究评测服务的 REST 文档
  • \n
  • · 自己写鉴权 / 上传 / 轮询代码
  • \n
  • · 把结果序列化后塞进 prompt
  • \n
  • · 每换一个大模型都得重写一遍
  • \n
\n
\n
\n
\n \n 用驰声 MCP 之后\n
\n
    \n
  • · 填一行 MCP Server 地址
  • \n
  • · 大模型自动发现&调用评测工具
  • \n
  • · 换任何支持 MCP 的大模型都能用
  • \n
  • · 不写一行调用代码
  • \n
\n
\n
\n \n MCP 让\"接入语音评测\"从一个\"后端工程\"变成了一个\"配置项\"。这也是为什么 Cursor、Claude Desktop、Dify、Coze、字节豆包、飞书智能助手都已经原生支持 MCP。\n \n
\n\n \n

\n 想象一个具体场景:一位开发者用 Claude 做了一款 「AI 雅思口语陪练」小程序,接入驰声语音评测 MCP。当用户发来一段录音,整个链路是这样的:\n

\n
\n \n

配置阶段(开发者 · 一次性)

\n

在 AI 后端的配置文件里填一行驰声 MCP Server 地址。大模型启动时自动发现:「我多了一个叫语音评测的工具」。

\n
\n \n

接收用户指令(终端用户)

\n

小程序用户发来一段自我介绍录音:「帮我听听,发音哪里有问题?」后端把「文字 + 录音链接」打包给大模型。

\n
\n \n

大模型自主思考(LLM · 最核心的魔法)

\n
\n 「用户让我听发音。」
\n 「但我只是文字大脑,我听不到。」
\n 「等等 —— 开发者给了我一个叫 chivox_voice_eval 的 MCP 工具!」\n
\n
\n \n

MCP 协议 · 自动调用(LLM → 驰声)

\n

大模型自动按 MCP 标准构造 tools/call 请求,把录音链接和参考文本发到驰声服务。开发者不需要写任何调用代码。

\n
\n \n

驰声服务处理(评测引擎)

\n

驰声对音频进行考试级打分,把结构化结果通过 MCP 原路返回:overall 85、/θ/ 音发音错误、流利度 88。

\n
\n \n

大模型整合并输出反馈(LLM)

\n

大模型把冷冰冰的分数翻译成温柔反馈:

\n
\n 「你的自我介绍很棒!综合 85 分 🎉 不过 think 这个词的 /θ/ 咬舌音不太标准,我们一起来练一下……」\n
\n
\n
\n \n 整条链路里,MCP 只出现在 ① 和 ④:① 让开发者一次性告诉大模型「你多了一个工具」,④ 让大模型可以自动调用它。这两步的标准化,就是 MCP 的全部价值。\n \n
\n\n \n

听起来复杂,但对开发者来说只需要两件事:

\n
\n
\n
\n 1\n 填一次 MCP 配置\n
\n

\n 在 AI 后端的配置里填入驰声 MCP Server 地址和 API Key,就这一次,以后新加评测能力完全免开发。\n

\n {`{\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"apiKey\": \"sk-••••••••••\"\n }\n}`}\n
\n
\n
\n 2\n 写一段 System Prompt\n
\n

\n 告诉大模型这个工具是做什么的、什么时候调用、结果怎么转成用户友好的反馈。\n

\n {`你是一位英语口语教练。\n当用户发来录音时:\n1. 调用 chivox_voice_eval 评分\n2. 聚焦 <70 分的音素家族\n3. 用高情商话术给出练习建议`}\n
\n
\n

\n 其余所有事情 —— 音频上传、鉴权、工具发现、调用时机、返回格式、结果整合 —— 都由 MCP 协议和大模型自己搞定。\n

\n
\n\n \n

根据你的技术栈,有三种等价的接入方式,底层都走完全相同的 MCP 协议:

\n\n {/* ── 姿势一:可视化 ── */}\n
\n
\n \n

姿势一 · 可视化拖拽(扣子 / Coze / 飞书智能助手)

\n
\n

\n 适合产品经理、运营、不写后端代码的开发者。整个过程像在手机上装 App。\n

\n
    \n
  1. 找到入口:在扣子平台的 「插件 / 工具」 配置区,点击「添加 MCP 服务」。
  2. \n
  3. 填两个字段(这也是你未来会从驰声这边拿到的):\n
    \n \n \n \n \n \n
    服务器地址https://speech-eval.site/mcp
    鉴权密钥sk-•••••••••• (由驰声分配,用于计费与识别)
    \n
    \n
  4. \n
  5. 平台自动发现能力:扣子会访问你填的地址,读取 MCP Server 自描述的\"说明书\"。瞬间明白:「这是个语音评测工具,需要传音频,会返发音分」。
  6. \n
  7. 右侧测试:在平台的聊天框里发一段语音,大模型就会自动调用工具。整个过程不需要写一行代码。
  8. \n
\n
\n\n {/* ── 姿势二:代码框架 ── */}\n
\n
\n \n

姿势二 · 代码框架配置(Dify / LangChain / 自研后端)

\n
\n

\n 适合做独立 APP / 小程序、用 Dify 或 LangChain 写 Agent 的极客开发者。核心就是往配置文件里加一段 JSON。\n

\n
    \n
  1. 打开配置文件(项目根目录下的 mcp.json 或框架指定的配置路径)。
  2. \n
  3. 在 mcpServers 下增加一个节点:\n {`{\n \"mcpServers\": {\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"env\": {\n \"API_KEY\": \"你的专属密钥\"\n }\n }\n }\n}`}\n
  4. \n
  5. 重启后端服务。大模型的底层调度器会在启动时自动连上驰声 MCP Server,把 16 种评测工具注册成随时待命的 tools。
  6. \n
  7. 触发调用:用户发来录音后,大模型看到 system prompt 的引导,自动选择合适的工具(单词/句子/段落/半开放)调用。
  8. \n
\n
\n\n {/* ── 姿势三:Function Calling 直连(分 A / B 两种做法) ── */}\n
\n
\n \n

姿势三 · 原生 Function Calling(豆包 / DeepSeek / OpenAI 兼容 API)

\n
\n

\n 适合不用任何 Agent 框架、直接调用 LLM API 的后端开发者。豆包 1.5+ / DeepSeek / GPT / Qwen 等模型都走标准 chat.completions 的 tools 参数。这里又分 A / B 两种做法,B 才是生产推荐。\n

\n\n \n 常见疑问:\"要不要手写一个 tool 定义?\"
\n — 姿势一 / 二不用(Coze、Dify、火山方舟控制台、Claude Desktop 会自动从 MCP Server 拉工具列表)。
\n — 姿势三看你选 A 还是 B:A 要手写,B 用 MCP 客户端库自动拉。\n
\n\n {/* ── 3-A:手写 tool schema ── */}\n
\n
\n

3-A · 手写 tool schema(最快验证,不推荐生产)

\n 快速 Demo\n
\n

\n 自己写一段 JSON Schema 告诉豆包\"有个工具叫 xxx,参数长这样\",豆包返回 tool_call 后你再手动去调驰声 MCP。缺点:驰声有 16 个评测工具,你每加一个题型都要改代码。\n

\n {`import os, json\nfrom openai import OpenAI\n\nclient = OpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv('ARK_API_KEY'),\n)\n\n# ─── 手写一段 tool schema(不推荐:16 个工具就要写 16 段)───\ntools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": \"en_word_eval\",\n \"description\": \"英语单词发音评测。当用户让你评价英语发音并提供录音链接时调用。\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"audio_url\": {\"type\": \"string\", \"description\": \"录音 URL\"},\n \"reference_text\": {\"type\": \"string\", \"description\": \"参考文本,如 Apple\"},\n },\n \"required\": [\"audio_url\", \"reference_text\"]\n }\n }\n}]\n\nresp = client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,拿到评测结果后温柔地反馈,不要直接报分数。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n)\n\nmsg = resp.choices[0].message\nif msg.tool_calls:\n args = json.loads(msg.tool_calls[0].function.arguments)\n # ↓↓↓ 这里手动调驰声 MCP,再把结果回填给豆包做第二趟 ↓↓↓\n # result = requests.post(\"https://speech-eval.site/mcp\", json={...})`}\n
\n\n {/* ── 3-B:MCP 自动发现 ── */}\n
\n
\n

\n 3-B · 用 MCP 客户端库自动发现 \n

\n 生产推荐\n
\n

\n 启动时连上驰声 MCP Server,调一次 tools/list,把 16 个评测工具自动转成 Function Calling 的 tools 格式。驰声加新工具,你代码不用改。这才是 MCP 协议的真正价值。\n

\n {`import asyncio, os\nfrom openai import AsyncOpenAI\nfrom mcp import ClientSession\nfrom mcp.client.streamable_http import streamablehttp_client\n\nclient = AsyncOpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv(\"ARK_API_KEY\"),\n)\n\nasync def main():\n # ─── 1. 连驰声 MCP Server,自动拉取全部 16 个工具 ───\n async with streamablehttp_client(\n \"https://speech-eval.site/mcp\",\n headers={\"Authorization\": f\"Bearer {os.getenv('CHIVOX_KEY')}\"},\n ) as (read, write, _):\n async with ClientSession(read, write) as session:\n await session.initialize()\n mcp_tools = (await session.list_tools()).tools # ← 一行拿到全部工具\n\n # ─── 2. MCP schema → OpenAI Function Calling schema ───\n tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema, # MCP 直接给 JSON Schema\n }\n } for t in mcp_tools]\n\n # ─── 3. 正常调豆包,tools 由 MCP 动态注入 ───\n resp = await client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,收到评测结果后温柔反馈。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n )\n\n # ─── 4. 折返跑:豆包选好工具后,直接走 MCP 调驰声 ───\n msg = resp.choices[0].message\n if msg.tool_calls:\n call = msg.tool_calls[0]\n result = await session.call_tool(\n call.function.name,\n arguments=__import__(\"json\").loads(call.function.arguments),\n )\n # 把 result 回填给豆包做第二趟 chat.completions 即可\n\nasyncio.run(main())`}\n

\n 想要更省心?直接用 官方 mcp python sdk、mcp-use、openai-agents,或火山官方 Arkitect 高代码 SDK,它们都把上面这段\"MCP → Function Calling\"的桥接封装好了。\n

\n
\n
\n\n \n 三种姿势走的是完全相同的 MCP 协议,能力完全等价。选型建议:产品经理 / 原型验证用姿势一(Coze 填表单);AI 客户端用户用姿势二(Cursor / Claude Desktop 填 mcp.json);后端生产服务用姿势三-B(MCP 客户端库自动发现工具,不要手写 tool schema)。\n \n
\n\n
\n\n {/* ══════ 架构说明 ══════ */}\n \n\n \n
\n
\n

AI 客户端

\n

Claude Desktop
Claude Code
Cursor

\n
\n
\n

⇄

\n

stdio

\n
\n
\n

chivox-local-mcp

\n

本地代理
SoX 录音

\n
\n
\n

⇄

\n

HTTP / WS

\n
\n
\n

Remote Chivox

\n

MCP Server
评测引擎

\n
\n
\n
\n\n \n
    \n
  • \n \n stdio — AI 客户端通过标准输入输出与本地代理通信,这是 MCP 的标准传输方式\n
  • \n
  • \n \n HTTP — 音频文件评测工具通过 HTTP 代理到远程服务,适用于非流式场景\n
  • \n
  • \n \n WebSocket — 实时录音音频通过 WebSocket 流式推送,支持断线自动重连\n
  • \n
\n
\n
\n\n {/* ══════ 快速开始 ══════ */}\n \n\n \n

chivox-local-mcp 是驰声语音评测的 MCP 本地代理,通过 Model Context Protocol 将远程驰声评测服务桥接到本地,让 AI 助手(Claude Desktop、Claude Code、Cursor 等)直接调用语音评测能力。

\n

它支持两种评测模式,覆盖从即时交互到批量处理的全部场景:

\n
\n
\n
\n \n 实时录音评测\n
\n

通过麦克风边录边评,音频以 WebSocket 流式推送,无需生成中间文件,延迟更低、体验更佳。

\n
\n
\n
\n \n 音频文件评测\n
\n

支持本地文件路径、Base64 编码、URL 三种输入,适合已有音频的批量评测场景。

\n
\n
\n 当前支持 16 种评测工具:英文 10 种(单词、句子、段落、纠音、自然拼读、口语选择、半开放题等)+ 中文 6 种(汉字、拼音、词句、段落、有限分支、AI Talk)。\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n
依赖版本说明
Node.js{'>'}= 18运行时必须
SoXany仅实时录音功能需要(处理麦克风音频流)
\n
\n

安装 SoX(仅在使用实时录音时需要):

\n {`# macOS\nbrew install sox\n\n# Ubuntu / Debian\nsudo apt-get install sox`}\n
\n\n \n

方式一:npm 全局安装(推荐)

\n {`npm install -g chivox-local-mcp`}\n\n

方式二:npx 免安装运行

\n {`MCP_REMOTE_URL=http://your-server:8080 npx chivox-local-mcp`}\n\n

方式三:从源码构建

\n {`git clone https://git.chivox.com/CLOUD_DEV/cvx_local_mcp.git\ncd cvx_local_mcp\nbash scripts/build.sh`}\n
\n\n \n \n \n
\n\n {/* ══════ 接入 · 直接用(零代码) ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 不用写代码、不用装 SDK,只在客户端的「MCP 配置」或「扩展」里填一段 JSON / URL
  • \n
  • 保存后 LLM 自动发现 16 个评测工具,并在对话 / Agent 中自主调用
  • \n
  • 覆盖 IDE 编程助手、桌面 AI 客户端、企业 AI 工作台、可视化 Bot / 工作流平台四大生态
  • \n
\n
\n\n\n \n
    \n
  1. 打开 Cursor 设置(Cmd + ,)
  2. \n
  3. 左侧选择 MCP(或搜索 "MCP")
  4. \n
  5. 点击 Add new MCP server
  6. \n
  7. 填写配置并保存:
  8. \n
\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n}`}\n Cursor 使用远程 Streamable HTTP 模式直连,无需安装本地代理。如需实时录音功能,请使用下方 Claude Desktop 的本地代理配置。\n
\n\n \n

编辑配置文件(macOS:~/Library/Application Support/Claude/claude_desktop_config.json):

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"chivox-local-mcp\",\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\",\n \"MCP_API_KEY\": \"your-api-key\"\n }\n }\n }\n}`}\n

如果是从源码构建:

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/cvx_local_mcp/dist/index.js\"],\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\"\n }\n }\n }\n}`}\n Claude Desktop 使用本地代理模式(stdio),支持实时录音评测。本地代理会自动桥接远程服务。\n
\n\n \n {`# npm 全局安装后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 chivox-local-mcp\n\n# 源码构建后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 node /path/to/cvx_local_mcp/dist/index.js`}\n \n\n \n

除了 Cursor 和 Claude Code,主流的 AI 编程 IDE 都原生支持 MCP。以下客户端使用完全一致的 Streamable HTTP 配置,区别只在配置入口:

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
客户端配置入口备注
Windsurf (Codeium)Settings → Cascade → MCP Servers直接贴下方 JSON
Zed~/.config/zed/settings.json 的 context_serversAssistant Panel 自动发现
Continue (VS Code / JetBrains)config.yaml 的 mcpServersv0.9+ 支持
通义灵码 / CodeGeeX / 文心快码插件设置 → MCP 服务2026 Q1 起陆续支持
Cline (原 Claude Dev)MCP Servers 面板 → 编辑配置VS Code 扩展
\n
\n {`{\n \"mcpServers\": {\n \"chivox-speech-eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n }\n }\n}`}\n 所有 IDE 类客户端都走远程 Streamable HTTP,零本地依赖。需要实时录音才需切到 Claude Desktop 的本地代理模式。\n
\n\n \n

扣子(Coze)是字节跳动推出的 AI 应用开发平台,支持通过 MCP 扩展为 Agent 赋予外部工具能力。接入驰声语音评测后,你可以构建口语练习 Bot、发音诊断助手等应用。

\n

方式一:扣子空间 MCP 扩展(推荐)

\n
    \n
  1. 打开 扣子空间(space.coze.cn)
  2. \n
  3. 在对话框下方点击 「添加扩展」
  4. \n
  5. 选择 「自定义」 标签,点击添加新的 MCP 服务
  6. \n
  7. 填入以下配置信息:
  8. \n
\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
名称chivox-speech-eval
传输类型streamable-http
URLhttps://speech-eval.site/mcp
\n
\n
    \n
  1. 保存后,在对话中输入 「帮我评测这段英文发音」 即可触发 Agent 调用
  2. \n
\n 添加 MCP 扩展后,扣子空间的 Agent 会自动识别并调用评测工具。你可以在 Agent 的思考过程中看到具体的工具调用细节。\n\n

方式二:在 Coze 开发平台的 Bot 中使用

\n
    \n
  1. 进入 Coze 开发平台,创建或编辑 Bot
  2. \n
  3. 在 Bot 的 「插件」 或 「工具」 面板中,添加 MCP 工具
  4. \n
  5. 选择 Streamable HTTP 类型,填入 URL:https://speech-eval.site/mcp
  6. \n
  7. Bot 将自动发现所有可用的评测工具(如 evaluate_english_word 等)
  8. \n
  9. 在 Bot 的人设提示词中,添加语音评测相关的引导语
  10. \n
\n {`你是一位专业的英语口语教练。当用户上传音频并请求评测时:\n1. 使用 evaluate_english_word / evaluate_english_sentence 等工具进行评测\n2. 根据评测结果(overall、accuracy、fluency 等分数)给出专业分析\n3. 针对得分较低的维度提供具体改进建议\n4. 鼓励用户持续练习`}\n
\n\n \n

如果你需要在 Coze 工作流中集成语音评测能力,可以通过 HTTP Request 节点调用评测 API:

\n\n

步骤 1:上传音频

\n

在工作流中添加一个 HTTP Request 节点,配置如下:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
配置项值
方法POST
URLhttps://speech-eval.site/upload
Content-Typeaudio/mp3
Body音频文件二进制数据
\n
\n

响应中获取 {'{{audioId}}'},传递给下一步。

\n\n

步骤 2:调用评测

\n

添加第二个 HTTP Request 节点,通过 MCP 接口调用评测工具:

\n {`{\n \"jsonrpc\": \"2.0\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"evaluate_english_sentence\",\n \"arguments\": {\n \"audioId\": \"{{audioId}}\",\n \"sentence\": \"{{ref_text}}\"\n }\n },\n \"id\": 1\n}`}\n\n

步骤 3:处理结果

\n

评测结果通过 JSON 格式返回,可使用 Coze 的 代码节点 或 LLM 节点 对结果进行解析和二次处理(如生成学习建议、计算进步趋势等)。

\n\n 工作流方式适合需要固定流程的场景(如批量评测、定时任务、与其他系统联动)。如果是交互式场景,推荐使用上方的 MCP 扩展方式,Agent 会自动选择合适的工具。\n\n
\n

完整工作流示意

\n
\n 用户输入音频\n →\n HTTP: 上传音频\n →\n HTTP: 调用评测\n →\n LLM: 分析结果\n →\n 输出反馈\n
\n
\n
\n\n \n

这一类是面向「上班族」的企业 / 日常 AI 助手,产品形态是个聊天框 + 插件市场 / 扩展面板。接入后,员工在 App 里打字「帮我评一下这段录音」就能自动触发驰声评测,不用写任何代码。

\n\n
\n
\n

豆包(Doubao)App / 桌面版

\n

字节跳动官方 AI 助手,2026 年起桌面版支持 MCP 扩展。

\n
    \n
  1. 桌面版设置 → 「智能体扩展」 → 添加 MCP 服务
  2. \n
  3. 类型选 streamable-http,URL 填 https://speech-eval.site/mcp
  4. \n
  5. 对话中直接说「帮我评测」即可自动调用
  6. \n
\n
\n\n
\n

飞书智能伙伴(My AI)

\n

飞书企业 AI,支持以 MCP / Function Calling 挂载外部工具给团队 Bot。

\n
    \n
  1. 飞书开发者后台 → 创建应用 → 「AI 能力 / 智能伙伴」
  2. \n
  3. 在「工具」中选 外部 MCP 服务,填入上方 URL
  4. \n
  5. 把智能伙伴拉进群聊,@ 它提交音频即可评测
  6. \n
\n
\n\n
\n

WorkBuddy / 企业智能助手

\n

字节 WorkBuddy、腾讯会议 AI、企业微信智能助手等企业 AI 工作台场景。

\n
    \n
  1. 在工作台的「技能 / 扩展」后台新增一个 MCP 连接器
  2. \n
  3. 传输协议选 Streamable HTTP,地址填 https://speech-eval.site/mcp
  4. \n
  5. 把技能发布到指定部门 / 群组,HR、培训、销售口语陪练场景即可直接用
  6. \n
\n
\n\n
\n

钉钉 AI 助理 / 通义千问 App

\n

阿里生态:钉钉 AI 助理支持自定义插件,通义 App 可通过「AI 工具箱」挂载 MCP。

\n
    \n
  1. 钉钉开发者后台 → AI 助理 → 「插件开发 / MCP 接入」
  2. \n
  3. 选 HTTP Streamable,填入驰声 MCP URL 并开启鉴权(可选)
  4. \n
  5. 在钉钉群 @AI 助理上传音频,自动返回评测卡片
  6. \n
\n
\n
\n\n 典型场景 · 小龙虾们的共同剧本:销售口语陪练 → 外语培训 → 主持 / 播音岗位考核 → K12 英语作业批改 → 客服话术复盘。这些「上班族 AI 工作台」接入驰声 MCP 后,员工 / 学员只要对着话筒说话,AI 就能自动打分并给出个性化改进建议,运营 / 培训 / 教研团队零开发即可上线。\n
\n\n \n

如果你需要把语音评测编排进多步业务流(例如:学员录音 → 评测 → 生成错题集 → 推送到 CRM),可视化工作流平台比聊天 Bot 更合适。

\n\n
\n
\n

Dify

\n

开源 LLMOps,v0.15+ 原生 MCP 工具。

\n
    \n
  • 「工具」→「自定义 MCP」→ 填 URL
  • \n
  • 在 Chatflow / Workflow 节点里直接拖用
  • \n
\n
\n
\n

n8n

\n

工作流自动化,用 MCP Client 节点。

\n
    \n
  • 添加 MCP Client 节点
  • \n
  • Transport 选 HTTP Stream,URL 贴驰声地址
  • \n
  • Tool 下拉自动列出 16 个评测能力
  • \n
\n
\n
\n

Flowise / LangFlow

\n

可视化 LangChain Agent 编排。

\n
    \n
  • 拖出 MCP Tool 节点
  • \n
  • 连到 AgentExecutor 即可
  • \n
\n
\n
\n\n 可视化平台的好处是流程可追溯、可回放,适合教育机构 / 培训部门做批量评测 + 报表导出;缺点是单步延迟略高于直接 MCP 调用,对延迟敏感的交互场景建议用 Cursor / Claude Desktop 直连。\n
\n\n \n

任何遵循 MCP 协议的客户端都可以接入,统一使用以下配置:

\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
传输类型streamable-http
URLhttps://speech-eval.site/mcp
鉴权(可选)Header:Authorization: Bearer <MCP_API_KEY>
\n
\n

还没找到你用的客户端?任何支持 Model Context Protocol 的终端都通用。找不到入口?下一小节「编程用 MCP」里用 SDK 直接接即可。

\n
\n
\n\n {/* ══════ 接入 · 编程用 MCP ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 你在写一段真正的后端服务:一个 Agent Worker、一个 API、一个自动化脚本
  • \n
  • 业务里的「语音评测」是其中一个步骤,需要由代码 决定何时调用、如何解析结果
  • \n
  • 三种主流写法:① 官方 MCP 客户端库 → ② Agent 框架自动桥接 → ③ 退化到 chat.completions + tools 参数
  • \n
\n

💡 强烈推荐①或②:驰声有 16 个评测工具,让 MCP 自动注入 tool schema,每新增一个题型不用改一行业务代码。

\n
\n\n \n

最底层、也最推荐的方式。由 Anthropic 官方维护,一次连接自动拿到全部工具的 JSON Schema,然后交给任意 LLM。

\n\n

Python:mcp

\n {`# pip install mcp openai\nimport asyncio, os\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nMCP_URL = \"https://speech-eval.site/mcp\"\nllm = OpenAI(api_key=os.getenv(\"DOUBAO_KEY\"),\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\") # 豆包 / DeepSeek / OpenAI 同构\n\nasync def main(audio_id: str, ref: str):\n async with streamablehttp_client(MCP_URL) as (reader, writer, _):\n async with ClientSession(reader, writer) as sess:\n await sess.initialize()\n\n tools = await sess.list_tools()\n openai_tools = [{\n \"type\": \"function\",\n \"function\": {\"name\": t.name, \"description\": t.description,\n \"parameters\": t.inputSchema},\n } for t in tools.tools]\n\n resp = llm.chat.completions.create(\n model=\"doubao-1-5-pro-32k\",\n messages=[{\"role\": \"user\",\n \"content\": f\"帮我评测 audioId={audio_id},参考文本:{ref}\"}],\n tools=openai_tools,\n )\n\n for call in resp.choices[0].message.tool_calls or []:\n result = await sess.call_tool(call.function.name,\n arguments=eval(call.function.arguments))\n print(call.function.name, \"→\", result.content[0].text[:200])\n\nasyncio.run(main(\"abc123\", \"I think therefore I am\"))`}\n\n

TypeScript / Node.js:@modelcontextprotocol/sdk

\n {`// npm i @modelcontextprotocol/sdk openai\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport OpenAI from \"openai\";\n\nconst mcp = new Client({ name: \"chivox-biz\", version: \"1.0.0\" });\nawait mcp.connect(new StreamableHTTPClientTransport(new URL(\"https://speech-eval.site/mcp\")));\n\nconst { tools } = await mcp.listTools();\nconst openai = new OpenAI({ apiKey: process.env.DEEPSEEK_KEY, baseURL: \"https://api.deepseek.com/v1\" });\n\nconst resp = await openai.chat.completions.create({\n model: \"deepseek-chat\",\n messages: [{ role: \"user\", content: \"评测 audioId=abc123, 参考 I think therefore I am\" }],\n tools: tools.map(t => ({ type: \"function\", function: {\n name: t.name, description: t.description, parameters: t.inputSchema\n }})),\n});\n\nfor (const call of resp.choices[0].message.tool_calls ?? []) {\n const r = await mcp.callTool({ name: call.function.name,\n arguments: JSON.parse(call.function.arguments) });\n console.log(call.function.name, r.content);\n}`}\n 这种写法 LLM 供应商可换(豆包 / DeepSeek / GPT / Qwen / Moonshot),工具自动更新(驰声新增题型无需改业务代码),适合生产后端。\n
\n\n \n

如果项目已经在用 Agent 框架,几行 adapter 就能把驰声 MCP 塞进去,框架本身会接管 tool-calling 循环、重试、日志。

\n\n
\n
\n

LangChain / LangGraph(Python)

\n {`# pip install langchain-mcp-adapters langgraph\nfrom langchain_mcp_adapters.client import MultiServerMCPClient\nfrom langgraph.prebuilt import create_react_agent\n\nclient = MultiServerMCPClient({\n \"chivox\": {\n \"transport\": \"streamable_http\",\n \"url\": \"https://speech-eval.site/mcp\",\n }\n})\ntools = await client.get_tools()\n\nagent = create_react_agent(\"openai:gpt-4o-mini\", tools)\nresult = await agent.ainvoke({\"messages\":\n [(\"user\", \"评测 audioId=abc123 参考 think\")]})\nprint(result[\"messages\"][-1].content)`}\n
\n\n
\n

Mastra(TypeScript)

\n {`// npm i @mastra/core @mastra/mcp\nimport { MCPClient } from \"@mastra/mcp\";\nimport { Agent } from \"@mastra/core/agent\";\nimport { openai } from \"@ai-sdk/openai\";\n\nconst mcp = new MCPClient({ servers: {\n chivox: { url: new URL(\"https://speech-eval.site/mcp\") }\n}});\n\nexport const speechCoach = new Agent({\n name: \"speech-coach\",\n instructions: \"你是口语教练,用 chivox 工具评测并给改进建议。\",\n model: openai(\"gpt-4o-mini\"),\n tools: await mcp.getTools(),\n});`}\n
\n\n
\n

OpenAI Agents SDK(Python)

\n {`# pip install openai-agents\nfrom agents import Agent, Runner\nfrom agents.mcp import MCPServerStreamableHttp\n\nchivox = MCPServerStreamableHttp(\n params={\"url\": \"https://speech-eval.site/mcp\"},\n name=\"chivox-speech-eval\",\n)\n\nasync with chivox:\n agent = Agent(name=\"coach\",\n instructions=\"专业口语教练\",\n mcp_servers=[chivox])\n r = await Runner.run(agent, \"评测 audioId=abc123\")\n print(r.final_output)`}\n
\n\n
\n

LlamaIndex / AutoGen / CrewAI

\n

这些框架都有官方或社区 MCP adapter,用法与上述类似:

\n
    \n
  • LlamaIndex:llama-index-tools-mcp
  • \n
  • AutoGen:autogen-ext[mcp]
  • \n
  • CrewAI:crewai-tools 的 MCPServerAdapter
  • \n
  • Spring AI(Java):spring-ai-mcp-client
  • \n
\n
\n
\n
\n\n \n

\n DeepSeek、GLM(智谱)、KIMI(Moonshot)、豆包(火山方舟)、千帆、DashScope 等若提供 OpenAI 兼容的 HTTP API,接入驰声 MCP 的套路一致:用 MCP 客户端拉取工具列表 → 转为{' '}\n tools → 模型决策 tool_calls → MCP 执行并回填 → 再让模型生成诊断话术。\n

\n
\n
\n ① MCP list_tools()\n →\n ② 转 OpenAI tools 格式\n →\n ③ LLM 决策 tool_calls\n →\n ④ MCP call_tool()\n →\n ⑤ 评测结果回填 → LLM 诊断\n
\n
\n 各厂商仅需替换 base_url 与 api_key,驰声 MCP 与 tools 桥接代码可原样复用。\n\n

先上传音频,拿到 audioId

\n

文件评测工具通常需要 audioId(或路径参数,视工具而定)。下面是用 HTTP 上传的最小示例:

\n {`import requests\n\nwith open('audio.mp3', 'rb') as f:\n r = requests.post(\n 'https://speech-eval.site/upload',\n data=f,\n headers={'Content-Type': 'audio/mp3'}\n )\n\nresult = r.json()\nprint(f\"audioId: {result['audioId']}\")\nprint(f\"size: {result['size']} bytes\")\nprint(f\"expires: {result['expiresIn']}\")`}\n {`const fs = require('fs');\n\nconst audioData = fs.readFileSync('audio.mp3');\n\nconst res = await fetch('https://speech-eval.site/upload', {\n method: 'POST',\n headers: { 'Content-Type': 'audio/mp3' },\n body: audioData,\n});\n\nconst result = await res.json();\nconsole.log('audioId:', result.audioId);`}\n\n

再以豆包为例:MCP 动态 tools + chat.completions 折返跑

\n

当你用的 LLM SDK 还没有原生 MCP 支持(比如老版本的火山方舟 / 百度千帆 / 通义 DashScope),退化方案是:用 MCP 客户端一次性拉到 tool schema,然后按 OpenAI Function Calling 格式喂给 LLM。

\n {`# 适用:豆包(火山方舟)/ DeepSeek / Qwen / Moonshot / GLM 等 OpenAI 兼容 API\n# 核心思路:MCP 列工具 → 转 OpenAI tools → LLM 决策 → MCP 执行 → 回填\n\nasync with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n\n # ① 用 MCP 拉到的 schema 自动转 OpenAI 格式\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 喂给豆包\n messages = [{\"role\": \"user\", \"content\": \"评测一下 audioId=abc123\"}]\n resp = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages, tools=oa_tools,\n )\n\n # ③ LLM 回 tool_calls → 折返跑到 MCP 执行\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for c in msg.tool_calls:\n result = await mcp.call_tool(\n c.function.name, arguments=json.loads(c.function.arguments))\n messages.append({\"role\": \"tool\", \"tool_call_id\": c.id,\n \"content\": result.content[0].text})\n # ④ 再喂一轮,让豆包根据评测结果产出自然语言诊断\n final = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages)\n print(final.choices[0].message.content)`}\n 千万别手写 tool schema!驰声共 16 个评测工具(英文 10 + 中文 6),每个工具参数较多,手写既容易错也难维护。一定用 MCP list_tools() 动态拿。\n
\n\n \n

\n DeepSeek 提供与 OpenAI 完全兼容的 API,当前最新模型为 DeepSeek-V3.2(2025 年 12 月发布,首个把\"思考 + 工具调用\"原生融合的模型)。\n 通过 deepseek-chat 进入非思考模式,\n 通过 deepseek-reasoner 进入思考模式,\n 两种模式均支持 Function Calling,128K 上下文。\n

\n\n

环境准备

\n {`DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# DeepSeek 客户端(OpenAI 兼容)\nclient = OpenAI(\n api_key=os.environ[\"DEEPSEEK_API_KEY\"],\n base_url=\"https://api.deepseek.com/v1\",\n)\n\nasync def evaluate_with_deepseek(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # ① 拉取驰声 MCP 工具列表\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 调用 DeepSeek,让它选择合适的评测工具\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段英文录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"deepseek-chat\", # 或 deepseek-reasoner\n messages=messages,\n tools=oa_tools,\n )\n\n # ③ 执行 tool_calls\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n # ④ 让 DeepSeek 根据评测结果生成自然语言诊断\n final = client.chat.completions.create(\n model=\"deepseek-chat\",\n messages=messages,\n )\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_deepseek(\"audio_abc123\", \"Hello, nice to meet you.\"))`}\n \n 选型建议(V3.2):日常评测诊断用 deepseek-chat,速度快、token 消耗低;\n 需要深度分析(错误归因 / 个性化练习路径)时用 deepseek-reasoner,\n V3.2 起思考模式也能在思维链中调用工具,可以一次性完成\"调评测 → 思考 → 出诊断\",无需再切回 V3 做工具调用。\n \n
\n\n \n

\n 智谱 AI 当前最新旗舰为 GLM-5 / GLM-5.1(2026 年 2 月发布,744B-A40B MoE,200K 上下文,对标 Claude Opus 4.5),\n 以及上一代 GLM-4.7、GLM-4.6。\n 此外保留 glm-4-flash(免费快速版)方便开发测试。\n 全部模型支持 OpenAI 兼容接口与原生 zhipuai SDK,原生 Function Calling。\n

\n\n

环境准备

\n {`ZHIPU_API_KEY=xxxxxxxx.xxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

方式一:OpenAI 兼容接口(推荐)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = OpenAI(\n api_key=os.environ[\"ZHIPU_API_KEY\"],\n base_url=\"https://open.bigmodel.cn/api/paas/v4/\",\n)\n\nasync def evaluate_with_glm(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"glm-4-flash\", # 免费快速版;生产推荐 glm-5 / glm-4.7\n messages=messages,\n tools=oa_tools,\n )\n\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n final = client.chat.completions.create(\n model=\"glm-4-flash\", messages=messages)\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_glm(\"audio_abc123\", \"How are you today?\"))`}\n\n

方式二:官方 zhipuai SDK

\n {`from zhipuai import ZhipuAI\n\nclient = ZhipuAI(api_key=os.environ[\"ZHIPU_API_KEY\"])\n\n# 其余逻辑与方式一相同,仅替换 client 实例\nresp = client.chat.completions.create(\n model=\"glm-5\", # 旗舰;也可用 glm-4.7 / glm-4-flash\n messages=messages,\n tools=oa_tools,\n)`}\n \n 选型建议:\n 开发联调用 glm-4-flash(免费);\n 在线辅导日常诊断用 glm-4.7 性价比最高;\n K12 / 复杂 Agent 编排(多步评测 + 个性化练习路径)用 glm-5 / glm-5.1,\n 200K 上下文、Agent 能力对标 Claude Opus 系列。\n \n
\n\n \n

\n Moonshot AI 当前最新旗舰是 Kimi K2.5(2026 年 1 月 27 日发布,MoE 架构、256K 上下文、原生多模态、Agent 集群协作)。\n 另外提供 kimi-k2-thinking(深度思考)、kimi-k2-turbo-preview(高速版)。\n 上一代 moonshot-v1-8k/32k/128k 仍然兼容,但推荐迁移到 kimi-k2.5。\n 全部模型 OpenAI 兼容,原生 Function Calling。\n

\n\n

环境准备

\n {`MOONSHOT_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# 中国大陆用 api.moonshot.cn;海外/国际版用 api.moonshot.ai\nclient = OpenAI(\n api_key=os.environ[\"MOONSHOT_API_KEY\"],\n base_url=\"https://api.moonshot.cn/v1\",\n)\n\nasync def evaluate_with_kimi(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段英文录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"kimi-k2.5\", # 旗舰;也可选 kimi-k2-turbo-preview / moonshot-v1-128k\n messages=messages,\n tools=oa_tools,\n )\n\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n final = client.chat.completions.create(\n model=\"kimi-k2.5\", messages=messages)\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_kimi(\"audio_abc123\", \"Nice to meet you.\"))`}\n \n Kimi K2.5 原生 256K 上下文 + Agent 集群协作,特别适合「多轮口语练习 + 历史分析 + 多步评测编排」场景:\n 把用户过去 30 次评测的完整 JSON 全部塞进 messages,让 K2.5 一次性生成跨多次练习的进步报告与个性化练习路径。\n 需要更深推理时使用 kimi-k2-thinking,\n 追求实时反馈用 kimi-k2-turbo-preview。\n \n
\n\n \n

\n 字节跳动 豆包 Seed 2.0(2026 年 2 月发布)是 ByteDance Seed 团队推出的新一代通用大模型,覆盖 Pro / Lite / Mini / Code 多种规格,\n 通过 火山方舟(Volcano Ark) 提供 OpenAI 兼容的 /api/v3/chat/completions 接口,\n 原生支持 Function Calling、JSON Schema 结构化输出、深度思考(Chain-of-Thought)模式,\n 接驰声 MCP 几乎无须改动业务代码。\n

\n\n \n 豆包 Seed 2.0 的优势在 深度思考 + 工具编排:让模型一次性规划\"先调 en.sent.score,看完弱项再调 en.word.score 进一步定位音素\",\n 适合做\"多步评测 + 自动纠音\"这类 Agent 场景。\n 默认开启思考模式,可通过 {'thinking: { type: \"disabled\" }'} 关闭以节省时延。\n \n\n

推荐版本

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
model规格推荐用途
doubao-seed-2-0-pro-260215Pro · 旗舰多步评测 + 深度诊断 + 复杂 Agent 编排
doubao-seed-2-0-lite-260215Lite · 平衡在线辅导单轮评测 + 自然语言反馈,性价比首选
doubao-seed-2-0-mini-260215Mini · 极小高并发 / 边缘部署 / 移动端实时反馈
doubao-seed-2-0-code-preview-260215Code · 预览代码生成 / 工具编排 DSL,对评测场景非主推
doubao-seed-1-8-2512281.8 · 深度思考支持 reasoning_effort 调档(minimal/low/medium/high),上一代深度思考强化版仍可用
doubao-seed-1-6-2510151.6 · 经典256K 上下文经典版,已上线项目可继续沿用
\n
\n\n

环境准备

\n {`# 火山方舟控制台 → API Key 管理\nARK_API_KEY=ak-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · 动态 tools + 折返跑)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# 火山方舟 OpenAI 兼容端点\nclient = OpenAI(\n api_key=os.environ[\"ARK_API_KEY\"],\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n)\n\nMODEL = \"doubao-seed-2-0-pro-260215\" # 也可换成 lite / mini\n\nasync def evaluate_with_doubao(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # ① 把驰声 16 个评测工具的 schema 动态注入豆包\n tools = (await mcp.list_tools()).tools\n ark_tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n },\n } for t in tools]\n\n messages = [\n {\"role\": \"system\",\n \"content\": \"你是一位专业的英语口语教练,会主动调用驰声评测工具获取真实分数。\"},\n {\"role\": \"user\",\n \"content\": f\"请评测这段录音,audio_id={audio_id},参考文本:{ref_text}。\"\n f\"先做句子级评测,弱项再追加单词级定位。\"},\n ]\n\n # ② 第一轮 —— 让豆包根据 prompt 自主选工具\n resp = client.chat.completions.create(\n model=MODEL,\n messages=messages,\n tools=ark_tools,\n tool_choice=\"auto\",\n # extra_body={\"thinking\": {\"type\": \"disabled\"}}, # 需要时可关思考\n )\n\n msg = resp.choices[0].message\n messages.append(msg)\n\n # ③ 折返跑:豆包可能一次发起多个 tool_calls,全部回填\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n # ④ 第二轮 —— 让豆包基于真实评测 JSON 输出诊断 / 练习建议\n final = client.chat.completions.create(\n model=MODEL,\n messages=messages,\n )\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_doubao(\n audio_id=\"audio_abc123\",\n ref_text=\"The quick brown fox jumps over the lazy dog.\",\n)))`}\n\n

深度思考模式(可选)

\n

\n 豆包 Seed 2.0 默认开启 thinking 模式,会在内部生成思维链再产出答案,\n 对\"多步评测编排 / 复杂诊断\"质量明显更好;但会增加 30%~80% 的端到端延迟。\n 在 extra_body 里可显式控制:\n

\n {`# 关闭思考(更快、适合实时反馈)\nclient.chat.completions.create(\n model=\"doubao-seed-2-0-lite-260215\",\n messages=messages,\n tools=ark_tools,\n extra_body={\"thinking\": {\"type\": \"disabled\"}},\n)\n\n# 开启思考(默认,适合 Pro 模型 + 多步 Agent)\nclient.chat.completions.create(\n model=\"doubao-seed-2-0-pro-260215\",\n messages=messages,\n tools=ark_tools,\n extra_body={\"thinking\": {\"type\": \"enabled\"}},\n)`}\n\n \n 选型建议:\n 课堂 / 培训类一对一辅导用 doubao-seed-2-0-lite + 关思考;\n K12 / 考试场景需要\"多题型联动 + 升级建议\"时用 doubao-seed-2-0-pro + 开思考;\n 移动端实时口语对话用 doubao-seed-2-0-mini 控制成本与时延。\n \n
\n\n \n

\n OpenAI 当前旗舰为 GPT-5.1(2025-11-13 发布),400K 上下文、128K 最大输出,\n 支持可调推理强度 reasoning_effort(none / low / medium / high)。\n 另有 gpt-5.1-chat-latest(ChatGPT 同款,128K 上下文,对话场景更优)和 gpt-5-mini(性价比版)。\n 全部模型原生支持 Function Calling 与 Structured Outputs。\n

\n\n

环境准备

\n {`OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · GPT-5.1 + 驰声 MCP)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = OpenAI(api_key=os.environ[\"OPENAI_API_KEY\"])\n\nasync def evaluate_with_gpt(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [\n {\"role\": \"system\",\n \"content\": \"你是英语口语教练,必须调用驰声评测工具拿真实分数后再回答。\"},\n {\"role\": \"user\",\n \"content\": f\"请评测:audioId={audio_id},参考文本:{ref_text}\"},\n ]\n\n resp = client.chat.completions.create(\n model=\"gpt-5.1\",\n messages=messages,\n tools=oa_tools,\n tool_choice=\"auto\",\n reasoning_effort=\"medium\", # GPT-5.1 新参数:none / low / medium / high\n )\n\n msg = resp.choices[0].message\n messages.append(msg)\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n final = client.chat.completions.create(\n model=\"gpt-5.1\", messages=messages)\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_gpt(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n \n 选型建议:\n 评测调用 + 诊断默认用 gpt-5.1(reasoning_effort="medium",质量与延迟平衡);\n 纯对话/课堂讲解用 gpt-5.1-chat-latest;\n 高并发批量评测降本用 gpt-5-mini。\n 深度推理 / 多步 Agent 编排把 reasoning_effort 调到 high。\n \n
\n\n \n

\n Anthropic 当前最新为 Claude Opus 4.7(旗舰)、Claude Sonnet 4.6(平衡)、Claude Haiku 4.5(高速)。\n Claude 用 Messages API(与 OpenAI Chat Completions 不同),工具协议是 tool_use / tool_result 块结构。\n 支持文本 + 视觉输入,工具 schema 用 input_schema 字段(与 OpenAI 的 parameters 等价)。\n

\n\n

环境准备

\n {`ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · 原生 Anthropic SDK + MCP 工具桥接)

\n {`# pip install anthropic mcp\nimport os, json, asyncio\nfrom anthropic import Anthropic\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = Anthropic(api_key=os.environ[\"ANTHROPIC_API_KEY\"])\n\nasync def evaluate_with_claude(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # 把驰声 MCP 工具转成 Anthropic 风格(用 input_schema 而非 parameters)\n tools = (await mcp.list_tools()).tools\n anth_tools = [{\n \"name\": t.name,\n \"description\": t.description,\n \"input_schema\": t.inputSchema,\n } for t in tools]\n\n messages = [{\"role\": \"user\",\n \"content\": f\"请评测这段录音 audioId={audio_id},参考文本:{ref_text}\"}]\n\n # 工具循环:Claude 可能多轮 tool_use,需逐轮回填\n while True:\n resp = client.messages.create(\n model=\"claude-opus-4-7\", # 或 claude-sonnet-4-6 / claude-haiku-4-5\n max_tokens=2048,\n tools=anth_tools,\n messages=messages,\n system=\"你是专业英语口语教练,必须调用驰声评测工具获取真实分数。\",\n )\n\n # 把整段助手回复(含 tool_use 块)追加进 messages\n messages.append({\"role\": \"assistant\", \"content\": resp.content})\n\n if resp.stop_reason != \"tool_use\":\n # 没有更多工具调用,输出最终诊断\n return \"\".join(b.text for b in resp.content if b.type == \"text\")\n\n # 提取所有 tool_use 块、并行执行、把 tool_result 回填给 Claude\n tool_results = []\n for block in resp.content:\n if block.type == \"tool_use\":\n result = await mcp.call_tool(block.name, arguments=block.input)\n tool_results.append({\n \"type\": \"tool_result\",\n \"tool_use_id\": block.id,\n \"content\": result.content[0].text,\n })\n messages.append({\"role\": \"user\", \"content\": tool_results})\n\nprint(asyncio.run(evaluate_with_claude(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n \n 选型建议:\n 深度评测诊断 + 复杂 Agent 编排用 claude-opus-4-7(旗舰,编程/Agent 提升明显);\n 日常评测 + 性价比首选 claude-sonnet-4-6;\n 高并发实时反馈用 claude-haiku-4-5。\n Opus 4.5 起新增 effort 参数(low/medium/high),medium 即可达到 Sonnet 4.5 同等质量但 token 减少 ~76%。\n \n
\n\n \n

\n Google 最新 Gemini 3 Flash(gemini-3-flash-preview,2025-12-17)以 Flash 价位提供 Pro 级推理;\n 另有 Gemini 3.1 Pro Preview(旗舰)、Gemini 3.1 Flash-Lite Preview。\n 全部支持 Function Calling、并行调用、组合调用,原生多模态,thinking_level 控制推理深度。\n 推荐用 OpenAI 兼容端点,可直接复用 OpenAI SDK 与已有的 MCP 工具桥接代码。\n

\n\n

环境准备

\n {`GEMINI_API_KEY=AIzaSyxxxxxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

方式一:OpenAI 兼容端点(推荐,零迁移成本)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# Gemini OpenAI 兼容端点 —— 完全复用 OpenAI SDK\nclient = OpenAI(\n api_key=os.environ[\"GEMINI_API_KEY\"],\n base_url=\"https://generativelanguage.googleapis.com/v1beta/openai/\",\n)\n\nasync def evaluate_with_gemini(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\",\n \"content\": f\"请评测:audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"gemini-3-flash-preview\", # 或 gemini-3.1-pro-preview\n messages=messages,\n tools=oa_tools,\n tool_choice=\"auto\",\n )\n msg = resp.choices[0].message\n messages.append(msg)\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n final = client.chat.completions.create(\n model=\"gemini-3-flash-preview\", messages=messages)\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_gemini(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n\n

方式二:原生 google-genai SDK(thinking_level / 流式工具调用)

\n {`# pip install google-genai\nfrom google import genai\nfrom google.genai import types\n\nclient = genai.Client(api_key=os.environ[\"GEMINI_API_KEY\"])\n\n# 把 MCP 工具转成 Gemini function_declarations\nfn_decls = [{\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n} for t in tools]\n\nresp = client.models.generate_content(\n model=\"gemini-3-flash-preview\",\n contents=f\"评测 audioId={audio_id},参考文本:{ref_text}\",\n config=types.GenerateContentConfig(\n tools=[types.Tool(function_declarations=fn_decls)],\n # Gemini 3 起:thinking_level 替代旧的 thinking_budget\n # thinking_level=\"high\",\n ),\n)\n\n# tool_call 在 response.candidates[0].content.parts[0].function_call\nfc = resp.candidates[0].content.parts[0].function_call\nprint(f\"call: {fc.name}({dict(fc.args)}) id={fc.id}\")`}\n \n 选型建议:\n 日常评测用 gemini-3-flash-preview(速度比 2.5 Pro 快 3 倍、价格 ~$0.50/M 输入),已是 Gemini App 默认;\n 复杂多步 Agent / 编程任务用 gemini-3.1-pro-preview;\n 超大上下文 + 多模态批处理用同系列的 gemini-3.1-flash-lite-preview。\n \n \n 注意:Gemini 3 起每次 function_call 自动带 id,多轮工具调用必须把 id 透传回 function_response,否则会被拒绝(OpenAI 兼容端点已自动处理)。\n \n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
模型推荐版本base_urlFunction Calling适合场景
DeepSeek V3.2 · 非思考deepseek-chatapi.deepseek.com/v1✓ 支持评测调用 + 诊断,性价比最高
DeepSeek V3.2 · 思考deepseek-reasonerapi.deepseek.com/v1✓ 支持(思考中可调工具)深度分析 + 错因归因 + 个性化练习路径
GLM-5 · 旗舰glm-5 / glm-5.1open.bigmodel.cn/…/v4✓ 支持200K 长上下文 + Agent 编排,复杂诊断
GLM-4.7glm-4.7open.bigmodel.cn/…/v4✓ 支持在线辅导日常诊断,性价比首选
GLM-4-Flashglm-4-flashopen.bigmodel.cn/…/v4✓ 支持免费额度,开发联调
Kimi K2.5(旗舰)kimi-k2.5api.moonshot.cn/v1✓ 支持256K + 多模态 + Agent 集群协作
Kimi K2 Thinkingkimi-k2-thinkingapi.moonshot.cn/v1✓ 支持多步推理 + 多轮历史进度报告
Kimi K2 Turbokimi-k2-turbo-previewapi.moonshot.cn/v1✓ 支持高速响应版,实时反馈
豆包 Seed 2.0 Prodoubao-seed-2-0-pro-260215ark.cn-beijing.volces.com/api/v3✓ 支持(含深度思考)多步评测编排 + 深度诊断 Agent
豆包 Seed 2.0 Litedoubao-seed-2-0-lite-260215ark.cn-beijing.volces.com/api/v3✓ 支持在线辅导 + 单轮诊断,性价比首选
豆包 Seed 2.0 Minidoubao-seed-2-0-mini-260215ark.cn-beijing.volces.com/api/v3✓ 支持移动端 / 边缘部署 / 低延迟实时反馈
GPT-5.1(旗舰)gpt-5.1api.openai.com/v1✓ 支持(reasoning_effort 可调)400K 上下文 + 深度推理 + 复杂 Agent 编排
GPT-5.1 Chatgpt-5.1-chat-latestapi.openai.com/v1✓ 支持ChatGPT 同款,对话 / 课堂讲解
GPT-5 minigpt-5-miniapi.openai.com/v1✓ 支持高并发 / 批量评测降本
Claude Opus 4.7claude-opus-4-7api.anthropic.com/v1✓ 支持(tool_use 协议)旗舰,编程 / Agent / 深度诊断
Claude Sonnet 4.6claude-sonnet-4-6api.anthropic.com/v1✓ 支持日常评测 + 性价比首选
Claude Haiku 4.5claude-haiku-4-5api.anthropic.com/v1✓ 支持高并发实时反馈
Gemini 3 Flashgemini-3-flash-preview…/v1beta/openai/✓ 支持(并行 / 组合)Pro 级推理 + Flash 价位,Gemini App 默认
Gemini 3.1 Pro Previewgemini-3.1-pro-preview…/v1beta/openai/✓ 支持(thinking_level 可调)复杂多步 Agent + 编程任务
\n
\n \n 除 Claude 用 Anthropic 原生 SDK(anthropic 包,tool_use / tool_result 协议)外,其余所有模型均可通过 OpenAI Python SDK(openai 包)调用,仅需替换 base_url 与 api_key,驰声 MCP 侧代码无需改动。\n \n
\n\n \n

大部分落地场景其实是:你已有一个业务后端(教育 SaaS / 培训系统 / 客服平台),只需要新增一个「语音评测」能力。推荐架构:

\n\n
\n
\n 前端录音 / 上传\n →\n 业务后端\n →\n MCP Client(常驻连接)\n →\n 驰声 MCP\n ↘\n LLM(诊断 / 出题)\n
\n
\n\n

FastAPI 示例(生产最小骨架)

\n {`from fastapi import FastAPI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\nfrom contextlib import asynccontextmanager\n\nmcp_session: ClientSession | None = None\n\n@asynccontextmanager\nasync def lifespan(app):\n global mcp_session\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as s:\n await s.initialize()\n mcp_session = s\n yield\n mcp_session = None\n\napp = FastAPI(lifespan=lifespan)\n\n@app.post(\"/api/evaluate\")\nasync def evaluate(audio_id: str, ref_text: str):\n # 直接选一个最合适的工具执行(不经 LLM,延迟最低)\n r = await mcp_session.call_tool(\"evaluate_english_sentence\",\n {\"audioId\": audio_id, \"sentence\": ref_text})\n return {\"result\": r.content[0].text}`}\n\n 关键优化:① MCP 连接在 lifespan 里做成长连接,不要每次请求都重连;② 对延迟敏感的场景可以「跳过 LLM 直接调 tool」,把 LLM 放到「生成诊断报告」那一步。\n
\n\n
\n

方案选型速查

\n
\n \n \n \n \n \n \n \n \n \n \n \n
场景推荐方案
AI 对话 / Copilot 类产品,LLM 供应商可能会换① 官方 MCP 客户端库
已有 LangChain / Mastra / Agents SDK 技术栈② Agent 框架 + adapter
火山方舟 / 千帆控制台直连,最小侵入③ chat.completions + tools
教育 SaaS / 培训 / 客服等业务后端集成④ 自研后端 Agent
\n
\n
\n
\n\n {/* ══════ 评测模式 ══════ */}\n \n\n \n

通过本地麦克风实时录音,音频以 WebSocket 流式推送到评测服务,无需生成中间文件。这是最灵活、延迟最低的评测方式,特别适合交互式口语练习场景。

\n 实时录音评测需要安装 SoX 并使用本地代理模式(Claude Desktop / Claude Code)。Cursor 等远程直连模式暂不支持实时录音。\n\n

需要按顺序调用三个工具:

\n\n
\n
\n

create_stream_session — 创建流式评测会话

\n \n

返回 session_id,后续步骤需使用。

\n
\n\n
\n

start_recording — 开始麦克风录音

\n \n

调用后自动启动麦克风,音频通过 WebSocket 实时推送到评测服务。

\n
\n\n
\n

stop_recording — 停止录音并获取结果

\n \n
\n
\n
\n\n \n
\n \n

用户:"请评测我的英文发音,文本是 Hello"

\n

AI 调用 create_stream_session(core_type="en.word.score", ref_text="Hello")

\n

→ 获得 session_id

\n
\n \n

AI 调用 start_recording(session_id=xxx)

\n

麦克风开始录音,音频通过 WebSocket 实时推送到评测服务

\n
\n \n

用户说完后告知 AI "结束"

\n

AI 调用 stop_recording(session_id=xxx)

\n

→ 返回评测结果(总分、准确度、流利度、音素得分等)

\n
\n
\n
\n\n \n

适用于已有音频文件的评测场景,支持三种输入方式:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
参数说明适用场景
audio_file_path本地文件路径代理自动读取并转为 Base64,最便捷
audio_base64Base64 编码数据已有编码数据时使用
audio_url音频文件 URL音频托管在云存储时使用
\n
\n 推荐使用 audio_file_path,只需传入本地文件路径,代理会自动处理编码和上传。\n

支持的音频格式:mp3, wav, ogg, m4a, aac, pcm

\n

限制:单文件最大 50MB,大于 500KB 的文件自动压缩为 16kHz / 单声道 / 32kbps。

\n
\n
\n\n {/* ══════ API 参考 ══════ */}\n \n\n \n \n\n

通用参数:所有英文评测工具均支持以下参数。

\n \n
\n\n \n \n\n

通用参数:

\n \n
\n\n \n

所有评测工具返回统一的结构化结果:

\n {`{\n \"overall\": 85,\n \"accuracy\": 82,\n \"pron\": 88,\n \"fluency\": {\n \"overall\": 78,\n \"speed\": 65,\n \"pause\": 2\n },\n \"integrity\": 95,\n \"details\": [\n {\n \"char\": \"hello\",\n \"score\": 85,\n \"phone\": [\n { \"phoneme\": \"h\", \"score\": 90 },\n { \"phoneme\": \"ɛ\", \"score\": 82 },\n { \"phoneme\": \"l\", \"score\": 88 },\n { \"phoneme\": \"oʊ\", \"score\": 80 }\n ]\n }\n ]\n}`}\n
\n \n \n \n \n \n \n \n {[\n ['overall', '0–100', '综合总分,反映整体语音质量'],\n ['accuracy', '0–100', '准确度,音素级别的发音准确率'],\n ['pron', '0–100', '发音得分,整体发音质量评价'],\n ['fluency.overall', '0–100', '流利度,语流的自然度与平滑度'],\n ['fluency.speed', '0–100', '语速得分,每分钟词/音节计量'],\n ['fluency.pause', 'number', '不自然停顿次数'],\n ['integrity', '0–100', '完整度,是否完整朗读了参考文本'],\n ['details[].phone[]', 'array', '每个音素的独立评分,可定位具体弱项'],\n ['details[].stress[]', 'array', '重音得分,检测重弱读是否正确'],\n ].map(([field, range, desc]) => (\n \n \n \n \n \n ))}\n \n
字段范围说明
{field}{range}{desc}
\n
\n
\n\n \n
\n \n \n \n \n \n \n \n {[\n ['音频 ID 无效或已过期', '音频上传后 5 分钟内有效,评测完成后自动删除', '重新上传音频'],\n ['服务器繁忙', '当前请求过多,排队已满', '稍后重试,使用指数退避策略'],\n ['存储空间已满', '服务器临时音频存储已满', '稍后重试,系统会自动清理'],\n ['音频格式不支持', '上传了不支持的文件类型', '使用 mp3/wav/ogg/m4a/aac/pcm'],\n ['音频时长超限', '超过该题型最大时长限制', '裁剪音频后重试'],\n ['WebSocket 连接断开', '网络不稳定导致流式连接中断', '代理会自动重连,如持续失败请检查网络'],\n ].map(([scene, reason, fix]) => (\n \n \n \n \n \n ))}\n \n
场景原因解决方式
{scene}{reason}{fix}
\n
\n
\n
\n\n {/* ══════ 最佳实践 ══════ */}\n \n\n \n

\n 下面这些模板与{' '}\n 免费体验{' '}\n Demo 中实际使用的「教练 Prompt」一脉相承,全部围绕 角色 / 任务 / 方法 / 输出格式 / 语气 五段式结构,并使用占位符{' '}\n {'{mcp_response}'} 直接拼接 MCP 工具返回的 JSON。\n 推荐在 system 消息里挂载,再把工具返回原文塞进\n user 消息,由 LLM 基于真实分数和音素生成可读诊断 / 练习材料。\n

\n\n \n 使用建议:\n
    \n
  • 把 MCP 工具调用的完整 JSON(含 overall / dp_type / phonemes 等字段)原样塞入 {'{mcp_response}'},不要预先做汇总——细节越完整诊断越具体。
  • \n
  • 「诊断」类模板让 LLM 输出 Markdown 给最终用户阅读;「练习」类模板要求 LLM 输出严格 JSON 给前端渲染。两步分开调用,效果远好于一次性混合。
  • \n
  • 题型决定 prompt:单词题用音素级、句子题加韵律、段落题加 chunk / 整体性,半开放题套四维评级。下面按这 6 类分别给出。
  • \n
\n
\n\n {/* ─── A. 诊断类 · 输出 Markdown 给学习者阅读 ─── */}\n

\n A. 二次诊断 · 输出 Markdown\n

\n
\n
\n

\n 1. 单词级 · 音素诊断\n

\n

\n 适用工具:en.word.score / cn.word.raw。围绕 phonemes[].dp_type 找出错读音。\n

\n {`你是一位专业的英语发音教练。下面是驰声 MCP(en.word.score)返回的单词级评测数据:\n一个目标词、总分与发音分、以及带有 dp_type 的音素数组。\n\n## 任务\n为学习者写一份 **可直接阅读** 的发音诊断,每一条都要引用音素分数(写出 IPA 符号)。\n\n## 方法\n- 按 dp_type 分组:先看 mispron,再补充 normal 但分数 < 70 的\"边缘音\"。\n- 每个问题音素:① 典型母语干扰 → ② 你听到的声音 → ③ 一条具体的发音修正动作(下颌 / 舌位 / 气流 / 唇形)。\n- 重音符号 ˈ 标记的音节,重音错位也要单独列出(即便音素本身分数尚可)。\n- 最多列 4 条,按 **影响力从弱到强** 排序。\n\n## 输出\n精简 Markdown:可选一句总结 → 编号列表 → 单行 **🎯 优先级** 排序。\n\n## 语气\n友善、具体、可执行,不要空喊\"加油\"。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 2. 句子级 · 节奏 + 重音诊断\n

\n

\n 适用工具:en.sent.score。开头先给一行\"计分牌\",再从 phones → words → prosody。\n

\n {`你是一位专业的英语口语教练。下面是驰声 MCP(en.sent.score)返回的句子级数据:refText、总分、发音子分(accuracy / integrity / fluency / rhythm)、可选 speed(WPM),以及 details[] 中的逐词得分、dp_type 与可选 phonemes[]。\n\n## 任务\n开头给一行紧凑的 **计分牌**(总分 + 各子分 + 速度),再按 **音素 → 词 → 韵律** 顺序展开诊断。\n\n## 检查清单(每项都要覆盖;不适用则写\"无明显问题\")\n1. **音素级**:每个 score < 70 或 dp_type ≠ normal 的词,展开 phonemes,命名典型错误(如 /ð/ → /d/)并给一条修正动作。\n2. **漏读 / 多读**:标注 dp_type=omit / insert,解释如何拉低 integrity。\n3. **韵律**:基于 rhythm + 错读词的重音,指出重音错位、陈述句调型平直、断句过多等。\n4. **流利度 vs 准确度**:若 fluency 高但 accuracy 低,明确指出,让学习者知道优先改哪一项。\n\n## 输出格式\nMarkdown 子标题:**Pronunciation / Prosody / Study priority**(最后一行简短排序,按 ROI 从高到低)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 3. 段落级 · 音素族归并 + 完整度\n

\n

\n 适用工具:en.pred.score。把同类错音合并为\"音素族\",避免逐词复述。\n

\n {`你是一位专业的英语口语教练。下面是驰声 MCP(en.pred.score)返回的段落级数据:长 refText、总分、发音子分、可选 speed / integrity,以及大量 details[](同一个词可能在不同子句中重复出现;空 char + dp_type=omit 表示漏读)。\n\n## 任务\n对整段做 **整体诊断**:\n(a) 完整度 / 漏读,\n(b) 反复出现的 **音素族**,\n(c) 节奏与断句,\n(d) 各子分之间是否相互印证。\n\n## 检查清单\n1. **integrity / dp_type**:列出每个 omit / insert,并给出所在子句;解释长读时为什么虚词容易被吞。\n2. **音素聚类**:将弱词按共同音素问题归族(/θ/ 链、/e/ 链、/ɒ/ 等),引用 details 中的实例。\n3. **韵律**:结合 rhythm 与标点 —— 短语内停顿过多?子句边界缺失?\n4. **整体一致性**:若 fluency 正常但 accuracy 差(或反之),点明并指出对练习设计的影响。\n\n## 输出格式\nMarkdown 章节:**Summary / Completeness / Pronunciation (families) / Rhythm / Study priorities**(最后一项最多 4 条,按影响力排序)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 4. 半开放题 · IELTS 风格四维评级\n

\n

\n 适用工具:en.pqan.score。结合学习者 transcript + 四维分数,给出可教学的\"升档建议\"。\n

\n {`你是一位 **IELTS / 课堂口语风格** 的口语教练。下面是驰声 MCP(en.pqan.score)返回的半开放题数据:题目 refText、学习者 transcript、overall、四个维度分(grammar / content / fluency / pron)、speed(WPM)、以及结构化的 issues[] 标记。\n\n## 任务\n给出 **基于 rubric 的诊断**:先用一句话给出 0–100 的整体段位估计,再 **逐维度** 解释,并 **引用 transcript 中的短句**(不要复述全文)。最后给 3–5 条 **可执行的\"升档建议\"**(句型 / 模板,而不是\"多练一点\")。\n\n## 权重(要明确告诉学习者)\n- **Content ~30%** — 想法深度、举例、具体程度\n- **Grammar ~25%** — 句型多样性、主谓一致、从句\n- **Fluency ~25%** — 语速、停顿、口头禅、衔接\n- **Pronunciation ~20%** — 音素 + 可懂度\n\n## 跨维度检查\n- 若 content 最低,先给\"展开模板\",不要先抠音素。\n- 若 fluency 低 + WPM 低,区分\"思考型停顿\"与\"发音卡顿\"。\n- 若 pron 标出特定音,绑定到 transcript 里 **真实出现过的词**。\n\n## 输出格式\nMarkdown:**段位估计** → 紧凑的 **得分表格** → **\"To reach the next band\"** 编号列表(每条给出可仿写的句型)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 5. 中文专项 · 声调 / 儿化 / 变调\n

\n

\n 适用工具:cn.word.raw / cn.sent.raw / cn.pred.raw。中文评测最大权重在 **声调**,必须单独检查。\n

\n {`你是一位专业的普通话口语教练。下面是驰声 MCP(cn.sent.raw)返回的中文句子评测数据:整句分数 + 逐字 details + 可选 phonemes + 流利 / 节奏分。\n\n## 中文评测的权重\n- **声调错误权重最高** —— 声调读错可能直接改变词义\n- dp_type=mispron 多来自:声调错、平翘舌混用、前后鼻音混用\n- 拼音对、声调错,听感仍是\"洋腔洋调\"\n\n## 检查清单(缺则写\"无明显问题\")\n1. **儿化**:phonemes 出现 r(儿化) 或 dp_type 提示时,确认是否被读成\"主音节 + 单独儿\"两拍。\n2. **轻声**:叠词、词缀、句末语气词 —— 第二字应短促轻读,无完整声调曲线。\n3. **变调**:三声连读、不 + 后字、一 + 后字,是否符合普通话规则。\n4. **节奏**:用 rhythm + 逗号位置,标记停顿过长或过碎,建议 chunk 边界。\n\n## 输出\nMarkdown 子标题:**总览 / 儿化 / 轻声 / 变调 / 节奏 / 学习优先级**(最后一项 1–3 条,按\"听感自然度提升\"排序)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n {/* ─── B. 练习类 · 输出 JSON 给前端渲染 ─── */}\n

\n B. 微练习生成 · 输出严格 JSON\n

\n
\n
\n

\n 6. 单词 / 句子 · 微练习\n

\n

\n 建议在 诊断完成后 第二轮调用:让 LLM 严格按弱项音素生成,避免\"通用绕口令包\"。\n

\n {`你仍是这位学习者的发音教练。**第二轮诊断已经完成** —— 现在严格基于诊断里点名的弱音素,生成 **1:1 对应** 的微练习(不要给通用题)。\n\n## 输出(仅返回一段合法 JSON 数组,外层不要任何文字)\n根节点必须是数组,每个元素含 category(字符串)、icon(单个 emoji)、items({ \"label\", \"content\" } 数组)。\n\\`\\`\\`json\n[\n { \"category\": \"Phoneme drills\", \"icon\": \"🎯\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Awareness\", \"icon\": \"🗣️\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Whole word\", \"icon\": \"📝\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] }\n]\n\\`\\`\\`\n\n## 规则\n- **Phoneme drills**:诊断里每个 mispron 音素至少给一对最小对立对 + 一句短绕口令 / 重复句。\n- **Awareness**:当重音偏弱时,给一条 stress / 舌位 / 下颌姿态提示。\n- **Whole word**:2–3 句自然句,目标词分别出现在句首 / 句中 / 句末。\n- 所有 content 必须可念出声;字符串内不要再嵌套 JSON。\n\n## 上下文\n诊断结论:{previous_diagnosis}\n原始 MCP:\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 7. 段落 · Chunk Map + 元认知\n

\n

\n 段落级练习要从\"音素\"上升到\"短语 / 整段 / 元认知录回放\"。直接对应 en.pred.score 的诊断结果。\n

\n {`你仍是这位学习者的口语教练。**段落级二次诊断** 已经列出了漏读位置和音素族 —— 现在请生成 **整段练习**:把弱音素串成\"族\"练习、用 chunk map 把虚词粘回短语,并附一条录音 → 回放 → 对照 MCP details 的元认知步骤。\n\n## 输出(仅返回一段合法 JSON 数组)\n\\`\\`\\`json\n[\n { \"category\": \"Phoneme families\", \"icon\": \"🎯\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Chunking\", \"icon\": \"🎵\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Metacognition\", \"icon\": \"🧠\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] }\n]\n\\`\\`\\`\n\n## 规则\n- **Phoneme families**:至少 3 条,按诊断里的音素族(/θ/、/e/、/ɒ/ 等)组织最小对立对 / 词链。\n- **Chunking**:① 给一行用 [ ] 和 / 标注的 chunk map(可加大致停顿秒数);② 给一句\"把漏掉的虚词嵌入短语\"的练习(不要孤立练)。\n- **Metacognition**:一条\"录音 → 回放 → 对照 MCP details\"的 N 遍练习(N 写明,2–3 之间)。\n- 字符串只能是纯展示文本,禁止嵌套 JSON。\n\n## 上下文\n诊断结论:{previous_diagnosis}\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n {/* ─── C. 跨题 / 运营 ─── */}\n

\n C. 跨题 / 运营\n

\n
\n
\n

\n 8. 多日学习报告\n

\n

\n 把过去 N 天的 MCP 评测结果聚合后丢给 LLM,输出适合发给学生 / 家长的周报。\n

\n {`你是一位英语口语学习顾问。下面是这位学习者过去 7 天的驰声 MCP 评测历史(按时间顺序),每条包含题型、coreType、overall、子分、weak_phonemes 摘要。\n\n## 任务\n为学习者生成一份 **周报**,目标读者:本人 + 家长 / 老师。\n强调 **趋势** 与 **下一步计划**,不要复述每一次具体分数。\n\n## 必须包含\n1. **整体趋势**:进步 / 持平 / 退步(一句话 + 简短依据)\n2. **维度变化**:accuracy / fluency / rhythm / integrity / speed 任意有数据的维度,给出\"本周均分 vs 上周\"\n3. **本周高光**:分数提升最大的题型 / 音素 / 句型\n4. **顽固问题**:连续 3 次以上未达 70 的音素或维度\n5. **下周计划**:3 条具体动作(每条对应一个 MCP 工具或一个练习类型)\n6. **结尾**:1–2 句鼓励性总结,避免空话\n\n## 风格\n- 像一位认真但不啰嗦的私教\n- 出现学生姓名时使用占位 {student_name}\n- 数字一律保留整数\n\n## 评测历史\n\\`\\`\\`json\n{history}\n\\`\\`\\``}\n
\n\n
\n

\n 9. 错误归因 · JSON 摘要\n

\n

\n 用于后端聚合 / 数据看板:让 LLM 把一次评测压缩成结构化摘要,方便入库统计。\n

\n {`你是一个评测结果归类器。下面是驰声 MCP 一次评测的完整返回。请抽取关键信息并 **仅返回合法 JSON**(不要任何解释文字)。\n\n## Schema\n\\`\\`\\`json\n{\n \"core_type\": \"string,例如 en.sent.score\",\n \"overall\": 0,\n \"sub_scores\": { \"accuracy\": 0, \"integrity\": 0, \"fluency\": 0, \"rhythm\": 0 },\n \"weak_phonemes\": [\n { \"ipa\": \"string\", \"avg_score\": 0, \"occur\": 0, \"example_word\": \"string\" }\n ],\n \"omissions\": [{ \"after\": \"string\", \"missing\": \"string\" }],\n \"stress_issues\": [{ \"word\": \"string\", \"expected\": \"string\", \"actual\": \"string\" }],\n \"primary_issue_tag\": \"phoneme|stress|fluency|integrity|content|none\",\n \"next_action_hint\": \"string,10 字以内,例如 \\\"练 /θ/ 对立对\\\"\"\n}\n\\`\\`\\`\n\n## 规则\n- weak_phonemes 只收 avg_score < 70 的项,最多 5 项,按 occur 降序。\n- 不要复述 refText,不要 markdown。\n- 字段缺失时使用 null 或空数组,不要省略 key。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n \n 怎么接到 MCP 工具调用?\n
\n 以「直调 chat.completions + 动态 tools」为例:第一轮 LLM 调出 en.sent.score 工具,把工具 result(即 tool 消息内容)原样填入上面任意「诊断」模板的{' '}\n {'{mcp_response}'},作为第二轮 user 消息发回;拿到诊断结论再走第三轮,套「微练习」模板得到 JSON。三轮调用即可串起 评测 → 诊断 → 练习 全链路。\n
\n
\n\n \n
    \n
  • 音频过期:上传后 5 分钟内有效。建议在上传后 3 分钟内完成评测。
  • \n
  • 服务繁忙:使用指数退避策略重试(1s → 2s → 4s),最多 3 次。
  • \n
  • 录音中断:WebSocket 断线后代理会自动重连。如持续失败,检查网络连接和 SoX 安装。
  • \n
\n
\n\n \n
    \n
  • 优先使用流式评测:实时录音模式跳过了文件上传环节,端到端延迟比文件评测低 30-50%。
  • \n
  • 音频压缩:文件评测时,上传前将音频转为 16kHz 单声道 mp3,可减少 60-80% 的上传体积。
  • \n
  • 选择合适的工具:单词评测比段落评测快 3-5 倍。如只需单词级分数,不要用句子评测。
  • \n
  • 本地文件路径最便捷:使用 audio_file_path 参数传入本地路径,代理自动处理编码,无需手动转 Base64。
  • \n
\n
\n
\n\n {/* ══════ 服务信息 ══════ */}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n
端点方法说明
/uploadPOST音频文件上传
/mcpPOSTMCP JSON-RPC 接口(Streamable HTTP)
/healthGET健康检查
\n
\n
\n \n
\n \n \n \n \n \n \n \n {[\n ['存储限制', '500MB', '最大音频存储空间'],\n ['最大排队', '10', '等待处理的请求数'],\n ['最大并发', '3', '同时处理的评测数'],\n ['音频有效期', '5 分钟', '上传后未评测自动过期'],\n ['文件大小限制', '50MB', '单个音频文件最大'],\n ].map(([k, v, d]) => (\n \n ))}\n \n
配置项默认值说明
{k}{v}{d}
\n
\n

\n 上表为托管侧技术默认;计费与试用/商用调用配额、并发档位以{' '}\n \n 会员套餐\n \n 说明为准,与上表独立。\n

\n
\n \n \n 当前线上版本:v1.0.0(网站未正式上线)。以下变更项为开发阶段规划记录,以正式发布公告为准。\n \n
\n {[\n { ver: 'v1.0.0', date: 'TBD', desc: '当前线上版本(网站未正式上线)' },\n ].map(l => (\n
\n {l.ver}\n {l.date}\n {l.desc}\n
\n ))}\n
\n
\n
\n\n \n );\n}\n\nexport default function DocsPage() {\n const locale = useLocale();\n return locale.startsWith('zh') ? : ;\n}\n"}, "fdbdbf4fba51ea8d4a904cd233d4d6d47fd62592": {"t": 1785765793.677472, "n": 145186, "h": "698501e54defff53", "c": "'use client';\n\nimport { useLocale } from 'next-intl';\nimport { Link } from '@/i18n/routing';\nimport { DocsShell, type NavGroup } from './docs-shell';\nimport {\n CodeBlock,\n DocSection,\n SubDoc,\n ParamTable,\n Callout,\n FlowStep,\n ToolTable,\n} from './docs-shared';\nimport { DocsEnglishBody } from './docs-content-en';\nimport {\n BookOpen,\n Code2,\n Zap,\n FileText,\n Terminal,\n Globe,\n Mic,\n MessageSquare,\n BarChart3,\n AlertTriangle,\n Radio,\n FolderOpen,\n Workflow,\n Sparkles,\n Plug,\n Bot,\n Building2,\n Check,\n Sparkle,\n Languages,\n GraduationCap,\n Notebook,\n Gauge,\n ListChecks,\n} from 'lucide-react';\n\n/* ─── Navigation Structure ─── */\n\nconst NAV = [\n { id: 'concept', icon: Workflow, label: 'MCP 工作原理', children: [\n { id: 'why-mcp', label: '为什么需要 MCP' },\n { id: 'scenario-walkthrough', label: '场景走查 · 6 步' },\n { id: 'dev-responsibility', label: '开发者只做两件事' },\n { id: 'integration-paths', label: '三种接入姿势' },\n ]},\n { id: 'architecture', icon: Terminal, label: '架构说明', children: [\n { id: 'arch-diagram', label: '架构图' },\n { id: 'transport', label: '传输协议' },\n ]},\n { id: 'quick-start', icon: Zap, label: '快速开始', children: [\n { id: 'overview', label: '概述' },\n { id: 'requirements', label: '系统要求' },\n { id: 'install', label: '安装方式' },\n { id: 'env-vars', label: '环境变量' },\n ]},\n { id: 'config', icon: Plug, label: '接入 · 直接用(零代码)', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: '扣子(Coze)' },\n { id: 'config-coze-workflow', label: 'Coze 工作流' },\n { id: 'config-ai-workspace', label: 'AI 工作台 · 豆包 / 飞书 / WorkBuddy / 钉钉' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: '其他 MCP 客户端' },\n ]},\n { id: 'config-code', icon: Code2, label: '接入 · 编程用(SDK / 代码)', children: [\n { id: 'code-mcp-sdk', label: '官方 MCP 客户端库' },\n { id: 'code-agent-frameworks', label: 'LangChain / Mastra / Agents SDK' },\n { id: 'code-function-calling', label: '直调 chat.completions · 上传与动态 tools' },\n { id: 'llm-deepseek', label: 'DeepSeek' },\n { id: 'llm-glm', label: 'GLM(智谱)' },\n { id: 'llm-kimi', label: 'KIMI(Moonshot)' },\n { id: 'llm-doubao', label: '豆包 Seed 2.0(火山方舟)' },\n { id: 'llm-openai', label: 'OpenAI(GPT-5.1)' },\n { id: 'llm-claude', label: 'Claude(Anthropic)' },\n { id: 'llm-gemini', label: 'Gemini(Google)' },\n { id: 'llm-comparison', label: '模型对比速查' },\n { id: 'code-selfhosted-agent', label: '自研后端 Agent' },\n ]},\n { id: 'eval-modes', icon: Radio, label: '评测模式', children: [\n { id: 'stream-eval', label: '实时录音评测' },\n { id: 'stream-flow', label: '流式评测流程' },\n { id: 'file-eval', label: '音频文件评测' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API 参考', children: [\n { id: 'tools-en', label: '英文评测工具' },\n { id: 'tools-cn', label: '中文评测工具' },\n { id: 'result-fields', label: '评测结果字段' },\n { id: 'error-codes', label: '错误码' },\n ]},\n { id: 'best-practices', icon: FileText, label: '最佳实践', children: [\n { id: 'prompt-templates', label: 'Prompt 模板' },\n { id: 'error-handling', label: '错误处理' },\n { id: 'performance', label: '性能优化' },\n ]},\n { id: 'service-info', icon: Globe, label: '服务信息', children: [\n { id: 'endpoints', label: '服务端点' },\n { id: 'limits', label: '服务限制' },\n { id: 'changelog', label: '更新日志' },\n ]},\n];\n\nconst NAV_EN: NavGroup[] = [\n { id: 'concept', icon: Workflow, label: 'How MCP works', children: [\n { id: 'why-mcp', label: 'Why MCP' },\n { id: 'scenario-walkthrough', label: 'Scenario · 6 steps' },\n { id: 'dev-responsibility', label: 'Two developer tasks' },\n { id: 'integration-paths', label: 'Three integration styles' },\n ]},\n { id: 'architecture', icon: Terminal, label: 'Architecture', children: [\n { id: 'arch-diagram', label: 'Diagram' },\n { id: 'transport', label: 'Transports' },\n ]},\n { id: 'quick-start', icon: Zap, label: 'Quick start', children: [\n { id: 'overview', label: 'Overview' },\n { id: 'requirements', label: 'Requirements' },\n { id: 'install', label: 'Install' },\n { id: 'env-vars', label: 'Environment' },\n ]},\n { id: 'config', icon: Plug, label: 'Zero-code clients', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: 'Coze' },\n { id: 'config-coze-workflow', label: 'Coze workflows' },\n { id: 'config-ai-workspace', label: 'Enterprise AI workspaces' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: 'Other MCP clients' },\n ]},\n { id: 'config-code', icon: Code2, label: 'SDK / code integration', children: [\n { id: 'code-mcp-sdk', label: 'Official MCP SDK' },\n { id: 'code-agent-frameworks', label: 'Agent frameworks' },\n { id: 'code-function-calling', label: 'chat.completions · upload & tools' },\n { id: 'llm-deepseek', label: 'DeepSeek' },\n { id: 'llm-glm', label: 'GLM (Zhipu)' },\n { id: 'llm-kimi', label: 'KIMI (Moonshot)' },\n { id: 'llm-doubao', label: 'Doubao Seed 2.0 (Volcano Ark)' },\n { id: 'llm-qwen', label: 'Qwen (Alibaba)' },\n { id: 'llm-openai', label: 'OpenAI (GPT-5.1)' },\n { id: 'llm-claude', label: 'Claude (Anthropic)' },\n { id: 'llm-gemini', label: 'Gemini (Google)' },\n { id: 'llm-comparison', label: 'Model comparison' },\n { id: 'code-selfhosted-agent', label: 'Custom backend' },\n ]},\n { id: 'eval-modes', icon: Radio, label: 'Evaluation modes', children: [\n { id: 'stream-eval', label: 'Streaming mic' },\n { id: 'stream-flow', label: 'Streaming flow' },\n { id: 'file-eval', label: 'Audio files' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API reference', children: [\n { id: 'tools-en', label: 'English tools' },\n { id: 'tools-cn', label: 'Chinese tools' },\n { id: 'result-fields', label: 'Result fields' },\n { id: 'error-codes', label: 'Errors' },\n ]},\n { id: 'best-practices', icon: FileText, label: 'Best practices', children: [\n { id: 'prompt-templates', label: 'Prompt templates' },\n { id: 'error-handling', label: 'Errors & retries' },\n { id: 'performance', label: 'Performance' },\n ]},\n { id: 'service-info', icon: Globe, label: 'Service info', children: [\n { id: 'endpoints', label: 'Endpoints' },\n { id: 'limits', label: 'Limits' },\n { id: 'changelog', label: 'Changelog' },\n ]},\n];\n\n/* ─── Page(英文 / 中文拆成两个组件,避免切换语言时 Hooks 数量变化导致白屏)─── */\n\nfunction DocsPageEn() {\n return (\n \n \n \n );\n}\n\nfunction DocsPageZh() {\n return (\n \n {/* ══════ MCP 工作原理 ══════ */}\n \n\n \n

\n 大模型(GPT / Claude / Gemini / 通义千问 等)本质上是文字大脑:它擅长读和写,但天生听不到音频、打不开你的数据库、调不通第三方 API。\n

\n

\n MCP(Model Context Protocol)是一套由 Anthropic 主导、业界共同推进的开放协议,它像一根\"对讲机\":让大模型可以在需要时主动去调用外部能力(工具、数据源、服务),然后把结果接回来继续对话。\n

\n
\n
\n
\n \n 没有 MCP 的做法\n
\n
    \n
  • · 研究评测服务的 REST 文档
  • \n
  • · 自己写鉴权 / 上传 / 轮询代码
  • \n
  • · 把结果序列化后塞进 prompt
  • \n
  • · 每换一个大模型都得重写一遍
  • \n
\n
\n
\n
\n \n 用驰声 MCP 之后\n
\n
    \n
  • · 填一行 MCP Server 地址
  • \n
  • · 大模型自动发现&调用评测工具
  • \n
  • · 换任何支持 MCP 的大模型都能用
  • \n
  • · 不写一行调用代码
  • \n
\n
\n
\n \n MCP 让\"接入语音评测\"从一个\"后端工程\"变成了一个\"配置项\"。这也是为什么 Cursor、Claude Desktop、Dify、Coze、字节豆包、飞书智能助手都已经原生支持 MCP。\n \n
\n\n \n

\n 想象一个具体场景:一位开发者用 Claude 做了一款 「AI 雅思口语陪练」小程序,接入驰声语音评测 MCP。当用户发来一段录音,整个链路是这样的:\n

\n
\n \n

配置阶段(开发者 · 一次性)

\n

在 AI 后端的配置文件里填一行驰声 MCP Server 地址。大模型启动时自动发现:「我多了一个叫语音评测的工具」。

\n
\n \n

接收用户指令(终端用户)

\n

小程序用户发来一段自我介绍录音:「帮我听听,发音哪里有问题?」后端把「文字 + 录音链接」打包给大模型。

\n
\n \n

大模型自主思考(LLM · 最核心的魔法)

\n
\n 「用户让我听发音。」
\n 「但我只是文字大脑,我听不到。」
\n 「等等 —— 开发者给了我一个叫 chivox_voice_eval 的 MCP 工具!」\n
\n
\n \n

MCP 协议 · 自动调用(LLM → 驰声)

\n

大模型自动按 MCP 标准构造 tools/call 请求,把录音链接和参考文本发到驰声服务。开发者不需要写任何调用代码。

\n
\n \n

驰声服务处理(评测引擎)

\n

驰声对音频进行考试级打分,把结构化结果通过 MCP 原路返回:overall 85、/θ/ 音发音错误、流利度 88。

\n
\n \n

大模型整合并输出反馈(LLM)

\n

大模型把冷冰冰的分数翻译成温柔反馈:

\n
\n 「你的自我介绍很棒!综合 85 分 🎉 不过 think 这个词的 /θ/ 咬舌音不太标准,我们一起来练一下……」\n
\n
\n
\n \n 整条链路里,MCP 只出现在 ① 和 ④:① 让开发者一次性告诉大模型「你多了一个工具」,④ 让大模型可以自动调用它。这两步的标准化,就是 MCP 的全部价值。\n \n
\n\n \n

听起来复杂,但对开发者来说只需要两件事:

\n
\n
\n
\n 1\n 填一次 MCP 配置\n
\n

\n 在 AI 后端的配置里填入驰声 MCP Server 地址和 API Key,就这一次,以后新加评测能力完全免开发。\n

\n {`{\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"apiKey\": \"sk-••••••••••\"\n }\n}`}\n
\n
\n
\n 2\n 写一段 System Prompt\n
\n

\n 告诉大模型这个工具是做什么的、什么时候调用、结果怎么转成用户友好的反馈。\n

\n {`你是一位英语口语教练。\n当用户发来录音时:\n1. 调用 chivox_voice_eval 评分\n2. 聚焦 <70 分的音素家族\n3. 用高情商话术给出练习建议`}\n
\n
\n

\n 其余所有事情 —— 音频上传、鉴权、工具发现、调用时机、返回格式、结果整合 —— 都由 MCP 协议和大模型自己搞定。\n

\n
\n\n \n

根据你的技术栈,有三种等价的接入方式,底层都走完全相同的 MCP 协议:

\n\n {/* ── 姿势一:可视化 ── */}\n
\n
\n \n

姿势一 · 可视化拖拽(扣子 / Coze / 飞书智能助手)

\n
\n

\n 适合产品经理、运营、不写后端代码的开发者。整个过程像在手机上装 App。\n

\n
    \n
  1. 找到入口:在扣子平台的 「插件 / 工具」 配置区,点击「添加 MCP 服务」。
  2. \n
  3. 填两个字段(这也是你未来会从驰声这边拿到的):\n
    \n \n \n \n \n \n
    服务器地址https://speech-eval.site/mcp
    鉴权密钥sk-•••••••••• (由驰声分配,用于计费与识别)
    \n
    \n
  4. \n
  5. 平台自动发现能力:扣子会访问你填的地址,读取 MCP Server 自描述的\"说明书\"。瞬间明白:「这是个语音评测工具,需要传音频,会返发音分」。
  6. \n
  7. 右侧测试:在平台的聊天框里发一段语音,大模型就会自动调用工具。整个过程不需要写一行代码。
  8. \n
\n
\n\n {/* ── 姿势二:代码框架 ── */}\n
\n
\n \n

姿势二 · 代码框架配置(Dify / LangChain / 自研后端)

\n
\n

\n 适合做独立 APP / 小程序、用 Dify 或 LangChain 写 Agent 的极客开发者。核心就是往配置文件里加一段 JSON。\n

\n
    \n
  1. 打开配置文件(项目根目录下的 mcp.json 或框架指定的配置路径)。
  2. \n
  3. 在 mcpServers 下增加一个节点:\n {`{\n \"mcpServers\": {\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"env\": {\n \"API_KEY\": \"你的专属密钥\"\n }\n }\n }\n}`}\n
  4. \n
  5. 重启后端服务。大模型的底层调度器会在启动时自动连上驰声 MCP Server,把 16 种评测工具注册成随时待命的 tools。
  6. \n
  7. 触发调用:用户发来录音后,大模型看到 system prompt 的引导,自动选择合适的工具(单词/句子/段落/半开放)调用。
  8. \n
\n
\n\n {/* ── 姿势三:Function Calling 直连(分 A / B 两种做法) ── */}\n
\n
\n \n

姿势三 · 原生 Function Calling(豆包 / DeepSeek / OpenAI 兼容 API)

\n
\n

\n 适合不用任何 Agent 框架、直接调用 LLM API 的后端开发者。豆包 1.5+ / DeepSeek / GPT / Qwen 等模型都走标准 chat.completions 的 tools 参数。这里又分 A / B 两种做法,B 才是生产推荐。\n

\n\n \n 常见疑问:\"要不要手写一个 tool 定义?\"
\n — 姿势一 / 二不用(Coze、Dify、火山方舟控制台、Claude Desktop 会自动从 MCP Server 拉工具列表)。
\n — 姿势三看你选 A 还是 B:A 要手写,B 用 MCP 客户端库自动拉。\n
\n\n {/* ── 3-A:手写 tool schema ── */}\n
\n
\n

3-A · 手写 tool schema(最快验证,不推荐生产)

\n 快速 Demo\n
\n

\n 自己写一段 JSON Schema 告诉豆包\"有个工具叫 xxx,参数长这样\",豆包返回 tool_call 后你再手动去调驰声 MCP。缺点:驰声有 16 个评测工具,你每加一个题型都要改代码。\n

\n {`import os, json\nfrom openai import OpenAI\n\nclient = OpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv('ARK_API_KEY'),\n)\n\n# ─── 手写一段 tool schema(不推荐:16 个工具就要写 16 段)───\ntools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": \"en_word_eval\",\n \"description\": \"英语单词发音评测。当用户让你评价英语发音并提供录音链接时调用。\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"audio_url\": {\"type\": \"string\", \"description\": \"录音 URL\"},\n \"reference_text\": {\"type\": \"string\", \"description\": \"参考文本,如 Apple\"},\n },\n \"required\": [\"audio_url\", \"reference_text\"]\n }\n }\n}]\n\nresp = client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,拿到评测结果后温柔地反馈,不要直接报分数。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n)\n\nmsg = resp.choices[0].message\nif msg.tool_calls:\n args = json.loads(msg.tool_calls[0].function.arguments)\n # ↓↓↓ 这里手动调驰声 MCP,再把结果回填给豆包做第二趟 ↓↓↓\n # result = requests.post(\"https://speech-eval.site/mcp\", json={...})`}\n
\n\n {/* ── 3-B:MCP 自动发现 ── */}\n
\n
\n

\n 3-B · 用 MCP 客户端库自动发现 \n

\n 生产推荐\n
\n

\n 启动时连上驰声 MCP Server,调一次 tools/list,把 16 个评测工具自动转成 Function Calling 的 tools 格式。驰声加新工具,你代码不用改。这才是 MCP 协议的真正价值。\n

\n {`import asyncio, os\nfrom openai import AsyncOpenAI\nfrom mcp import ClientSession\nfrom mcp.client.streamable_http import streamablehttp_client\n\nclient = AsyncOpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv(\"ARK_API_KEY\"),\n)\n\nasync def main():\n # ─── 1. 连驰声 MCP Server,自动拉取全部 16 个工具 ───\n async with streamablehttp_client(\n \"https://speech-eval.site/mcp\",\n headers={\"Authorization\": f\"Bearer {os.getenv('CHIVOX_KEY')}\"},\n ) as (read, write, _):\n async with ClientSession(read, write) as session:\n await session.initialize()\n mcp_tools = (await session.list_tools()).tools # ← 一行拿到全部工具\n\n # ─── 2. MCP schema → OpenAI Function Calling schema ───\n tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema, # MCP 直接给 JSON Schema\n }\n } for t in mcp_tools]\n\n # ─── 3. 正常调豆包,tools 由 MCP 动态注入 ───\n resp = await client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,收到评测结果后温柔反馈。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n )\n\n # ─── 4. 折返跑:豆包选好工具后,直接走 MCP 调驰声 ───\n msg = resp.choices[0].message\n if msg.tool_calls:\n call = msg.tool_calls[0]\n result = await session.call_tool(\n call.function.name,\n arguments=__import__(\"json\").loads(call.function.arguments),\n )\n # 把 result 回填给豆包做第二趟 chat.completions 即可\n\nasyncio.run(main())`}\n

\n 想要更省心?直接用 官方 mcp python sdk、mcp-use、openai-agents,或火山官方 Arkitect 高代码 SDK,它们都把上面这段\"MCP → Function Calling\"的桥接封装好了。\n

\n
\n
\n\n \n 三种姿势走的是完全相同的 MCP 协议,能力完全等价。选型建议:产品经理 / 原型验证用姿势一(Coze 填表单);AI 客户端用户用姿势二(Cursor / Claude Desktop 填 mcp.json);后端生产服务用姿势三-B(MCP 客户端库自动发现工具,不要手写 tool schema)。\n \n
\n\n
\n\n {/* ══════ 架构说明 ══════ */}\n \n\n \n
\n
\n

AI 客户端

\n

Claude Desktop
Claude Code
Cursor

\n
\n
\n

⇄

\n

stdio

\n
\n
\n

chivox-local-mcp

\n

本地代理
SoX 录音

\n
\n
\n

⇄

\n

HTTP / WS

\n
\n
\n

Remote Chivox

\n

MCP Server
评测引擎

\n
\n
\n
\n\n \n
    \n
  • \n \n stdio — AI 客户端通过标准输入输出与本地代理通信,这是 MCP 的标准传输方式\n
  • \n
  • \n \n HTTP — 音频文件评测工具通过 HTTP 代理到远程服务,适用于非流式场景\n
  • \n
  • \n \n WebSocket — 实时录音音频通过 WebSocket 流式推送,支持断线自动重连\n
  • \n
\n
\n
\n\n {/* ══════ 快速开始 ══════ */}\n \n\n \n

chivox-local-mcp 是驰声语音评测的 MCP 本地代理,通过 Model Context Protocol 将远程驰声评测服务桥接到本地,让 AI 助手(Claude Desktop、Claude Code、Cursor 等)直接调用语音评测能力。

\n

它支持两种评测模式,覆盖从即时交互到批量处理的全部场景:

\n
\n
\n
\n \n 实时录音评测\n
\n

通过麦克风边录边评,音频以 WebSocket 流式推送,无需生成中间文件,延迟更低、体验更佳。

\n
\n
\n
\n \n 音频文件评测\n
\n

支持本地文件路径、Base64 编码、URL 三种输入,适合已有音频的批量评测场景。

\n
\n
\n 当前支持 16 种评测工具:英文 10 种(单词、句子、段落、纠音、自然拼读、口语选择、半开放题等)+ 中文 6 种(汉字、拼音、词句、段落、有限分支、AI Talk)。\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n
依赖版本说明
Node.js{'>'}= 18运行时必须
SoXany仅实时录音功能需要(处理麦克风音频流)
\n
\n

安装 SoX(仅在使用实时录音时需要):

\n {`# macOS\nbrew install sox\n\n# Ubuntu / Debian\nsudo apt-get install sox`}\n
\n\n \n

方式一:npm 全局安装(推荐)

\n {`npm install -g chivox-local-mcp`}\n\n

方式二:npx 免安装运行

\n {`MCP_REMOTE_URL=http://your-server:8080 npx chivox-local-mcp`}\n\n

方式三:从源码构建

\n {`git clone https://git.chivox.com/CLOUD_DEV/cvx_local_mcp.git\ncd cvx_local_mcp\nbash scripts/build.sh`}\n
\n\n \n \n \n
\n\n {/* ══════ 接入 · 直接用(零代码) ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 不用写代码、不用装 SDK,只在客户端的「MCP 配置」或「扩展」里填一段 JSON / URL
  • \n
  • 保存后 LLM 自动发现 16 个评测工具,并在对话 / Agent 中自主调用
  • \n
  • 覆盖 IDE 编程助手、桌面 AI 客户端、企业 AI 工作台、可视化 Bot / 工作流平台四大生态
  • \n
\n
\n\n\n \n
    \n
  1. 打开 Cursor 设置(Cmd + ,)
  2. \n
  3. 左侧选择 MCP(或搜索 "MCP")
  4. \n
  5. 点击 Add new MCP server
  6. \n
  7. 填写配置并保存:
  8. \n
\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n}`}\n Cursor 使用远程 Streamable HTTP 模式直连,无需安装本地代理。如需实时录音功能,请使用下方 Claude Desktop 的本地代理配置。\n
\n\n \n

编辑配置文件(macOS:~/Library/Application Support/Claude/claude_desktop_config.json):

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"chivox-local-mcp\",\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\",\n \"MCP_API_KEY\": \"your-api-key\"\n }\n }\n }\n}`}\n

如果是从源码构建:

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/cvx_local_mcp/dist/index.js\"],\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\"\n }\n }\n }\n}`}\n Claude Desktop 使用本地代理模式(stdio),支持实时录音评测。本地代理会自动桥接远程服务。\n
\n\n \n {`# npm 全局安装后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 chivox-local-mcp\n\n# 源码构建后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 node /path/to/cvx_local_mcp/dist/index.js`}\n \n\n \n

除了 Cursor 和 Claude Code,主流的 AI 编程 IDE 都原生支持 MCP。以下客户端使用完全一致的 Streamable HTTP 配置,区别只在配置入口:

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
客户端配置入口备注
Windsurf (Codeium)Settings → Cascade → MCP Servers直接贴下方 JSON
Zed~/.config/zed/settings.json 的 context_serversAssistant Panel 自动发现
Continue (VS Code / JetBrains)config.yaml 的 mcpServersv0.9+ 支持
通义灵码 / CodeGeeX / 文心快码插件设置 → MCP 服务2026 Q1 起陆续支持
Cline (原 Claude Dev)MCP Servers 面板 → 编辑配置VS Code 扩展
\n
\n {`{\n \"mcpServers\": {\n \"chivox-speech-eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n }\n }\n}`}\n 所有 IDE 类客户端都走远程 Streamable HTTP,零本地依赖。需要实时录音才需切到 Claude Desktop 的本地代理模式。\n
\n\n \n

扣子(Coze)是字节跳动推出的 AI 应用开发平台,支持通过 MCP 扩展为 Agent 赋予外部工具能力。接入驰声语音评测后,你可以构建口语练习 Bot、发音诊断助手等应用。

\n

方式一:扣子空间 MCP 扩展(推荐)

\n
    \n
  1. 打开 扣子空间(space.coze.cn)
  2. \n
  3. 在对话框下方点击 「添加扩展」
  4. \n
  5. 选择 「自定义」 标签,点击添加新的 MCP 服务
  6. \n
  7. 填入以下配置信息:
  8. \n
\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
名称chivox-speech-eval
传输类型streamable-http
URLhttps://speech-eval.site/mcp
\n
\n
    \n
  1. 保存后,在对话中输入 「帮我评测这段英文发音」 即可触发 Agent 调用
  2. \n
\n 添加 MCP 扩展后,扣子空间的 Agent 会自动识别并调用评测工具。你可以在 Agent 的思考过程中看到具体的工具调用细节。\n\n

方式二:在 Coze 开发平台的 Bot 中使用

\n
    \n
  1. 进入 Coze 开发平台,创建或编辑 Bot
  2. \n
  3. 在 Bot 的 「插件」 或 「工具」 面板中,添加 MCP 工具
  4. \n
  5. 选择 Streamable HTTP 类型,填入 URL:https://speech-eval.site/mcp
  6. \n
  7. Bot 将自动发现所有可用的评测工具(如 evaluate_english_word 等)
  8. \n
  9. 在 Bot 的人设提示词中,添加语音评测相关的引导语
  10. \n
\n {`你是一位专业的英语口语教练。当用户上传音频并请求评测时:\n1. 使用 evaluate_english_word / evaluate_english_sentence 等工具进行评测\n2. 根据评测结果(overall、accuracy、fluency 等分数)给出专业分析\n3. 针对得分较低的维度提供具体改进建议\n4. 鼓励用户持续练习`}\n
\n\n \n

如果你需要在 Coze 工作流中集成语音评测能力,可以通过 HTTP Request 节点调用评测 API:

\n\n

步骤 1:上传音频

\n

在工作流中添加一个 HTTP Request 节点,配置如下:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
配置项值
方法POST
URLhttps://speech-eval.site/upload
Content-Typeaudio/mp3
Body音频文件二进制数据
\n
\n

响应中获取 {'{{audioId}}'},传递给下一步。

\n\n

步骤 2:调用评测

\n

添加第二个 HTTP Request 节点,通过 MCP 接口调用评测工具:

\n {`{\n \"jsonrpc\": \"2.0\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"evaluate_english_sentence\",\n \"arguments\": {\n \"audioId\": \"{{audioId}}\",\n \"sentence\": \"{{ref_text}}\"\n }\n },\n \"id\": 1\n}`}\n\n

步骤 3:处理结果

\n

评测结果通过 JSON 格式返回,可使用 Coze 的 代码节点 或 LLM 节点 对结果进行解析和二次处理(如生成学习建议、计算进步趋势等)。

\n\n 工作流方式适合需要固定流程的场景(如批量评测、定时任务、与其他系统联动)。如果是交互式场景,推荐使用上方的 MCP 扩展方式,Agent 会自动选择合适的工具。\n\n
\n

完整工作流示意

\n
\n 用户输入音频\n →\n HTTP: 上传音频\n →\n HTTP: 调用评测\n →\n LLM: 分析结果\n →\n 输出反馈\n
\n
\n
\n\n \n

这一类是面向「上班族」的企业 / 日常 AI 助手,产品形态是个聊天框 + 插件市场 / 扩展面板。接入后,员工在 App 里打字「帮我评一下这段录音」就能自动触发驰声评测,不用写任何代码。

\n\n
\n
\n

豆包(Doubao)App / 桌面版

\n

字节跳动官方 AI 助手,2026 年起桌面版支持 MCP 扩展。

\n
    \n
  1. 桌面版设置 → 「智能体扩展」 → 添加 MCP 服务
  2. \n
  3. 类型选 streamable-http,URL 填 https://speech-eval.site/mcp
  4. \n
  5. 对话中直接说「帮我评测」即可自动调用
  6. \n
\n
\n\n
\n

飞书智能伙伴(My AI)

\n

飞书企业 AI,支持以 MCP / Function Calling 挂载外部工具给团队 Bot。

\n
    \n
  1. 飞书开发者后台 → 创建应用 → 「AI 能力 / 智能伙伴」
  2. \n
  3. 在「工具」中选 外部 MCP 服务,填入上方 URL
  4. \n
  5. 把智能伙伴拉进群聊,@ 它提交音频即可评测
  6. \n
\n
\n\n
\n

WorkBuddy / 企业智能助手

\n

字节 WorkBuddy、腾讯会议 AI、企业微信智能助手等企业 AI 工作台场景。

\n
    \n
  1. 在工作台的「技能 / 扩展」后台新增一个 MCP 连接器
  2. \n
  3. 传输协议选 Streamable HTTP,地址填 https://speech-eval.site/mcp
  4. \n
  5. 把技能发布到指定部门 / 群组,HR、培训、销售口语陪练场景即可直接用
  6. \n
\n
\n\n
\n

钉钉 AI 助理 / 通义千问 App

\n

阿里生态:钉钉 AI 助理支持自定义插件,通义 App 可通过「AI 工具箱」挂载 MCP。

\n
    \n
  1. 钉钉开发者后台 → AI 助理 → 「插件开发 / MCP 接入」
  2. \n
  3. 选 HTTP Streamable,填入驰声 MCP URL 并开启鉴权(可选)
  4. \n
  5. 在钉钉群 @AI 助理上传音频,自动返回评测卡片
  6. \n
\n
\n
\n\n 典型场景 · 小龙虾们的共同剧本:销售口语陪练 → 外语培训 → 主持 / 播音岗位考核 → K12 英语作业批改 → 客服话术复盘。这些「上班族 AI 工作台」接入驰声 MCP 后,员工 / 学员只要对着话筒说话,AI 就能自动打分并给出个性化改进建议,运营 / 培训 / 教研团队零开发即可上线。\n
\n\n \n

如果你需要把语音评测编排进多步业务流(例如:学员录音 → 评测 → 生成错题集 → 推送到 CRM),可视化工作流平台比聊天 Bot 更合适。

\n\n
\n
\n

Dify

\n

开源 LLMOps,v0.15+ 原生 MCP 工具。

\n
    \n
  • 「工具」→「自定义 MCP」→ 填 URL
  • \n
  • 在 Chatflow / Workflow 节点里直接拖用
  • \n
\n
\n
\n

n8n

\n

工作流自动化,用 MCP Client 节点。

\n
    \n
  • 添加 MCP Client 节点
  • \n
  • Transport 选 HTTP Stream,URL 贴驰声地址
  • \n
  • Tool 下拉自动列出 16 个评测能力
  • \n
\n
\n
\n

Flowise / LangFlow

\n

可视化 LangChain Agent 编排。

\n
    \n
  • 拖出 MCP Tool 节点
  • \n
  • 连到 AgentExecutor 即可
  • \n
\n
\n
\n\n 可视化平台的好处是流程可追溯、可回放,适合教育机构 / 培训部门做批量评测 + 报表导出;缺点是单步延迟略高于直接 MCP 调用,对延迟敏感的交互场景建议用 Cursor / Claude Desktop 直连。\n
\n\n \n

任何遵循 MCP 协议的客户端都可以接入,统一使用以下配置:

\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
传输类型streamable-http
URLhttps://speech-eval.site/mcp
鉴权(可选)Header:Authorization: Bearer <MCP_API_KEY>
\n
\n

还没找到你用的客户端?任何支持 Model Context Protocol 的终端都通用。找不到入口?下一小节「编程用 MCP」里用 SDK 直接接即可。

\n
\n
\n\n {/* ══════ 接入 · 编程用 MCP ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 你在写一段真正的后端服务:一个 Agent Worker、一个 API、一个自动化脚本
  • \n
  • 业务里的「语音评测」是其中一个步骤,需要由代码 决定何时调用、如何解析结果
  • \n
  • 三种主流写法:① 官方 MCP 客户端库 → ② Agent 框架自动桥接 → ③ 退化到 chat.completions + tools 参数
  • \n
\n

💡 强烈推荐①或②:驰声有 16 个评测工具,让 MCP 自动注入 tool schema,每新增一个题型不用改一行业务代码。

\n
\n\n \n

最底层、也最推荐的方式。由 Anthropic 官方维护,一次连接自动拿到全部工具的 JSON Schema,然后交给任意 LLM。

\n\n

Python:mcp

\n {`# pip install mcp openai\nimport asyncio, os\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nMCP_URL = \"https://speech-eval.site/mcp\"\nllm = OpenAI(api_key=os.getenv(\"DOUBAO_KEY\"),\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\") # 豆包 / DeepSeek / OpenAI 同构\n\nasync def main(audio_id: str, ref: str):\n async with streamablehttp_client(MCP_URL) as (reader, writer, _):\n async with ClientSession(reader, writer) as sess:\n await sess.initialize()\n\n tools = await sess.list_tools()\n openai_tools = [{\n \"type\": \"function\",\n \"function\": {\"name\": t.name, \"description\": t.description,\n \"parameters\": t.inputSchema},\n } for t in tools.tools]\n\n resp = llm.chat.completions.create(\n model=\"doubao-1-5-pro-32k\",\n messages=[{\"role\": \"user\",\n \"content\": f\"帮我评测 audioId={audio_id},参考文本:{ref}\"}],\n tools=openai_tools,\n )\n\n for call in resp.choices[0].message.tool_calls or []:\n result = await sess.call_tool(call.function.name,\n arguments=eval(call.function.arguments))\n print(call.function.name, \"→\", result.content[0].text[:200])\n\nasyncio.run(main(\"abc123\", \"I think therefore I am\"))`}\n\n

TypeScript / Node.js:@modelcontextprotocol/sdk

\n {`// npm i @modelcontextprotocol/sdk openai\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport OpenAI from \"openai\";\n\nconst mcp = new Client({ name: \"chivox-biz\", version: \"1.0.0\" });\nawait mcp.connect(new StreamableHTTPClientTransport(new URL(\"https://speech-eval.site/mcp\")));\n\nconst { tools } = await mcp.listTools();\nconst openai = new OpenAI({ apiKey: process.env.DEEPSEEK_KEY, baseURL: \"https://api.deepseek.com/v1\" });\n\nconst resp = await openai.chat.completions.create({\n model: \"deepseek-chat\",\n messages: [{ role: \"user\", content: \"评测 audioId=abc123, 参考 I think therefore I am\" }],\n tools: tools.map(t => ({ type: \"function\", function: {\n name: t.name, description: t.description, parameters: t.inputSchema\n }})),\n});\n\nfor (const call of resp.choices[0].message.tool_calls ?? []) {\n const r = await mcp.callTool({ name: call.function.name,\n arguments: JSON.parse(call.function.arguments) });\n console.log(call.function.name, r.content);\n}`}\n 这种写法 LLM 供应商可换(豆包 / DeepSeek / GPT / Qwen / Moonshot),工具自动更新(驰声新增题型无需改业务代码),适合生产后端。\n
\n\n \n

如果项目已经在用 Agent 框架,几行 adapter 就能把驰声 MCP 塞进去,框架本身会接管 tool-calling 循环、重试、日志。

\n\n
\n
\n

LangChain / LangGraph(Python)

\n {`# pip install langchain-mcp-adapters langgraph\nfrom langchain_mcp_adapters.client import MultiServerMCPClient\nfrom langgraph.prebuilt import create_react_agent\n\nclient = MultiServerMCPClient({\n \"chivox\": {\n \"transport\": \"streamable_http\",\n \"url\": \"https://speech-eval.site/mcp\",\n }\n})\ntools = await client.get_tools()\n\nagent = create_react_agent(\"openai:gpt-4o-mini\", tools)\nresult = await agent.ainvoke({\"messages\":\n [(\"user\", \"评测 audioId=abc123 参考 think\")]})\nprint(result[\"messages\"][-1].content)`}\n
\n\n
\n

Mastra(TypeScript)

\n {`// npm i @mastra/core @mastra/mcp\nimport { MCPClient } from \"@mastra/mcp\";\nimport { Agent } from \"@mastra/core/agent\";\nimport { openai } from \"@ai-sdk/openai\";\n\nconst mcp = new MCPClient({ servers: {\n chivox: { url: new URL(\"https://speech-eval.site/mcp\") }\n}});\n\nexport const speechCoach = new Agent({\n name: \"speech-coach\",\n instructions: \"你是口语教练,用 chivox 工具评测并给改进建议。\",\n model: openai(\"gpt-4o-mini\"),\n tools: await mcp.getTools(),\n});`}\n
\n\n
\n

OpenAI Agents SDK(Python)

\n {`# pip install openai-agents\nfrom agents import Agent, Runner\nfrom agents.mcp import MCPServerStreamableHttp\n\nchivox = MCPServerStreamableHttp(\n params={\"url\": \"https://speech-eval.site/mcp\"},\n name=\"chivox-speech-eval\",\n)\n\nasync with chivox:\n agent = Agent(name=\"coach\",\n instructions=\"专业口语教练\",\n mcp_servers=[chivox])\n r = await Runner.run(agent, \"评测 audioId=abc123\")\n print(r.final_output)`}\n
\n\n
\n

LlamaIndex / AutoGen / CrewAI

\n

这些框架都有官方或社区 MCP adapter,用法与上述类似:

\n
    \n
  • LlamaIndex:llama-index-tools-mcp
  • \n
  • AutoGen:autogen-ext[mcp]
  • \n
  • CrewAI:crewai-tools 的 MCPServerAdapter
  • \n
  • Spring AI(Java):spring-ai-mcp-client
  • \n
\n
\n
\n
\n\n \n

\n DeepSeek、GLM(智谱)、KIMI(Moonshot)、豆包(火山方舟)、千帆、DashScope 等若提供 OpenAI 兼容的 HTTP API,接入驰声 MCP 的套路一致:用 MCP 客户端拉取工具列表 → 转为{' '}\n tools → 模型决策 tool_calls → MCP 执行并回填 → 再让模型生成诊断话术。\n

\n
\n
\n ① MCP list_tools()\n →\n ② 转 OpenAI tools 格式\n →\n ③ LLM 决策 tool_calls\n →\n ④ MCP call_tool()\n →\n ⑤ 评测结果回填 → LLM 诊断\n
\n
\n 各厂商仅需替换 base_url 与 api_key,驰声 MCP 与 tools 桥接代码可原样复用。\n\n

先上传音频,拿到 audioId

\n

文件评测工具通常需要 audioId(或路径参数,视工具而定)。下面是用 HTTP 上传的最小示例:

\n {`import requests\n\nwith open('audio.mp3', 'rb') as f:\n r = requests.post(\n 'https://speech-eval.site/upload',\n data=f,\n headers={'Content-Type': 'audio/mp3'}\n )\n\nresult = r.json()\nprint(f\"audioId: {result['audioId']}\")\nprint(f\"size: {result['size']} bytes\")\nprint(f\"expires: {result['expiresIn']}\")`}\n {`const fs = require('fs');\n\nconst audioData = fs.readFileSync('audio.mp3');\n\nconst res = await fetch('https://speech-eval.site/upload', {\n method: 'POST',\n headers: { 'Content-Type': 'audio/mp3' },\n body: audioData,\n});\n\nconst result = await res.json();\nconsole.log('audioId:', result.audioId);`}\n\n

再以豆包为例:MCP 动态 tools + chat.completions 折返跑

\n

当你用的 LLM SDK 还没有原生 MCP 支持(比如老版本的火山方舟 / 百度千帆 / 通义 DashScope),退化方案是:用 MCP 客户端一次性拉到 tool schema,然后按 OpenAI Function Calling 格式喂给 LLM。

\n {`# 适用:豆包(火山方舟)/ DeepSeek / Qwen / Moonshot / GLM 等 OpenAI 兼容 API\n# 核心思路:MCP 列工具 → 转 OpenAI tools → LLM 决策 → MCP 执行 → 回填\n\nasync with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n\n # ① 用 MCP 拉到的 schema 自动转 OpenAI 格式\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 喂给豆包\n messages = [{\"role\": \"user\", \"content\": \"评测一下 audioId=abc123\"}]\n resp = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages, tools=oa_tools,\n )\n\n # ③ LLM 回 tool_calls → 折返跑到 MCP 执行\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for c in msg.tool_calls:\n result = await mcp.call_tool(\n c.function.name, arguments=json.loads(c.function.arguments))\n messages.append({\"role\": \"tool\", \"tool_call_id\": c.id,\n \"content\": result.content[0].text})\n # ④ 再喂一轮,让豆包根据评测结果产出自然语言诊断\n final = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages)\n print(final.choices[0].message.content)`}\n 千万别手写 tool schema!驰声共 16 个评测工具(英文 10 + 中文 6),每个工具参数较多,手写既容易错也难维护。一定用 MCP list_tools() 动态拿。\n
\n\n \n

\n DeepSeek 提供与 OpenAI 完全兼容的 API,当前最新模型为 DeepSeek-V3.2(2025 年 12 月发布,首个把\"思考 + 工具调用\"原生融合的模型)。\n 通过 deepseek-chat 进入非思考模式,\n 通过 deepseek-reasoner 进入思考模式,\n 两种模式均支持 Function Calling,128K 上下文。\n

\n\n

环境准备

\n {`DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# DeepSeek 客户端(OpenAI 兼容)\nclient = OpenAI(\n api_key=os.environ[\"DEEPSEEK_API_KEY\"],\n base_url=\"https://api.deepseek.com/v1\",\n)\n\nasync def evaluate_with_deepseek(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # ① 拉取驰声 MCP 工具列表\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 调用 DeepSeek,让它选择合适的评测工具\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段英文录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"deepseek-chat\", # 或 deepseek-reasoner\n messages=messages,\n tools=oa_tools,\n )\n\n # ③ 执行 tool_calls\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n # ④ 让 DeepSeek 根据评测结果生成自然语言诊断\n final = client.chat.completions.create(\n model=\"deepseek-chat\",\n messages=messages,\n )\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_deepseek(\"audio_abc123\", \"Hello, nice to meet you.\"))`}\n \n 选型建议(V3.2):日常评测诊断用 deepseek-chat,速度快、token 消耗低;\n 需要深度分析(错误归因 / 个性化练习路径)时用 deepseek-reasoner,\n V3.2 起思考模式也能在思维链中调用工具,可以一次性完成\"调评测 → 思考 → 出诊断\",无需再切回 V3 做工具调用。\n \n
\n\n \n

\n 智谱 AI 当前最新旗舰为 GLM-5 / GLM-5.1(2026 年 2 月发布,744B-A40B MoE,200K 上下文,对标 Claude Opus 4.5),\n 以及上一代 GLM-4.7、GLM-4.6。\n 此外保留 glm-4-flash(免费快速版)方便开发测试。\n 全部模型支持 OpenAI 兼容接口与原生 zhipuai SDK,原生 Function Calling。\n

\n\n

环境准备

\n {`ZHIPU_API_KEY=xxxxxxxx.xxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

方式一:OpenAI 兼容接口(推荐)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = OpenAI(\n api_key=os.environ[\"ZHIPU_API_KEY\"],\n base_url=\"https://open.bigmodel.cn/api/paas/v4/\",\n)\n\nasync def evaluate_with_glm(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"glm-4-flash\", # 免费快速版;生产推荐 glm-5 / glm-4.7\n messages=messages,\n tools=oa_tools,\n )\n\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n final = client.chat.completions.create(\n model=\"glm-4-flash\", messages=messages)\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_glm(\"audio_abc123\", \"How are you today?\"))`}\n\n

方式二:官方 zhipuai SDK

\n {`from zhipuai import ZhipuAI\n\nclient = ZhipuAI(api_key=os.environ[\"ZHIPU_API_KEY\"])\n\n# 其余逻辑与方式一相同,仅替换 client 实例\nresp = client.chat.completions.create(\n model=\"glm-5\", # 旗舰;也可用 glm-4.7 / glm-4-flash\n messages=messages,\n tools=oa_tools,\n)`}\n \n 选型建议:\n 开发联调用 glm-4-flash(免费);\n 在线辅导日常诊断用 glm-4.7 性价比最高;\n K12 / 复杂 Agent 编排(多步评测 + 个性化练习路径)用 glm-5 / glm-5.1,\n 200K 上下文、Agent 能力对标 Claude Opus 系列。\n \n
\n\n \n

\n Moonshot AI 当前最新旗舰是 Kimi K2.5(2026 年 1 月 27 日发布,MoE 架构、256K 上下文、原生多模态、Agent 集群协作)。\n 另外提供 kimi-k2-thinking(深度思考)、kimi-k2-turbo-preview(高速版)。\n 上一代 moonshot-v1-8k/32k/128k 仍然兼容,但推荐迁移到 kimi-k2.5。\n 全部模型 OpenAI 兼容,原生 Function Calling。\n

\n\n

环境准备

\n {`MOONSHOT_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# 中国大陆用 api.moonshot.cn;海外/国际版用 api.moonshot.ai\nclient = OpenAI(\n api_key=os.environ[\"MOONSHOT_API_KEY\"],\n base_url=\"https://api.moonshot.cn/v1\",\n)\n\nasync def evaluate_with_kimi(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段英文录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"kimi-k2.5\", # 旗舰;也可选 kimi-k2-turbo-preview / moonshot-v1-128k\n messages=messages,\n tools=oa_tools,\n )\n\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n final = client.chat.completions.create(\n model=\"kimi-k2.5\", messages=messages)\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_kimi(\"audio_abc123\", \"Nice to meet you.\"))`}\n \n Kimi K2.5 原生 256K 上下文 + Agent 集群协作,特别适合「多轮口语练习 + 历史分析 + 多步评测编排」场景:\n 把用户过去 30 次评测的完整 JSON 全部塞进 messages,让 K2.5 一次性生成跨多次练习的进步报告与个性化练习路径。\n 需要更深推理时使用 kimi-k2-thinking,\n 追求实时反馈用 kimi-k2-turbo-preview。\n \n
\n\n \n

\n 字节跳动 豆包 Seed 2.0(2026 年 2 月发布)是 ByteDance Seed 团队推出的新一代通用大模型,覆盖 Pro / Lite / Mini / Code 多种规格,\n 通过 火山方舟(Volcano Ark) 提供 OpenAI 兼容的 /api/v3/chat/completions 接口,\n 原生支持 Function Calling、JSON Schema 结构化输出、深度思考(Chain-of-Thought)模式,\n 接驰声 MCP 几乎无须改动业务代码。\n

\n\n \n 豆包 Seed 2.0 的优势在 深度思考 + 工具编排:让模型一次性规划\"先调 en.sent.score,看完弱项再调 en.word.score 进一步定位音素\",\n 适合做\"多步评测 + 自动纠音\"这类 Agent 场景。\n 默认开启思考模式,可通过 {'thinking: { type: \"disabled\" }'} 关闭以节省时延。\n \n\n

推荐版本

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
model规格推荐用途
doubao-seed-2-0-pro-260215Pro · 旗舰多步评测 + 深度诊断 + 复杂 Agent 编排
doubao-seed-2-0-lite-260215Lite · 平衡在线辅导单轮评测 + 自然语言反馈,性价比首选
doubao-seed-2-0-mini-260215Mini · 极小高并发 / 边缘部署 / 移动端实时反馈
doubao-seed-2-0-code-preview-260215Code · 预览代码生成 / 工具编排 DSL,对评测场景非主推
doubao-seed-1-8-2512281.8 · 深度思考支持 reasoning_effort 调档(minimal/low/medium/high),上一代深度思考强化版仍可用
doubao-seed-1-6-2510151.6 · 经典256K 上下文经典版,已上线项目可继续沿用
\n
\n\n

环境准备

\n {`# 火山方舟控制台 → API Key 管理\nARK_API_KEY=ak-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · 动态 tools + 折返跑)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# 火山方舟 OpenAI 兼容端点\nclient = OpenAI(\n api_key=os.environ[\"ARK_API_KEY\"],\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n)\n\nMODEL = \"doubao-seed-2-0-pro-260215\" # 也可换成 lite / mini\n\nasync def evaluate_with_doubao(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # ① 把驰声 16 个评测工具的 schema 动态注入豆包\n tools = (await mcp.list_tools()).tools\n ark_tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n },\n } for t in tools]\n\n messages = [\n {\"role\": \"system\",\n \"content\": \"你是一位专业的英语口语教练,会主动调用驰声评测工具获取真实分数。\"},\n {\"role\": \"user\",\n \"content\": f\"请评测这段录音,audio_id={audio_id},参考文本:{ref_text}。\"\n f\"先做句子级评测,弱项再追加单词级定位。\"},\n ]\n\n # ② 第一轮 —— 让豆包根据 prompt 自主选工具\n resp = client.chat.completions.create(\n model=MODEL,\n messages=messages,\n tools=ark_tools,\n tool_choice=\"auto\",\n # extra_body={\"thinking\": {\"type\": \"disabled\"}}, # 需要时可关思考\n )\n\n msg = resp.choices[0].message\n messages.append(msg)\n\n # ③ 折返跑:豆包可能一次发起多个 tool_calls,全部回填\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n # ④ 第二轮 —— 让豆包基于真实评测 JSON 输出诊断 / 练习建议\n final = client.chat.completions.create(\n model=MODEL,\n messages=messages,\n )\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_doubao(\n audio_id=\"audio_abc123\",\n ref_text=\"The quick brown fox jumps over the lazy dog.\",\n)))`}\n\n

深度思考模式(可选)

\n

\n 豆包 Seed 2.0 默认开启 thinking 模式,会在内部生成思维链再产出答案,\n 对\"多步评测编排 / 复杂诊断\"质量明显更好;但会增加 30%~80% 的端到端延迟。\n 在 extra_body 里可显式控制:\n

\n {`# 关闭思考(更快、适合实时反馈)\nclient.chat.completions.create(\n model=\"doubao-seed-2-0-lite-260215\",\n messages=messages,\n tools=ark_tools,\n extra_body={\"thinking\": {\"type\": \"disabled\"}},\n)\n\n# 开启思考(默认,适合 Pro 模型 + 多步 Agent)\nclient.chat.completions.create(\n model=\"doubao-seed-2-0-pro-260215\",\n messages=messages,\n tools=ark_tools,\n extra_body={\"thinking\": {\"type\": \"enabled\"}},\n)`}\n\n \n 选型建议:\n 课堂 / 培训类一对一辅导用 doubao-seed-2-0-lite + 关思考;\n K12 / 考试场景需要\"多题型联动 + 升级建议\"时用 doubao-seed-2-0-pro + 开思考;\n 移动端实时口语对话用 doubao-seed-2-0-mini 控制成本与时延。\n \n
\n\n \n

\n OpenAI 当前旗舰为 GPT-5.1(2025-11-13 发布),400K 上下文、128K 最大输出,\n 支持可调推理强度 reasoning_effort(none / low / medium / high)。\n 另有 gpt-5.1-chat-latest(ChatGPT 同款,128K 上下文,对话场景更优)和 gpt-5-mini(性价比版)。\n 全部模型原生支持 Function Calling 与 Structured Outputs。\n

\n\n

环境准备

\n {`OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · GPT-5.1 + 驰声 MCP)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = OpenAI(api_key=os.environ[\"OPENAI_API_KEY\"])\n\nasync def evaluate_with_gpt(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [\n {\"role\": \"system\",\n \"content\": \"你是英语口语教练,必须调用驰声评测工具拿真实分数后再回答。\"},\n {\"role\": \"user\",\n \"content\": f\"请评测:audioId={audio_id},参考文本:{ref_text}\"},\n ]\n\n resp = client.chat.completions.create(\n model=\"gpt-5.1\",\n messages=messages,\n tools=oa_tools,\n tool_choice=\"auto\",\n reasoning_effort=\"medium\", # GPT-5.1 新参数:none / low / medium / high\n )\n\n msg = resp.choices[0].message\n messages.append(msg)\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n final = client.chat.completions.create(\n model=\"gpt-5.1\", messages=messages)\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_gpt(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n \n 选型建议:\n 评测调用 + 诊断默认用 gpt-5.1(reasoning_effort="medium",质量与延迟平衡);\n 纯对话/课堂讲解用 gpt-5.1-chat-latest;\n 高并发批量评测降本用 gpt-5-mini。\n 深度推理 / 多步 Agent 编排把 reasoning_effort 调到 high。\n \n
\n\n \n

\n Anthropic 当前最新为 Claude Opus 4.7(旗舰)、Claude Sonnet 4.6(平衡)、Claude Haiku 4.5(高速)。\n Claude 用 Messages API(与 OpenAI Chat Completions 不同),工具协议是 tool_use / tool_result 块结构。\n 支持文本 + 视觉输入,工具 schema 用 input_schema 字段(与 OpenAI 的 parameters 等价)。\n

\n\n

环境准备

\n {`ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · 原生 Anthropic SDK + MCP 工具桥接)

\n {`# pip install anthropic mcp\nimport os, json, asyncio\nfrom anthropic import Anthropic\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = Anthropic(api_key=os.environ[\"ANTHROPIC_API_KEY\"])\n\nasync def evaluate_with_claude(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # 把驰声 MCP 工具转成 Anthropic 风格(用 input_schema 而非 parameters)\n tools = (await mcp.list_tools()).tools\n anth_tools = [{\n \"name\": t.name,\n \"description\": t.description,\n \"input_schema\": t.inputSchema,\n } for t in tools]\n\n messages = [{\"role\": \"user\",\n \"content\": f\"请评测这段录音 audioId={audio_id},参考文本:{ref_text}\"}]\n\n # 工具循环:Claude 可能多轮 tool_use,需逐轮回填\n while True:\n resp = client.messages.create(\n model=\"claude-opus-4-7\", # 或 claude-sonnet-4-6 / claude-haiku-4-5\n max_tokens=2048,\n tools=anth_tools,\n messages=messages,\n system=\"你是专业英语口语教练,必须调用驰声评测工具获取真实分数。\",\n )\n\n # 把整段助手回复(含 tool_use 块)追加进 messages\n messages.append({\"role\": \"assistant\", \"content\": resp.content})\n\n if resp.stop_reason != \"tool_use\":\n # 没有更多工具调用,输出最终诊断\n return \"\".join(b.text for b in resp.content if b.type == \"text\")\n\n # 提取所有 tool_use 块、并行执行、把 tool_result 回填给 Claude\n tool_results = []\n for block in resp.content:\n if block.type == \"tool_use\":\n result = await mcp.call_tool(block.name, arguments=block.input)\n tool_results.append({\n \"type\": \"tool_result\",\n \"tool_use_id\": block.id,\n \"content\": result.content[0].text,\n })\n messages.append({\"role\": \"user\", \"content\": tool_results})\n\nprint(asyncio.run(evaluate_with_claude(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n \n 选型建议:\n 深度评测诊断 + 复杂 Agent 编排用 claude-opus-4-7(旗舰,编程/Agent 提升明显);\n 日常评测 + 性价比首选 claude-sonnet-4-6;\n 高并发实时反馈用 claude-haiku-4-5。\n Opus 4.5 起新增 effort 参数(low/medium/high),medium 即可达到 Sonnet 4.5 同等质量但 token 减少 ~76%。\n \n
\n\n \n

\n Google 最新 Gemini 3 Flash(gemini-3-flash-preview,2025-12-17)以 Flash 价位提供 Pro 级推理;\n 另有 Gemini 3.1 Pro Preview(旗舰)、Gemini 3.1 Flash-Lite Preview。\n 全部支持 Function Calling、并行调用、组合调用,原生多模态,thinking_level 控制推理深度。\n 推荐用 OpenAI 兼容端点,可直接复用 OpenAI SDK 与已有的 MCP 工具桥接代码。\n

\n\n

环境准备

\n {`GEMINI_API_KEY=AIzaSyxxxxxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

方式一:OpenAI 兼容端点(推荐,零迁移成本)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# Gemini OpenAI 兼容端点 —— 完全复用 OpenAI SDK\nclient = OpenAI(\n api_key=os.environ[\"GEMINI_API_KEY\"],\n base_url=\"https://generativelanguage.googleapis.com/v1beta/openai/\",\n)\n\nasync def evaluate_with_gemini(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\",\n \"content\": f\"请评测:audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"gemini-3-flash-preview\", # 或 gemini-3.1-pro-preview\n messages=messages,\n tools=oa_tools,\n tool_choice=\"auto\",\n )\n msg = resp.choices[0].message\n messages.append(msg)\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n final = client.chat.completions.create(\n model=\"gemini-3-flash-preview\", messages=messages)\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_gemini(\n \"audio_abc123\", \"The quick brown fox jumps over the lazy dog.\")))`}\n\n

方式二:原生 google-genai SDK(thinking_level / 流式工具调用)

\n {`# pip install google-genai\nfrom google import genai\nfrom google.genai import types\n\nclient = genai.Client(api_key=os.environ[\"GEMINI_API_KEY\"])\n\n# 把 MCP 工具转成 Gemini function_declarations\nfn_decls = [{\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n} for t in tools]\n\nresp = client.models.generate_content(\n model=\"gemini-3-flash-preview\",\n contents=f\"评测 audioId={audio_id},参考文本:{ref_text}\",\n config=types.GenerateContentConfig(\n tools=[types.Tool(function_declarations=fn_decls)],\n # Gemini 3 起:thinking_level 替代旧的 thinking_budget\n # thinking_level=\"high\",\n ),\n)\n\n# tool_call 在 response.candidates[0].content.parts[0].function_call\nfc = resp.candidates[0].content.parts[0].function_call\nprint(f\"call: {fc.name}({dict(fc.args)}) id={fc.id}\")`}\n \n 选型建议:\n 日常评测用 gemini-3-flash-preview(速度比 2.5 Pro 快 3 倍、价格 ~$0.50/M 输入),已是 Gemini App 默认;\n 复杂多步 Agent / 编程任务用 gemini-3.1-pro-preview;\n 超大上下文 + 多模态批处理用同系列的 gemini-3.1-flash-lite-preview。\n \n \n 注意:Gemini 3 起每次 function_call 自动带 id,多轮工具调用必须把 id 透传回 function_response,否则会被拒绝(OpenAI 兼容端点已自动处理)。\n \n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
模型推荐版本base_urlFunction Calling适合场景
DeepSeek V3.2 · 非思考deepseek-chatapi.deepseek.com/v1✓ 支持评测调用 + 诊断,性价比最高
DeepSeek V3.2 · 思考deepseek-reasonerapi.deepseek.com/v1✓ 支持(思考中可调工具)深度分析 + 错因归因 + 个性化练习路径
GLM-5 · 旗舰glm-5 / glm-5.1open.bigmodel.cn/…/v4✓ 支持200K 长上下文 + Agent 编排,复杂诊断
GLM-4.7glm-4.7open.bigmodel.cn/…/v4✓ 支持在线辅导日常诊断,性价比首选
GLM-4-Flashglm-4-flashopen.bigmodel.cn/…/v4✓ 支持免费额度,开发联调
Kimi K2.5(旗舰)kimi-k2.5api.moonshot.cn/v1✓ 支持256K + 多模态 + Agent 集群协作
Kimi K2 Thinkingkimi-k2-thinkingapi.moonshot.cn/v1✓ 支持多步推理 + 多轮历史进度报告
Kimi K2 Turbokimi-k2-turbo-previewapi.moonshot.cn/v1✓ 支持高速响应版,实时反馈
豆包 Seed 2.0 Prodoubao-seed-2-0-pro-260215ark.cn-beijing.volces.com/api/v3✓ 支持(含深度思考)多步评测编排 + 深度诊断 Agent
豆包 Seed 2.0 Litedoubao-seed-2-0-lite-260215ark.cn-beijing.volces.com/api/v3✓ 支持在线辅导 + 单轮诊断,性价比首选
豆包 Seed 2.0 Minidoubao-seed-2-0-mini-260215ark.cn-beijing.volces.com/api/v3✓ 支持移动端 / 边缘部署 / 低延迟实时反馈
GPT-5.1(旗舰)gpt-5.1api.openai.com/v1✓ 支持(reasoning_effort 可调)400K 上下文 + 深度推理 + 复杂 Agent 编排
GPT-5.1 Chatgpt-5.1-chat-latestapi.openai.com/v1✓ 支持ChatGPT 同款,对话 / 课堂讲解
GPT-5 minigpt-5-miniapi.openai.com/v1✓ 支持高并发 / 批量评测降本
Claude Opus 4.7claude-opus-4-7api.anthropic.com/v1✓ 支持(tool_use 协议)旗舰,编程 / Agent / 深度诊断
Claude Sonnet 4.6claude-sonnet-4-6api.anthropic.com/v1✓ 支持日常评测 + 性价比首选
Claude Haiku 4.5claude-haiku-4-5api.anthropic.com/v1✓ 支持高并发实时反馈
Gemini 3 Flashgemini-3-flash-preview…/v1beta/openai/✓ 支持(并行 / 组合)Pro 级推理 + Flash 价位,Gemini App 默认
Gemini 3.1 Pro Previewgemini-3.1-pro-preview…/v1beta/openai/✓ 支持(thinking_level 可调)复杂多步 Agent + 编程任务
\n
\n \n 除 Claude 用 Anthropic 原生 SDK(anthropic 包,tool_use / tool_result 协议)外,其余所有模型均可通过 OpenAI Python SDK(openai 包)调用,仅需替换 base_url 与 api_key,驰声 MCP 侧代码无需改动。\n \n
\n\n \n

大部分落地场景其实是:你已有一个业务后端(教育 SaaS / 培训系统 / 客服平台),只需要新增一个「语音评测」能力。推荐架构:

\n\n
\n
\n 前端录音 / 上传\n →\n 业务后端\n →\n MCP Client(常驻连接)\n →\n 驰声 MCP\n ↘\n LLM(诊断 / 出题)\n
\n
\n\n

FastAPI 示例(生产最小骨架)

\n {`from fastapi import FastAPI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\nfrom contextlib import asynccontextmanager\n\nmcp_session: ClientSession | None = None\n\n@asynccontextmanager\nasync def lifespan(app):\n global mcp_session\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as s:\n await s.initialize()\n mcp_session = s\n yield\n mcp_session = None\n\napp = FastAPI(lifespan=lifespan)\n\n@app.post(\"/api/evaluate\")\nasync def evaluate(audio_id: str, ref_text: str):\n # 直接选一个最合适的工具执行(不经 LLM,延迟最低)\n r = await mcp_session.call_tool(\"evaluate_english_sentence\",\n {\"audioId\": audio_id, \"sentence\": ref_text})\n return {\"result\": r.content[0].text}`}\n\n 关键优化:① MCP 连接在 lifespan 里做成长连接,不要每次请求都重连;② 对延迟敏感的场景可以「跳过 LLM 直接调 tool」,把 LLM 放到「生成诊断报告」那一步。\n
\n\n
\n

方案选型速查

\n
\n \n \n \n \n \n \n \n \n \n \n \n
场景推荐方案
AI 对话 / Copilot 类产品,LLM 供应商可能会换① 官方 MCP 客户端库
已有 LangChain / Mastra / Agents SDK 技术栈② Agent 框架 + adapter
火山方舟 / 千帆控制台直连,最小侵入③ chat.completions + tools
教育 SaaS / 培训 / 客服等业务后端集成④ 自研后端 Agent
\n
\n
\n
\n\n {/* ══════ 评测模式 ══════ */}\n \n\n \n

通过本地麦克风实时录音,音频以 WebSocket 流式推送到评测服务,无需生成中间文件。这是最灵活、延迟最低的评测方式,特别适合交互式口语练习场景。

\n 实时录音评测需要安装 SoX 并使用本地代理模式(Claude Desktop / Claude Code)。Cursor 等远程直连模式暂不支持实时录音。\n\n

需要按顺序调用三个工具:

\n\n
\n
\n

create_stream_session — 创建流式评测会话

\n \n

返回 session_id,后续步骤需使用。

\n
\n\n
\n

start_recording — 开始麦克风录音

\n \n

调用后自动启动麦克风,音频通过 WebSocket 实时推送到评测服务。

\n
\n\n
\n

stop_recording — 停止录音并获取结果

\n \n
\n
\n
\n\n \n
\n \n

用户:"请评测我的英文发音,文本是 Hello"

\n

AI 调用 create_stream_session(core_type="en.word.score", ref_text="Hello")

\n

→ 获得 session_id

\n
\n \n

AI 调用 start_recording(session_id=xxx)

\n

麦克风开始录音,音频通过 WebSocket 实时推送到评测服务

\n
\n \n

用户说完后告知 AI "结束"

\n

AI 调用 stop_recording(session_id=xxx)

\n

→ 返回评测结果(总分、准确度、流利度、音素得分等)

\n
\n
\n
\n\n \n

适用于已有音频文件的评测场景,支持三种输入方式:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
参数说明适用场景
audio_file_path本地文件路径代理自动读取并转为 Base64,最便捷
audio_base64Base64 编码数据已有编码数据时使用
audio_url音频文件 URL音频托管在云存储时使用
\n
\n 推荐使用 audio_file_path,只需传入本地文件路径,代理会自动处理编码和上传。\n

支持的音频格式:mp3, wav, ogg, m4a, aac, pcm

\n

限制:单文件最大 50MB,大于 500KB 的文件自动压缩为 16kHz / 单声道 / 32kbps。

\n
\n
\n\n {/* ══════ API 参考 ══════ */}\n \n\n \n \n\n

通用参数:所有英文评测工具均支持以下参数。

\n \n
\n\n \n \n\n

通用参数:

\n \n
\n\n \n

所有评测工具返回统一的结构化结果:

\n {`{\n \"overall\": 85,\n \"accuracy\": 82,\n \"pron\": 88,\n \"fluency\": {\n \"overall\": 78,\n \"speed\": 65,\n \"pause\": 2\n },\n \"integrity\": 95,\n \"details\": [\n {\n \"char\": \"hello\",\n \"score\": 85,\n \"phone\": [\n { \"phoneme\": \"h\", \"score\": 90 },\n { \"phoneme\": \"ɛ\", \"score\": 82 },\n { \"phoneme\": \"l\", \"score\": 88 },\n { \"phoneme\": \"oʊ\", \"score\": 80 }\n ]\n }\n ]\n}`}\n
\n \n \n \n \n \n \n \n {[\n ['overall', '0–100', '综合总分,反映整体语音质量'],\n ['accuracy', '0–100', '准确度,音素级别的发音准确率'],\n ['pron', '0–100', '发音得分,整体发音质量评价'],\n ['fluency.overall', '0–100', '流利度,语流的自然度与平滑度'],\n ['fluency.speed', '0–100', '语速得分,每分钟词/音节计量'],\n ['fluency.pause', 'number', '不自然停顿次数'],\n ['integrity', '0–100', '完整度,是否完整朗读了参考文本'],\n ['details[].phone[]', 'array', '每个音素的独立评分,可定位具体弱项'],\n ['details[].stress[]', 'array', '重音得分,检测重弱读是否正确'],\n ].map(([field, range, desc]) => (\n \n \n \n \n \n ))}\n \n
字段范围说明
{field}{range}{desc}
\n
\n
\n\n \n
\n \n \n \n \n \n \n \n {[\n ['音频 ID 无效或已过期', '音频上传后 5 分钟内有效,评测完成后自动删除', '重新上传音频'],\n ['服务器繁忙', '当前请求过多,排队已满', '稍后重试,使用指数退避策略'],\n ['存储空间已满', '服务器临时音频存储已满', '稍后重试,系统会自动清理'],\n ['音频格式不支持', '上传了不支持的文件类型', '使用 mp3/wav/ogg/m4a/aac/pcm'],\n ['音频时长超限', '超过该题型最大时长限制', '裁剪音频后重试'],\n ['WebSocket 连接断开', '网络不稳定导致流式连接中断', '代理会自动重连,如持续失败请检查网络'],\n ].map(([scene, reason, fix]) => (\n \n \n \n \n \n ))}\n \n
场景原因解决方式
{scene}{reason}{fix}
\n
\n
\n
\n\n {/* ══════ 最佳实践 ══════ */}\n \n\n \n

\n 下面这些模板与{' '}\n 免费体验{' '}\n Demo 中实际使用的「教练 Prompt」一脉相承,全部围绕 角色 / 任务 / 方法 / 输出格式 / 语气 五段式结构,并使用占位符{' '}\n {'{mcp_response}'} 直接拼接 MCP 工具返回的 JSON。\n 推荐在 system 消息里挂载,再把工具返回原文塞进\n user 消息,由 LLM 基于真实分数和音素生成可读诊断 / 练习材料。\n

\n\n \n 使用建议:\n
    \n
  • 把 MCP 工具调用的完整 JSON(含 overall / dp_type / phonemes 等字段)原样塞入 {'{mcp_response}'},不要预先做汇总——细节越完整诊断越具体。
  • \n
  • 「诊断」类模板让 LLM 输出 Markdown 给最终用户阅读;「练习」类模板要求 LLM 输出严格 JSON 给前端渲染。两步分开调用,效果远好于一次性混合。
  • \n
  • 题型决定 prompt:单词题用音素级、句子题加韵律、段落题加 chunk / 整体性,半开放题套四维评级。下面按这 6 类分别给出。
  • \n
\n
\n\n {/* ─── A. 诊断类 · 输出 Markdown 给学习者阅读 ─── */}\n

\n A. 二次诊断 · 输出 Markdown\n

\n
\n
\n

\n 1. 单词级 · 音素诊断\n

\n

\n 适用工具:en.word.score / cn.word.raw。围绕 phonemes[].dp_type 找出错读音。\n

\n {`你是一位专业的英语发音教练。下面是驰声 MCP(en.word.score)返回的单词级评测数据:\n一个目标词、总分与发音分、以及带有 dp_type 的音素数组。\n\n## 任务\n为学习者写一份 **可直接阅读** 的发音诊断,每一条都要引用音素分数(写出 IPA 符号)。\n\n## 方法\n- 按 dp_type 分组:先看 mispron,再补充 normal 但分数 < 70 的\"边缘音\"。\n- 每个问题音素:① 典型母语干扰 → ② 你听到的声音 → ③ 一条具体的发音修正动作(下颌 / 舌位 / 气流 / 唇形)。\n- 重音符号 ˈ 标记的音节,重音错位也要单独列出(即便音素本身分数尚可)。\n- 最多列 4 条,按 **影响力从弱到强** 排序。\n\n## 输出\n精简 Markdown:可选一句总结 → 编号列表 → 单行 **🎯 优先级** 排序。\n\n## 语气\n友善、具体、可执行,不要空喊\"加油\"。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 2. 句子级 · 节奏 + 重音诊断\n

\n

\n 适用工具:en.sent.score。开头先给一行\"计分牌\",再从 phones → words → prosody。\n

\n {`你是一位专业的英语口语教练。下面是驰声 MCP(en.sent.score)返回的句子级数据:refText、总分、发音子分(accuracy / integrity / fluency / rhythm)、可选 speed(WPM),以及 details[] 中的逐词得分、dp_type 与可选 phonemes[]。\n\n## 任务\n开头给一行紧凑的 **计分牌**(总分 + 各子分 + 速度),再按 **音素 → 词 → 韵律** 顺序展开诊断。\n\n## 检查清单(每项都要覆盖;不适用则写\"无明显问题\")\n1. **音素级**:每个 score < 70 或 dp_type ≠ normal 的词,展开 phonemes,命名典型错误(如 /ð/ → /d/)并给一条修正动作。\n2. **漏读 / 多读**:标注 dp_type=omit / insert,解释如何拉低 integrity。\n3. **韵律**:基于 rhythm + 错读词的重音,指出重音错位、陈述句调型平直、断句过多等。\n4. **流利度 vs 准确度**:若 fluency 高但 accuracy 低,明确指出,让学习者知道优先改哪一项。\n\n## 输出格式\nMarkdown 子标题:**Pronunciation / Prosody / Study priority**(最后一行简短排序,按 ROI 从高到低)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 3. 段落级 · 音素族归并 + 完整度\n

\n

\n 适用工具:en.pred.score。把同类错音合并为\"音素族\",避免逐词复述。\n

\n {`你是一位专业的英语口语教练。下面是驰声 MCP(en.pred.score)返回的段落级数据:长 refText、总分、发音子分、可选 speed / integrity,以及大量 details[](同一个词可能在不同子句中重复出现;空 char + dp_type=omit 表示漏读)。\n\n## 任务\n对整段做 **整体诊断**:\n(a) 完整度 / 漏读,\n(b) 反复出现的 **音素族**,\n(c) 节奏与断句,\n(d) 各子分之间是否相互印证。\n\n## 检查清单\n1. **integrity / dp_type**:列出每个 omit / insert,并给出所在子句;解释长读时为什么虚词容易被吞。\n2. **音素聚类**:将弱词按共同音素问题归族(/θ/ 链、/e/ 链、/ɒ/ 等),引用 details 中的实例。\n3. **韵律**:结合 rhythm 与标点 —— 短语内停顿过多?子句边界缺失?\n4. **整体一致性**:若 fluency 正常但 accuracy 差(或反之),点明并指出对练习设计的影响。\n\n## 输出格式\nMarkdown 章节:**Summary / Completeness / Pronunciation (families) / Rhythm / Study priorities**(最后一项最多 4 条,按影响力排序)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 4. 半开放题 · IELTS 风格四维评级\n

\n

\n 适用工具:en.pqan.score。结合学习者 transcript + 四维分数,给出可教学的\"升档建议\"。\n

\n {`你是一位 **IELTS / 课堂口语风格** 的口语教练。下面是驰声 MCP(en.pqan.score)返回的半开放题数据:题目 refText、学习者 transcript、overall、四个维度分(grammar / content / fluency / pron)、speed(WPM)、以及结构化的 issues[] 标记。\n\n## 任务\n给出 **基于 rubric 的诊断**:先用一句话给出 0–100 的整体段位估计,再 **逐维度** 解释,并 **引用 transcript 中的短句**(不要复述全文)。最后给 3–5 条 **可执行的\"升档建议\"**(句型 / 模板,而不是\"多练一点\")。\n\n## 权重(要明确告诉学习者)\n- **Content ~30%** — 想法深度、举例、具体程度\n- **Grammar ~25%** — 句型多样性、主谓一致、从句\n- **Fluency ~25%** — 语速、停顿、口头禅、衔接\n- **Pronunciation ~20%** — 音素 + 可懂度\n\n## 跨维度检查\n- 若 content 最低,先给\"展开模板\",不要先抠音素。\n- 若 fluency 低 + WPM 低,区分\"思考型停顿\"与\"发音卡顿\"。\n- 若 pron 标出特定音,绑定到 transcript 里 **真实出现过的词**。\n\n## 输出格式\nMarkdown:**段位估计** → 紧凑的 **得分表格** → **\"To reach the next band\"** 编号列表(每条给出可仿写的句型)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 5. 中文专项 · 声调 / 儿化 / 变调\n

\n

\n 适用工具:cn.word.raw / cn.sent.raw / cn.pred.raw。中文评测最大权重在 **声调**,必须单独检查。\n

\n {`你是一位专业的普通话口语教练。下面是驰声 MCP(cn.sent.raw)返回的中文句子评测数据:整句分数 + 逐字 details + 可选 phonemes + 流利 / 节奏分。\n\n## 中文评测的权重\n- **声调错误权重最高** —— 声调读错可能直接改变词义\n- dp_type=mispron 多来自:声调错、平翘舌混用、前后鼻音混用\n- 拼音对、声调错,听感仍是\"洋腔洋调\"\n\n## 检查清单(缺则写\"无明显问题\")\n1. **儿化**:phonemes 出现 r(儿化) 或 dp_type 提示时,确认是否被读成\"主音节 + 单独儿\"两拍。\n2. **轻声**:叠词、词缀、句末语气词 —— 第二字应短促轻读,无完整声调曲线。\n3. **变调**:三声连读、不 + 后字、一 + 后字,是否符合普通话规则。\n4. **节奏**:用 rhythm + 逗号位置,标记停顿过长或过碎,建议 chunk 边界。\n\n## 输出\nMarkdown 子标题:**总览 / 儿化 / 轻声 / 变调 / 节奏 / 学习优先级**(最后一项 1–3 条,按\"听感自然度提升\"排序)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n {/* ─── B. 练习类 · 输出 JSON 给前端渲染 ─── */}\n

\n B. 微练习生成 · 输出严格 JSON\n

\n
\n
\n

\n 6. 单词 / 句子 · 微练习\n

\n

\n 建议在 诊断完成后 第二轮调用:让 LLM 严格按弱项音素生成,避免\"通用绕口令包\"。\n

\n {`你仍是这位学习者的发音教练。**第二轮诊断已经完成** —— 现在严格基于诊断里点名的弱音素,生成 **1:1 对应** 的微练习(不要给通用题)。\n\n## 输出(仅返回一段合法 JSON 数组,外层不要任何文字)\n根节点必须是数组,每个元素含 category(字符串)、icon(单个 emoji)、items({ \"label\", \"content\" } 数组)。\n\\`\\`\\`json\n[\n { \"category\": \"Phoneme drills\", \"icon\": \"🎯\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Awareness\", \"icon\": \"🗣️\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Whole word\", \"icon\": \"📝\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] }\n]\n\\`\\`\\`\n\n## 规则\n- **Phoneme drills**:诊断里每个 mispron 音素至少给一对最小对立对 + 一句短绕口令 / 重复句。\n- **Awareness**:当重音偏弱时,给一条 stress / 舌位 / 下颌姿态提示。\n- **Whole word**:2–3 句自然句,目标词分别出现在句首 / 句中 / 句末。\n- 所有 content 必须可念出声;字符串内不要再嵌套 JSON。\n\n## 上下文\n诊断结论:{previous_diagnosis}\n原始 MCP:\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 7. 段落 · Chunk Map + 元认知\n

\n

\n 段落级练习要从\"音素\"上升到\"短语 / 整段 / 元认知录回放\"。直接对应 en.pred.score 的诊断结果。\n

\n {`你仍是这位学习者的口语教练。**段落级二次诊断** 已经列出了漏读位置和音素族 —— 现在请生成 **整段练习**:把弱音素串成\"族\"练习、用 chunk map 把虚词粘回短语,并附一条录音 → 回放 → 对照 MCP details 的元认知步骤。\n\n## 输出(仅返回一段合法 JSON 数组)\n\\`\\`\\`json\n[\n { \"category\": \"Phoneme families\", \"icon\": \"🎯\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Chunking\", \"icon\": \"🎵\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Metacognition\", \"icon\": \"🧠\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] }\n]\n\\`\\`\\`\n\n## 规则\n- **Phoneme families**:至少 3 条,按诊断里的音素族(/θ/、/e/、/ɒ/ 等)组织最小对立对 / 词链。\n- **Chunking**:① 给一行用 [ ] 和 / 标注的 chunk map(可加大致停顿秒数);② 给一句\"把漏掉的虚词嵌入短语\"的练习(不要孤立练)。\n- **Metacognition**:一条\"录音 → 回放 → 对照 MCP details\"的 N 遍练习(N 写明,2–3 之间)。\n- 字符串只能是纯展示文本,禁止嵌套 JSON。\n\n## 上下文\n诊断结论:{previous_diagnosis}\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n {/* ─── C. 跨题 / 运营 ─── */}\n

\n C. 跨题 / 运营\n

\n
\n
\n

\n 8. 多日学习报告\n

\n

\n 把过去 N 天的 MCP 评测结果聚合后丢给 LLM,输出适合发给学生 / 家长的周报。\n

\n {`你是一位英语口语学习顾问。下面是这位学习者过去 7 天的驰声 MCP 评测历史(按时间顺序),每条包含题型、coreType、overall、子分、weak_phonemes 摘要。\n\n## 任务\n为学习者生成一份 **周报**,目标读者:本人 + 家长 / 老师。\n强调 **趋势** 与 **下一步计划**,不要复述每一次具体分数。\n\n## 必须包含\n1. **整体趋势**:进步 / 持平 / 退步(一句话 + 简短依据)\n2. **维度变化**:accuracy / fluency / rhythm / integrity / speed 任意有数据的维度,给出\"本周均分 vs 上周\"\n3. **本周高光**:分数提升最大的题型 / 音素 / 句型\n4. **顽固问题**:连续 3 次以上未达 70 的音素或维度\n5. **下周计划**:3 条具体动作(每条对应一个 MCP 工具或一个练习类型)\n6. **结尾**:1–2 句鼓励性总结,避免空话\n\n## 风格\n- 像一位认真但不啰嗦的私教\n- 出现学生姓名时使用占位 {student_name}\n- 数字一律保留整数\n\n## 评测历史\n\\`\\`\\`json\n{history}\n\\`\\`\\``}\n
\n\n
\n

\n 9. 错误归因 · JSON 摘要\n

\n

\n 用于后端聚合 / 数据看板:让 LLM 把一次评测压缩成结构化摘要,方便入库统计。\n

\n {`你是一个评测结果归类器。下面是驰声 MCP 一次评测的完整返回。请抽取关键信息并 **仅返回合法 JSON**(不要任何解释文字)。\n\n## Schema\n\\`\\`\\`json\n{\n \"core_type\": \"string,例如 en.sent.score\",\n \"overall\": 0,\n \"sub_scores\": { \"accuracy\": 0, \"integrity\": 0, \"fluency\": 0, \"rhythm\": 0 },\n \"weak_phonemes\": [\n { \"ipa\": \"string\", \"avg_score\": 0, \"occur\": 0, \"example_word\": \"string\" }\n ],\n \"omissions\": [{ \"after\": \"string\", \"missing\": \"string\" }],\n \"stress_issues\": [{ \"word\": \"string\", \"expected\": \"string\", \"actual\": \"string\" }],\n \"primary_issue_tag\": \"phoneme|stress|fluency|integrity|content|none\",\n \"next_action_hint\": \"string,10 字以内,例如 \\\"练 /θ/ 对立对\\\"\"\n}\n\\`\\`\\`\n\n## 规则\n- weak_phonemes 只收 avg_score < 70 的项,最多 5 项,按 occur 降序。\n- 不要复述 refText,不要 markdown。\n- 字段缺失时使用 null 或空数组,不要省略 key。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n \n 怎么接到 MCP 工具调用?\n
\n 以「直调 chat.completions + 动态 tools」为例:第一轮 LLM 调出 en.sent.score 工具,把工具 result(即 tool 消息内容)原样填入上面任意「诊断」模板的{' '}\n {'{mcp_response}'},作为第二轮 user 消息发回;拿到诊断结论再走第三轮,套「微练习」模板得到 JSON。三轮调用即可串起 评测 → 诊断 → 练习 全链路。\n
\n
\n\n \n
    \n
  • 音频过期:上传后 5 分钟内有效。建议在上传后 3 分钟内完成评测。
  • \n
  • 服务繁忙:使用指数退避策略重试(1s → 2s → 4s),最多 3 次。
  • \n
  • 录音中断:WebSocket 断线后代理会自动重连。如持续失败,检查网络连接和 SoX 安装。
  • \n
\n
\n\n \n
    \n
  • 优先使用流式评测:实时录音模式跳过了文件上传环节,端到端延迟比文件评测低 30-50%。
  • \n
  • 音频压缩:文件评测时,上传前将音频转为 16kHz 单声道 mp3,可减少 60-80% 的上传体积。
  • \n
  • 选择合适的工具:单词评测比段落评测快 3-5 倍。如只需单词级分数,不要用句子评测。
  • \n
  • 本地文件路径最便捷:使用 audio_file_path 参数传入本地路径,代理自动处理编码,无需手动转 Base64。
  • \n
\n
\n
\n\n {/* ══════ 服务信息 ══════ */}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n
端点方法说明
/uploadPOST音频文件上传
/mcpPOSTMCP JSON-RPC 接口(Streamable HTTP)
/healthGET健康检查
\n
\n
\n \n
\n \n \n \n \n \n \n \n {[\n ['存储限制', '500MB', '最大音频存储空间'],\n ['最大排队', '10', '等待处理的请求数'],\n ['最大并发', '3', '同时处理的评测数'],\n ['音频有效期', '5 分钟', '上传后未评测自动过期'],\n ['文件大小限制', '50MB', '单个音频文件最大'],\n ].map(([k, v, d]) => (\n \n ))}\n \n
配置项默认值说明
{k}{v}{d}
\n
\n

\n 上表为托管侧技术默认;计费与试用/商用调用配额、并发档位以{' '}\n \n 会员套餐\n \n 说明为准,与上表独立。\n

\n
\n \n \n 当前线上版本:v1.0.0(网站未正式上线)。以下变更项为开发阶段规划记录,以正式发布公告为准。\n \n
\n {[\n { ver: 'v1.0.0', date: 'TBD', desc: '当前线上版本(网站未正式上线)' },\n ].map(l => (\n
\n {l.ver}\n {l.date}\n {l.desc}\n
\n ))}\n
\n
\n
\n\n \n );\n}\n\nexport default function DocsPage() {\n const locale = useLocale();\n return locale.startsWith('zh') ? : ;\n}\n"}, "5376ba40d9fd235425e84c7e70b98cc70fccee41": {"t": 1785765796.7490954, "n": 122951, "h": "b1230ec5d58ea199", "c": "'use client';\n\nimport { useLocale } from 'next-intl';\nimport { Link } from '@/i18n/routing';\nimport { DocsShell, type NavGroup } from './docs-shell';\nimport {\n CodeBlock,\n DocSection,\n SubDoc,\n ParamTable,\n Callout,\n FlowStep,\n ToolTable,\n} from './docs-shared';\nimport { DocsEnglishBody } from './docs-content-en';\nimport {\n BookOpen,\n Code2,\n Zap,\n FileText,\n Terminal,\n Globe,\n Mic,\n MessageSquare,\n BarChart3,\n AlertTriangle,\n Radio,\n FolderOpen,\n Workflow,\n Sparkles,\n Plug,\n Bot,\n Building2,\n Check,\n Sparkle,\n Languages,\n GraduationCap,\n Notebook,\n Gauge,\n ListChecks,\n} from 'lucide-react';\n\n/* ─── Navigation Structure ─── */\n\nconst NAV = [\n { id: 'concept', icon: Workflow, label: 'MCP 工作原理', children: [\n { id: 'why-mcp', label: '为什么需要 MCP' },\n { id: 'scenario-walkthrough', label: '场景走查 · 6 步' },\n { id: 'dev-responsibility', label: '开发者只做两件事' },\n { id: 'integration-paths', label: '三种接入姿势' },\n ]},\n { id: 'architecture', icon: Terminal, label: '架构说明', children: [\n { id: 'arch-diagram', label: '架构图' },\n { id: 'transport', label: '传输协议' },\n ]},\n { id: 'quick-start', icon: Zap, label: '快速开始', children: [\n { id: 'overview', label: '概述' },\n { id: 'requirements', label: '系统要求' },\n { id: 'install', label: '安装方式' },\n { id: 'env-vars', label: '环境变量' },\n ]},\n { id: 'config', icon: Plug, label: '接入 · 直接用(零代码)', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: '扣子(Coze)' },\n { id: 'config-coze-workflow', label: 'Coze 工作流' },\n { id: 'config-ai-workspace', label: 'AI 工作台 · 豆包 / 飞书 / WorkBuddy / 钉钉' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: '其他 MCP 客户端' },\n ]},\n { id: 'config-code', icon: Code2, label: '接入 · 编程用(SDK / 代码)', children: [\n { id: 'code-mcp-sdk', label: '官方 MCP 客户端库' },\n { id: 'code-agent-frameworks', label: 'LangChain / Mastra / Agents SDK' },\n { id: 'code-function-calling', label: '直调 chat.completions · 上传与动态 tools' },\n { id: 'llm-deepseek', label: 'DeepSeek' },\n { id: 'llm-glm', label: 'GLM(智谱)' },\n { id: 'llm-kimi', label: 'KIMI(Moonshot)' },\n { id: 'llm-doubao', label: '豆包 Seed 2.0(火山方舟)' },\n { id: 'llm-comparison', label: '模型对比速查' },\n { id: 'code-selfhosted-agent', label: '自研后端 Agent' },\n ]},\n { id: 'eval-modes', icon: Radio, label: '评测模式', children: [\n { id: 'stream-eval', label: '实时录音评测' },\n { id: 'stream-flow', label: '流式评测流程' },\n { id: 'file-eval', label: '音频文件评测' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API 参考', children: [\n { id: 'tools-en', label: '英文评测工具' },\n { id: 'tools-cn', label: '中文评测工具' },\n { id: 'result-fields', label: '评测结果字段' },\n { id: 'error-codes', label: '错误码' },\n ]},\n { id: 'best-practices', icon: FileText, label: '最佳实践', children: [\n { id: 'prompt-templates', label: 'Prompt 模板' },\n { id: 'error-handling', label: '错误处理' },\n { id: 'performance', label: '性能优化' },\n ]},\n { id: 'service-info', icon: Globe, label: '服务信息', children: [\n { id: 'endpoints', label: '服务端点' },\n { id: 'limits', label: '服务限制' },\n { id: 'changelog', label: '更新日志' },\n ]},\n];\n\nconst NAV_EN: NavGroup[] = [\n { id: 'concept', icon: Workflow, label: 'How MCP works', children: [\n { id: 'why-mcp', label: 'Why MCP' },\n { id: 'scenario-walkthrough', label: 'Scenario · 6 steps' },\n { id: 'dev-responsibility', label: 'Two developer tasks' },\n { id: 'integration-paths', label: 'Three integration styles' },\n ]},\n { id: 'architecture', icon: Terminal, label: 'Architecture', children: [\n { id: 'arch-diagram', label: 'Diagram' },\n { id: 'transport', label: 'Transports' },\n ]},\n { id: 'quick-start', icon: Zap, label: 'Quick start', children: [\n { id: 'overview', label: 'Overview' },\n { id: 'requirements', label: 'Requirements' },\n { id: 'install', label: 'Install' },\n { id: 'env-vars', label: 'Environment' },\n ]},\n { id: 'config', icon: Plug, label: 'Zero-code clients', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: 'Coze' },\n { id: 'config-coze-workflow', label: 'Coze workflows' },\n { id: 'config-ai-workspace', label: 'Enterprise AI workspaces' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: 'Other MCP clients' },\n ]},\n { id: 'config-code', icon: Code2, label: 'SDK / code integration', children: [\n { id: 'code-mcp-sdk', label: 'Official MCP SDK' },\n { id: 'code-agent-frameworks', label: 'Agent frameworks' },\n { id: 'code-function-calling', label: 'chat.completions · upload & tools' },\n { id: 'llm-deepseek', label: 'DeepSeek' },\n { id: 'llm-glm', label: 'GLM (Zhipu)' },\n { id: 'llm-kimi', label: 'KIMI (Moonshot)' },\n { id: 'llm-doubao', label: 'Doubao Seed 2.0 (Volcano Ark)' },\n { id: 'llm-comparison', label: 'Model comparison' },\n { id: 'code-selfhosted-agent', label: 'Custom backend' },\n ]},\n { id: 'eval-modes', icon: Radio, label: 'Evaluation modes', children: [\n { id: 'stream-eval', label: 'Streaming mic' },\n { id: 'stream-flow', label: 'Streaming flow' },\n { id: 'file-eval', label: 'Audio files' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API reference', children: [\n { id: 'tools-en', label: 'English tools' },\n { id: 'tools-cn', label: 'Chinese tools' },\n { id: 'result-fields', label: 'Result fields' },\n { id: 'error-codes', label: 'Errors' },\n ]},\n { id: 'best-practices', icon: FileText, label: 'Best practices', children: [\n { id: 'prompt-templates', label: 'Prompt templates' },\n { id: 'error-handling', label: 'Errors & retries' },\n { id: 'performance', label: 'Performance' },\n ]},\n { id: 'service-info', icon: Globe, label: 'Service info', children: [\n { id: 'endpoints', label: 'Endpoints' },\n { id: 'limits', label: 'Limits' },\n { id: 'changelog', label: 'Changelog' },\n ]},\n];\n\n/* ─── Page(英文 / 中文拆成两个组件,避免切换语言时 Hooks 数量变化导致白屏)─── */\n\nfunction DocsPageEn() {\n return (\n \n \n \n );\n}\n\nfunction DocsPageZh() {\n return (\n \n {/* ══════ MCP 工作原理 ══════ */}\n \n\n \n

\n 大模型(GPT / Claude / Gemini / 通义千问 等)本质上是文字大脑:它擅长读和写,但天生听不到音频、打不开你的数据库、调不通第三方 API。\n

\n

\n MCP(Model Context Protocol)是一套由 Anthropic 主导、业界共同推进的开放协议,它像一根\"对讲机\":让大模型可以在需要时主动去调用外部能力(工具、数据源、服务),然后把结果接回来继续对话。\n

\n
\n
\n
\n \n 没有 MCP 的做法\n
\n
    \n
  • · 研究评测服务的 REST 文档
  • \n
  • · 自己写鉴权 / 上传 / 轮询代码
  • \n
  • · 把结果序列化后塞进 prompt
  • \n
  • · 每换一个大模型都得重写一遍
  • \n
\n
\n
\n
\n \n 用驰声 MCP 之后\n
\n
    \n
  • · 填一行 MCP Server 地址
  • \n
  • · 大模型自动发现&调用评测工具
  • \n
  • · 换任何支持 MCP 的大模型都能用
  • \n
  • · 不写一行调用代码
  • \n
\n
\n
\n \n MCP 让\"接入语音评测\"从一个\"后端工程\"变成了一个\"配置项\"。这也是为什么 Cursor、Claude Desktop、Dify、Coze、字节豆包、飞书智能助手都已经原生支持 MCP。\n \n
\n\n \n

\n 想象一个具体场景:一位开发者用 Claude 做了一款 「AI 雅思口语陪练」小程序,接入驰声语音评测 MCP。当用户发来一段录音,整个链路是这样的:\n

\n
\n \n

配置阶段(开发者 · 一次性)

\n

在 AI 后端的配置文件里填一行驰声 MCP Server 地址。大模型启动时自动发现:「我多了一个叫语音评测的工具」。

\n
\n \n

接收用户指令(终端用户)

\n

小程序用户发来一段自我介绍录音:「帮我听听,发音哪里有问题?」后端把「文字 + 录音链接」打包给大模型。

\n
\n \n

大模型自主思考(LLM · 最核心的魔法)

\n
\n 「用户让我听发音。」
\n 「但我只是文字大脑,我听不到。」
\n 「等等 —— 开发者给了我一个叫 chivox_voice_eval 的 MCP 工具!」\n
\n
\n \n

MCP 协议 · 自动调用(LLM → 驰声)

\n

大模型自动按 MCP 标准构造 tools/call 请求,把录音链接和参考文本发到驰声服务。开发者不需要写任何调用代码。

\n
\n \n

驰声服务处理(评测引擎)

\n

驰声对音频进行考试级打分,把结构化结果通过 MCP 原路返回:overall 85、/θ/ 音发音错误、流利度 88。

\n
\n \n

大模型整合并输出反馈(LLM)

\n

大模型把冷冰冰的分数翻译成温柔反馈:

\n
\n 「你的自我介绍很棒!综合 85 分 🎉 不过 think 这个词的 /θ/ 咬舌音不太标准,我们一起来练一下……」\n
\n
\n
\n \n 整条链路里,MCP 只出现在 ① 和 ④:① 让开发者一次性告诉大模型「你多了一个工具」,④ 让大模型可以自动调用它。这两步的标准化,就是 MCP 的全部价值。\n \n
\n\n \n

听起来复杂,但对开发者来说只需要两件事:

\n
\n
\n
\n 1\n 填一次 MCP 配置\n
\n

\n 在 AI 后端的配置里填入驰声 MCP Server 地址和 API Key,就这一次,以后新加评测能力完全免开发。\n

\n {`{\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"apiKey\": \"sk-••••••••••\"\n }\n}`}\n
\n
\n
\n 2\n 写一段 System Prompt\n
\n

\n 告诉大模型这个工具是做什么的、什么时候调用、结果怎么转成用户友好的反馈。\n

\n {`你是一位英语口语教练。\n当用户发来录音时:\n1. 调用 chivox_voice_eval 评分\n2. 聚焦 <70 分的音素家族\n3. 用高情商话术给出练习建议`}\n
\n
\n

\n 其余所有事情 —— 音频上传、鉴权、工具发现、调用时机、返回格式、结果整合 —— 都由 MCP 协议和大模型自己搞定。\n

\n
\n\n \n

根据你的技术栈,有三种等价的接入方式,底层都走完全相同的 MCP 协议:

\n\n {/* ── 姿势一:可视化 ── */}\n
\n
\n \n

姿势一 · 可视化拖拽(扣子 / Coze / 飞书智能助手)

\n
\n

\n 适合产品经理、运营、不写后端代码的开发者。整个过程像在手机上装 App。\n

\n
    \n
  1. 找到入口:在扣子平台的 「插件 / 工具」 配置区,点击「添加 MCP 服务」。
  2. \n
  3. 填两个字段(这也是你未来会从驰声这边拿到的):\n
    \n \n \n \n \n \n
    服务器地址https://speech-eval.site/mcp
    鉴权密钥sk-•••••••••• (由驰声分配,用于计费与识别)
    \n
    \n
  4. \n
  5. 平台自动发现能力:扣子会访问你填的地址,读取 MCP Server 自描述的\"说明书\"。瞬间明白:「这是个语音评测工具,需要传音频,会返发音分」。
  6. \n
  7. 右侧测试:在平台的聊天框里发一段语音,大模型就会自动调用工具。整个过程不需要写一行代码。
  8. \n
\n
\n\n {/* ── 姿势二:代码框架 ── */}\n
\n
\n \n

姿势二 · 代码框架配置(Dify / LangChain / 自研后端)

\n
\n

\n 适合做独立 APP / 小程序、用 Dify 或 LangChain 写 Agent 的极客开发者。核心就是往配置文件里加一段 JSON。\n

\n
    \n
  1. 打开配置文件(项目根目录下的 mcp.json 或框架指定的配置路径)。
  2. \n
  3. 在 mcpServers 下增加一个节点:\n {`{\n \"mcpServers\": {\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"env\": {\n \"API_KEY\": \"你的专属密钥\"\n }\n }\n }\n}`}\n
  4. \n
  5. 重启后端服务。大模型的底层调度器会在启动时自动连上驰声 MCP Server,把 16 种评测工具注册成随时待命的 tools。
  6. \n
  7. 触发调用:用户发来录音后,大模型看到 system prompt 的引导,自动选择合适的工具(单词/句子/段落/半开放)调用。
  8. \n
\n
\n\n {/* ── 姿势三:Function Calling 直连(分 A / B 两种做法) ── */}\n
\n
\n \n

姿势三 · 原生 Function Calling(豆包 / DeepSeek / OpenAI 兼容 API)

\n
\n

\n 适合不用任何 Agent 框架、直接调用 LLM API 的后端开发者。豆包 1.5+ / DeepSeek / GPT / Qwen 等模型都走标准 chat.completions 的 tools 参数。这里又分 A / B 两种做法,B 才是生产推荐。\n

\n\n \n 常见疑问:\"要不要手写一个 tool 定义?\"
\n — 姿势一 / 二不用(Coze、Dify、火山方舟控制台、Claude Desktop 会自动从 MCP Server 拉工具列表)。
\n — 姿势三看你选 A 还是 B:A 要手写,B 用 MCP 客户端库自动拉。\n
\n\n {/* ── 3-A:手写 tool schema ── */}\n
\n
\n

3-A · 手写 tool schema(最快验证,不推荐生产)

\n 快速 Demo\n
\n

\n 自己写一段 JSON Schema 告诉豆包\"有个工具叫 xxx,参数长这样\",豆包返回 tool_call 后你再手动去调驰声 MCP。缺点:驰声有 16 个评测工具,你每加一个题型都要改代码。\n

\n {`import os, json\nfrom openai import OpenAI\n\nclient = OpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv('ARK_API_KEY'),\n)\n\n# ─── 手写一段 tool schema(不推荐:16 个工具就要写 16 段)───\ntools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": \"en_word_eval\",\n \"description\": \"英语单词发音评测。当用户让你评价英语发音并提供录音链接时调用。\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"audio_url\": {\"type\": \"string\", \"description\": \"录音 URL\"},\n \"reference_text\": {\"type\": \"string\", \"description\": \"参考文本,如 Apple\"},\n },\n \"required\": [\"audio_url\", \"reference_text\"]\n }\n }\n}]\n\nresp = client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,拿到评测结果后温柔地反馈,不要直接报分数。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n)\n\nmsg = resp.choices[0].message\nif msg.tool_calls:\n args = json.loads(msg.tool_calls[0].function.arguments)\n # ↓↓↓ 这里手动调驰声 MCP,再把结果回填给豆包做第二趟 ↓↓↓\n # result = requests.post(\"https://speech-eval.site/mcp\", json={...})`}\n
\n\n {/* ── 3-B:MCP 自动发现 ── */}\n
\n
\n

\n 3-B · 用 MCP 客户端库自动发现 \n

\n 生产推荐\n
\n

\n 启动时连上驰声 MCP Server,调一次 tools/list,把 16 个评测工具自动转成 Function Calling 的 tools 格式。驰声加新工具,你代码不用改。这才是 MCP 协议的真正价值。\n

\n {`import asyncio, os\nfrom openai import AsyncOpenAI\nfrom mcp import ClientSession\nfrom mcp.client.streamable_http import streamablehttp_client\n\nclient = AsyncOpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv(\"ARK_API_KEY\"),\n)\n\nasync def main():\n # ─── 1. 连驰声 MCP Server,自动拉取全部 16 个工具 ───\n async with streamablehttp_client(\n \"https://speech-eval.site/mcp\",\n headers={\"Authorization\": f\"Bearer {os.getenv('CHIVOX_KEY')}\"},\n ) as (read, write, _):\n async with ClientSession(read, write) as session:\n await session.initialize()\n mcp_tools = (await session.list_tools()).tools # ← 一行拿到全部工具\n\n # ─── 2. MCP schema → OpenAI Function Calling schema ───\n tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema, # MCP 直接给 JSON Schema\n }\n } for t in mcp_tools]\n\n # ─── 3. 正常调豆包,tools 由 MCP 动态注入 ───\n resp = await client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,收到评测结果后温柔反馈。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n )\n\n # ─── 4. 折返跑:豆包选好工具后,直接走 MCP 调驰声 ───\n msg = resp.choices[0].message\n if msg.tool_calls:\n call = msg.tool_calls[0]\n result = await session.call_tool(\n call.function.name,\n arguments=__import__(\"json\").loads(call.function.arguments),\n )\n # 把 result 回填给豆包做第二趟 chat.completions 即可\n\nasyncio.run(main())`}\n

\n 想要更省心?直接用 官方 mcp python sdk、mcp-use、openai-agents,或火山官方 Arkitect 高代码 SDK,它们都把上面这段\"MCP → Function Calling\"的桥接封装好了。\n

\n
\n
\n\n \n 三种姿势走的是完全相同的 MCP 协议,能力完全等价。选型建议:产品经理 / 原型验证用姿势一(Coze 填表单);AI 客户端用户用姿势二(Cursor / Claude Desktop 填 mcp.json);后端生产服务用姿势三-B(MCP 客户端库自动发现工具,不要手写 tool schema)。\n \n
\n\n
\n\n {/* ══════ 架构说明 ══════ */}\n \n\n \n
\n
\n

AI 客户端

\n

Claude Desktop
Claude Code
Cursor

\n
\n
\n

⇄

\n

stdio

\n
\n
\n

chivox-local-mcp

\n

本地代理
SoX 录音

\n
\n
\n

⇄

\n

HTTP / WS

\n
\n
\n

Remote Chivox

\n

MCP Server
评测引擎

\n
\n
\n
\n\n \n
    \n
  • \n \n stdio — AI 客户端通过标准输入输出与本地代理通信,这是 MCP 的标准传输方式\n
  • \n
  • \n \n HTTP — 音频文件评测工具通过 HTTP 代理到远程服务,适用于非流式场景\n
  • \n
  • \n \n WebSocket — 实时录音音频通过 WebSocket 流式推送,支持断线自动重连\n
  • \n
\n
\n
\n\n {/* ══════ 快速开始 ══════ */}\n \n\n \n

chivox-local-mcp 是驰声语音评测的 MCP 本地代理,通过 Model Context Protocol 将远程驰声评测服务桥接到本地,让 AI 助手(Claude Desktop、Claude Code、Cursor 等)直接调用语音评测能力。

\n

它支持两种评测模式,覆盖从即时交互到批量处理的全部场景:

\n
\n
\n
\n \n 实时录音评测\n
\n

通过麦克风边录边评,音频以 WebSocket 流式推送,无需生成中间文件,延迟更低、体验更佳。

\n
\n
\n
\n \n 音频文件评测\n
\n

支持本地文件路径、Base64 编码、URL 三种输入,适合已有音频的批量评测场景。

\n
\n
\n 当前支持 16 种评测工具:英文 10 种(单词、句子、段落、纠音、自然拼读、口语选择、半开放题等)+ 中文 6 种(汉字、拼音、词句、段落、有限分支、AI Talk)。\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n
依赖版本说明
Node.js{'>'}= 18运行时必须
SoXany仅实时录音功能需要(处理麦克风音频流)
\n
\n

安装 SoX(仅在使用实时录音时需要):

\n {`# macOS\nbrew install sox\n\n# Ubuntu / Debian\nsudo apt-get install sox`}\n
\n\n \n

方式一:npm 全局安装(推荐)

\n {`npm install -g chivox-local-mcp`}\n\n

方式二:npx 免安装运行

\n {`MCP_REMOTE_URL=http://your-server:8080 npx chivox-local-mcp`}\n\n

方式三:从源码构建

\n {`git clone https://git.chivox.com/CLOUD_DEV/cvx_local_mcp.git\ncd cvx_local_mcp\nbash scripts/build.sh`}\n
\n\n \n \n \n
\n\n {/* ══════ 接入 · 直接用(零代码) ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 不用写代码、不用装 SDK,只在客户端的「MCP 配置」或「扩展」里填一段 JSON / URL
  • \n
  • 保存后 LLM 自动发现 16 个评测工具,并在对话 / Agent 中自主调用
  • \n
  • 覆盖 IDE 编程助手、桌面 AI 客户端、企业 AI 工作台、可视化 Bot / 工作流平台四大生态
  • \n
\n
\n\n\n \n
    \n
  1. 打开 Cursor 设置(Cmd + ,)
  2. \n
  3. 左侧选择 MCP(或搜索 "MCP")
  4. \n
  5. 点击 Add new MCP server
  6. \n
  7. 填写配置并保存:
  8. \n
\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n}`}\n Cursor 使用远程 Streamable HTTP 模式直连,无需安装本地代理。如需实时录音功能,请使用下方 Claude Desktop 的本地代理配置。\n
\n\n \n

编辑配置文件(macOS:~/Library/Application Support/Claude/claude_desktop_config.json):

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"chivox-local-mcp\",\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\",\n \"MCP_API_KEY\": \"your-api-key\"\n }\n }\n }\n}`}\n

如果是从源码构建:

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/cvx_local_mcp/dist/index.js\"],\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\"\n }\n }\n }\n}`}\n Claude Desktop 使用本地代理模式(stdio),支持实时录音评测。本地代理会自动桥接远程服务。\n
\n\n \n {`# npm 全局安装后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 chivox-local-mcp\n\n# 源码构建后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 node /path/to/cvx_local_mcp/dist/index.js`}\n \n\n \n

除了 Cursor 和 Claude Code,主流的 AI 编程 IDE 都原生支持 MCP。以下客户端使用完全一致的 Streamable HTTP 配置,区别只在配置入口:

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
客户端配置入口备注
Windsurf (Codeium)Settings → Cascade → MCP Servers直接贴下方 JSON
Zed~/.config/zed/settings.json 的 context_serversAssistant Panel 自动发现
Continue (VS Code / JetBrains)config.yaml 的 mcpServersv0.9+ 支持
通义灵码 / CodeGeeX / 文心快码插件设置 → MCP 服务2026 Q1 起陆续支持
Cline (原 Claude Dev)MCP Servers 面板 → 编辑配置VS Code 扩展
\n
\n {`{\n \"mcpServers\": {\n \"chivox-speech-eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n }\n }\n}`}\n 所有 IDE 类客户端都走远程 Streamable HTTP,零本地依赖。需要实时录音才需切到 Claude Desktop 的本地代理模式。\n
\n\n \n

扣子(Coze)是字节跳动推出的 AI 应用开发平台,支持通过 MCP 扩展为 Agent 赋予外部工具能力。接入驰声语音评测后,你可以构建口语练习 Bot、发音诊断助手等应用。

\n

方式一:扣子空间 MCP 扩展(推荐)

\n
    \n
  1. 打开 扣子空间(space.coze.cn)
  2. \n
  3. 在对话框下方点击 「添加扩展」
  4. \n
  5. 选择 「自定义」 标签,点击添加新的 MCP 服务
  6. \n
  7. 填入以下配置信息:
  8. \n
\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
名称chivox-speech-eval
传输类型streamable-http
URLhttps://speech-eval.site/mcp
\n
\n
    \n
  1. 保存后,在对话中输入 「帮我评测这段英文发音」 即可触发 Agent 调用
  2. \n
\n 添加 MCP 扩展后,扣子空间的 Agent 会自动识别并调用评测工具。你可以在 Agent 的思考过程中看到具体的工具调用细节。\n\n

方式二:在 Coze 开发平台的 Bot 中使用

\n
    \n
  1. 进入 Coze 开发平台,创建或编辑 Bot
  2. \n
  3. 在 Bot 的 「插件」 或 「工具」 面板中,添加 MCP 工具
  4. \n
  5. 选择 Streamable HTTP 类型,填入 URL:https://speech-eval.site/mcp
  6. \n
  7. Bot 将自动发现所有可用的评测工具(如 evaluate_english_word 等)
  8. \n
  9. 在 Bot 的人设提示词中,添加语音评测相关的引导语
  10. \n
\n {`你是一位专业的英语口语教练。当用户上传音频并请求评测时:\n1. 使用 evaluate_english_word / evaluate_english_sentence 等工具进行评测\n2. 根据评测结果(overall、accuracy、fluency 等分数)给出专业分析\n3. 针对得分较低的维度提供具体改进建议\n4. 鼓励用户持续练习`}\n
\n\n \n

如果你需要在 Coze 工作流中集成语音评测能力,可以通过 HTTP Request 节点调用评测 API:

\n\n

步骤 1:上传音频

\n

在工作流中添加一个 HTTP Request 节点,配置如下:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
配置项值
方法POST
URLhttps://speech-eval.site/upload
Content-Typeaudio/mp3
Body音频文件二进制数据
\n
\n

响应中获取 {'{{audioId}}'},传递给下一步。

\n\n

步骤 2:调用评测

\n

添加第二个 HTTP Request 节点,通过 MCP 接口调用评测工具:

\n {`{\n \"jsonrpc\": \"2.0\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"evaluate_english_sentence\",\n \"arguments\": {\n \"audioId\": \"{{audioId}}\",\n \"sentence\": \"{{ref_text}}\"\n }\n },\n \"id\": 1\n}`}\n\n

步骤 3:处理结果

\n

评测结果通过 JSON 格式返回,可使用 Coze 的 代码节点 或 LLM 节点 对结果进行解析和二次处理(如生成学习建议、计算进步趋势等)。

\n\n 工作流方式适合需要固定流程的场景(如批量评测、定时任务、与其他系统联动)。如果是交互式场景,推荐使用上方的 MCP 扩展方式,Agent 会自动选择合适的工具。\n\n
\n

完整工作流示意

\n
\n 用户输入音频\n →\n HTTP: 上传音频\n →\n HTTP: 调用评测\n →\n LLM: 分析结果\n →\n 输出反馈\n
\n
\n
\n\n \n

这一类是面向「上班族」的企业 / 日常 AI 助手,产品形态是个聊天框 + 插件市场 / 扩展面板。接入后,员工在 App 里打字「帮我评一下这段录音」就能自动触发驰声评测,不用写任何代码。

\n\n
\n
\n

豆包(Doubao)App / 桌面版

\n

字节跳动官方 AI 助手,2026 年起桌面版支持 MCP 扩展。

\n
    \n
  1. 桌面版设置 → 「智能体扩展」 → 添加 MCP 服务
  2. \n
  3. 类型选 streamable-http,URL 填 https://speech-eval.site/mcp
  4. \n
  5. 对话中直接说「帮我评测」即可自动调用
  6. \n
\n
\n\n
\n

飞书智能伙伴(My AI)

\n

飞书企业 AI,支持以 MCP / Function Calling 挂载外部工具给团队 Bot。

\n
    \n
  1. 飞书开发者后台 → 创建应用 → 「AI 能力 / 智能伙伴」
  2. \n
  3. 在「工具」中选 外部 MCP 服务,填入上方 URL
  4. \n
  5. 把智能伙伴拉进群聊,@ 它提交音频即可评测
  6. \n
\n
\n\n
\n

WorkBuddy / 企业智能助手

\n

字节 WorkBuddy、腾讯会议 AI、企业微信智能助手等企业 AI 工作台场景。

\n
    \n
  1. 在工作台的「技能 / 扩展」后台新增一个 MCP 连接器
  2. \n
  3. 传输协议选 Streamable HTTP,地址填 https://speech-eval.site/mcp
  4. \n
  5. 把技能发布到指定部门 / 群组,HR、培训、销售口语陪练场景即可直接用
  6. \n
\n
\n\n
\n

钉钉 AI 助理 / 通义千问 App

\n

阿里生态:钉钉 AI 助理支持自定义插件,通义 App 可通过「AI 工具箱」挂载 MCP。

\n
    \n
  1. 钉钉开发者后台 → AI 助理 → 「插件开发 / MCP 接入」
  2. \n
  3. 选 HTTP Streamable,填入驰声 MCP URL 并开启鉴权(可选)
  4. \n
  5. 在钉钉群 @AI 助理上传音频,自动返回评测卡片
  6. \n
\n
\n
\n\n 典型场景 · 小龙虾们的共同剧本:销售口语陪练 → 外语培训 → 主持 / 播音岗位考核 → K12 英语作业批改 → 客服话术复盘。这些「上班族 AI 工作台」接入驰声 MCP 后,员工 / 学员只要对着话筒说话,AI 就能自动打分并给出个性化改进建议,运营 / 培训 / 教研团队零开发即可上线。\n
\n\n \n

如果你需要把语音评测编排进多步业务流(例如:学员录音 → 评测 → 生成错题集 → 推送到 CRM),可视化工作流平台比聊天 Bot 更合适。

\n\n
\n
\n

Dify

\n

开源 LLMOps,v0.15+ 原生 MCP 工具。

\n
    \n
  • 「工具」→「自定义 MCP」→ 填 URL
  • \n
  • 在 Chatflow / Workflow 节点里直接拖用
  • \n
\n
\n
\n

n8n

\n

工作流自动化,用 MCP Client 节点。

\n
    \n
  • 添加 MCP Client 节点
  • \n
  • Transport 选 HTTP Stream,URL 贴驰声地址
  • \n
  • Tool 下拉自动列出 16 个评测能力
  • \n
\n
\n
\n

Flowise / LangFlow

\n

可视化 LangChain Agent 编排。

\n
    \n
  • 拖出 MCP Tool 节点
  • \n
  • 连到 AgentExecutor 即可
  • \n
\n
\n
\n\n 可视化平台的好处是流程可追溯、可回放,适合教育机构 / 培训部门做批量评测 + 报表导出;缺点是单步延迟略高于直接 MCP 调用,对延迟敏感的交互场景建议用 Cursor / Claude Desktop 直连。\n
\n\n \n

任何遵循 MCP 协议的客户端都可以接入,统一使用以下配置:

\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
传输类型streamable-http
URLhttps://speech-eval.site/mcp
鉴权(可选)Header:Authorization: Bearer <MCP_API_KEY>
\n
\n

还没找到你用的客户端?任何支持 Model Context Protocol 的终端都通用。找不到入口?下一小节「编程用 MCP」里用 SDK 直接接即可。

\n
\n
\n\n {/* ══════ 接入 · 编程用 MCP ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 你在写一段真正的后端服务:一个 Agent Worker、一个 API、一个自动化脚本
  • \n
  • 业务里的「语音评测」是其中一个步骤,需要由代码 决定何时调用、如何解析结果
  • \n
  • 三种主流写法:① 官方 MCP 客户端库 → ② Agent 框架自动桥接 → ③ 退化到 chat.completions + tools 参数
  • \n
\n

💡 强烈推荐①或②:驰声有 16 个评测工具,让 MCP 自动注入 tool schema,每新增一个题型不用改一行业务代码。

\n
\n\n \n

最底层、也最推荐的方式。由 Anthropic 官方维护,一次连接自动拿到全部工具的 JSON Schema,然后交给任意 LLM。

\n\n

Python:mcp

\n {`# pip install mcp openai\nimport asyncio, os\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nMCP_URL = \"https://speech-eval.site/mcp\"\nllm = OpenAI(api_key=os.getenv(\"DOUBAO_KEY\"),\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\") # 豆包 / DeepSeek / OpenAI 同构\n\nasync def main(audio_id: str, ref: str):\n async with streamablehttp_client(MCP_URL) as (reader, writer, _):\n async with ClientSession(reader, writer) as sess:\n await sess.initialize()\n\n tools = await sess.list_tools()\n openai_tools = [{\n \"type\": \"function\",\n \"function\": {\"name\": t.name, \"description\": t.description,\n \"parameters\": t.inputSchema},\n } for t in tools.tools]\n\n resp = llm.chat.completions.create(\n model=\"doubao-1-5-pro-32k\",\n messages=[{\"role\": \"user\",\n \"content\": f\"帮我评测 audioId={audio_id},参考文本:{ref}\"}],\n tools=openai_tools,\n )\n\n for call in resp.choices[0].message.tool_calls or []:\n result = await sess.call_tool(call.function.name,\n arguments=eval(call.function.arguments))\n print(call.function.name, \"→\", result.content[0].text[:200])\n\nasyncio.run(main(\"abc123\", \"I think therefore I am\"))`}\n\n

TypeScript / Node.js:@modelcontextprotocol/sdk

\n {`// npm i @modelcontextprotocol/sdk openai\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport OpenAI from \"openai\";\n\nconst mcp = new Client({ name: \"chivox-biz\", version: \"1.0.0\" });\nawait mcp.connect(new StreamableHTTPClientTransport(new URL(\"https://speech-eval.site/mcp\")));\n\nconst { tools } = await mcp.listTools();\nconst openai = new OpenAI({ apiKey: process.env.DEEPSEEK_KEY, baseURL: \"https://api.deepseek.com\" });\n\nconst resp = await openai.chat.completions.create({\n model: \"deepseek-chat\",\n messages: [{ role: \"user\", content: \"评测 audioId=abc123, 参考 I think therefore I am\" }],\n tools: tools.map(t => ({ type: \"function\", function: {\n name: t.name, description: t.description, parameters: t.inputSchema\n }})),\n});\n\nfor (const call of resp.choices[0].message.tool_calls ?? []) {\n const r = await mcp.callTool({ name: call.function.name,\n arguments: JSON.parse(call.function.arguments) });\n console.log(call.function.name, r.content);\n}`}\n 这种写法 LLM 供应商可换(豆包 / DeepSeek / GPT / Qwen / Moonshot),工具自动更新(驰声新增题型无需改业务代码),适合生产后端。\n
\n\n \n

如果项目已经在用 Agent 框架,几行 adapter 就能把驰声 MCP 塞进去,框架本身会接管 tool-calling 循环、重试、日志。

\n\n
\n
\n

LangChain / LangGraph(Python)

\n {`# pip install langchain-mcp-adapters langgraph\nfrom langchain_mcp_adapters.client import MultiServerMCPClient\nfrom langgraph.prebuilt import create_react_agent\n\nclient = MultiServerMCPClient({\n \"chivox\": {\n \"transport\": \"streamable_http\",\n \"url\": \"https://speech-eval.site/mcp\",\n }\n})\ntools = await client.get_tools()\n\nagent = create_react_agent(\"openai:gpt-4o-mini\", tools)\nresult = await agent.ainvoke({\"messages\":\n [(\"user\", \"评测 audioId=abc123 参考 think\")]})\nprint(result[\"messages\"][-1].content)`}\n
\n\n
\n

Mastra(TypeScript)

\n {`// npm i @mastra/core @mastra/mcp\nimport { MCPClient } from \"@mastra/mcp\";\nimport { Agent } from \"@mastra/core/agent\";\nimport { openai } from \"@ai-sdk/openai\";\n\nconst mcp = new MCPClient({ servers: {\n chivox: { url: new URL(\"https://speech-eval.site/mcp\") }\n}});\n\nexport const speechCoach = new Agent({\n name: \"speech-coach\",\n instructions: \"你是口语教练,用 chivox 工具评测并给改进建议。\",\n model: openai(\"gpt-4o-mini\"),\n tools: await mcp.getTools(),\n});`}\n
\n\n
\n

OpenAI Agents SDK(Python)

\n {`# pip install openai-agents\nfrom agents import Agent, Runner\nfrom agents.mcp import MCPServerStreamableHttp\n\nchivox = MCPServerStreamableHttp(\n params={\"url\": \"https://speech-eval.site/mcp\"},\n name=\"chivox-speech-eval\",\n)\n\nasync with chivox:\n agent = Agent(name=\"coach\",\n instructions=\"专业口语教练\",\n mcp_servers=[chivox])\n r = await Runner.run(agent, \"评测 audioId=abc123\")\n print(r.final_output)`}\n
\n\n
\n

LlamaIndex / AutoGen / CrewAI

\n

这些框架都有官方或社区 MCP adapter,用法与上述类似:

\n
    \n
  • LlamaIndex:llama-index-tools-mcp
  • \n
  • AutoGen:autogen-ext[mcp]
  • \n
  • CrewAI:crewai-tools 的 MCPServerAdapter
  • \n
  • Spring AI(Java):spring-ai-mcp-client
  • \n
\n
\n
\n
\n\n \n

\n DeepSeek、GLM(智谱)、KIMI(Moonshot)、豆包(火山方舟)、千帆、DashScope 等若提供 OpenAI 兼容的 HTTP API,接入驰声 MCP 的套路一致:用 MCP 客户端拉取工具列表 → 转为{' '}\n tools → 模型决策 tool_calls → MCP 执行并回填 → 再让模型生成诊断话术。\n

\n
\n
\n ① MCP list_tools()\n →\n ② 转 OpenAI tools 格式\n →\n ③ LLM 决策 tool_calls\n →\n ④ MCP call_tool()\n →\n ⑤ 评测结果回填 → LLM 诊断\n
\n
\n 各厂商仅需替换 base_url 与 api_key,驰声 MCP 与 tools 桥接代码可原样复用。\n\n

先上传音频,拿到 audioId

\n

文件评测工具通常需要 audioId(或路径参数,视工具而定)。下面是用 HTTP 上传的最小示例:

\n {`import requests\n\nwith open('audio.mp3', 'rb') as f:\n r = requests.post(\n 'https://speech-eval.site/upload',\n data=f,\n headers={'Content-Type': 'audio/mp3'}\n )\n\nresult = r.json()\nprint(f\"audioId: {result['audioId']}\")\nprint(f\"size: {result['size']} bytes\")\nprint(f\"expires: {result['expiresIn']}\")`}\n {`const fs = require('fs');\n\nconst audioData = fs.readFileSync('audio.mp3');\n\nconst res = await fetch('https://speech-eval.site/upload', {\n method: 'POST',\n headers: { 'Content-Type': 'audio/mp3' },\n body: audioData,\n});\n\nconst result = await res.json();\nconsole.log('audioId:', result.audioId);`}\n\n

再以豆包为例:MCP 动态 tools + chat.completions 折返跑

\n

当你用的 LLM SDK 还没有原生 MCP 支持(比如老版本的火山方舟 / 百度千帆 / 通义 DashScope),退化方案是:用 MCP 客户端一次性拉到 tool schema,然后按 OpenAI Function Calling 格式喂给 LLM。

\n {`# 适用:豆包(火山方舟)/ DeepSeek / Qwen / Moonshot / GLM 等 OpenAI 兼容 API\n# 核心思路:MCP 列工具 → 转 OpenAI tools → LLM 决策 → MCP 执行 → 回填\n\nasync with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n\n # ① 用 MCP 拉到的 schema 自动转 OpenAI 格式\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 喂给豆包\n messages = [{\"role\": \"user\", \"content\": \"评测一下 audioId=abc123\"}]\n resp = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages, tools=oa_tools,\n )\n\n # ③ LLM 回 tool_calls → 折返跑到 MCP 执行\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for c in msg.tool_calls:\n result = await mcp.call_tool(\n c.function.name, arguments=json.loads(c.function.arguments))\n messages.append({\"role\": \"tool\", \"tool_call_id\": c.id,\n \"content\": result.content[0].text})\n # ④ 再喂一轮,让豆包根据评测结果产出自然语言诊断\n final = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages)\n print(final.choices[0].message.content)`}\n 千万别手写 tool schema!驰声共 16 个评测工具(英文 10 + 中文 6),每个工具参数较多,手写既容易错也难维护。一定用 MCP list_tools() 动态拿。\n
\n\n \n

DeepSeek 提供与 OpenAI 完全兼容的 API,推荐使用 deepseek-chat(V3)或 deepseek-reasoner(R1)。

\n\n

环境准备

\n {`DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# DeepSeek 客户端(OpenAI 兼容)\nclient = OpenAI(\n api_key=os.environ[\"DEEPSEEK_API_KEY\"],\n base_url=\"https://api.deepseek.com\",\n)\n\nasync def evaluate_with_deepseek(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # ① 拉取驰声 MCP 工具列表\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 调用 DeepSeek,让它选择合适的评测工具\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段英文录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"deepseek-chat\", # 或 deepseek-reasoner\n messages=messages,\n tools=oa_tools,\n )\n\n # ③ 执行 tool_calls\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n # ④ 让 DeepSeek 根据评测结果生成自然语言诊断\n final = client.chat.completions.create(\n model=\"deepseek-chat\",\n messages=messages,\n )\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_deepseek(\"audio_abc123\", \"Hello, nice to meet you.\"))`}\n 推荐使用 deepseek-chat(V3)处理评测结果诊断,速度快、成本低;若需要深度分析或出题逻辑,可换用 deepseek-reasoner(R1),但注意 R1 不支持 Function Calling,需先用 V3 做工具调用再将结果交给 R1 分析。\n
\n\n \n

智谱 AI 提供 glm-4、glm-4-flash(免费)等模型,支持 OpenAI 兼容接口,同时也有官方 Python SDK。

\n\n

环境准备

\n {`ZHIPU_API_KEY=xxxxxxxx.xxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

方式一:OpenAI 兼容接口(推荐)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = OpenAI(\n api_key=os.environ[\"ZHIPU_API_KEY\"],\n base_url=\"https://open.bigmodel.cn/api/paas/v4/\",\n)\n\nasync def evaluate_with_glm(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"glm-4-flash\", # 免费模型;生产可换 glm-4 或 glm-4-plus\n messages=messages,\n tools=oa_tools,\n )\n\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n final = client.chat.completions.create(\n model=\"glm-4-flash\", messages=messages)\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_glm(\"audio_abc123\", \"How are you today?\"))`}\n\n

方式二:官方 zhipuai SDK

\n {`from zhipuai import ZhipuAI\n\nclient = ZhipuAI(api_key=os.environ[\"ZHIPU_API_KEY\"])\n\n# 其余逻辑与方式一相同,仅替换 client 实例\nresp = client.chat.completions.create(\n model=\"glm-4-flash\",\n messages=messages,\n tools=oa_tools,\n)`}\n glm-4-flash 免费,适合开发测试;glm-4-plus 上下文更长、指令遵循更准,适合生产环境中的诊断报告生成。\n
\n\n \n

Moonshot AI 的 KIMI 模型同样兼容 OpenAI API,支持超长上下文(最高 128k),特别适合需要分析多段录音历史或生成详细学习报告的场景。

\n\n

环境准备

\n {`MOONSHOT_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = OpenAI(\n api_key=os.environ[\"MOONSHOT_API_KEY\"],\n base_url=\"https://api.moonshot.cn/v1\",\n)\n\nasync def evaluate_with_kimi(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段英文录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"moonshot-v1-8k\", # 也可选 moonshot-v1-32k / moonshot-v1-128k\n messages=messages,\n tools=oa_tools,\n )\n\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n final = client.chat.completions.create(\n model=\"moonshot-v1-8k\", messages=messages)\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_kimi(\"audio_abc123\", \"Nice to meet you.\"))`}\n KIMI 的长上下文特别适合「多轮口语练习 + 历史分析」场景:把用户过去 10 次的评测 JSON 全部塞进 messages,让 KIMI 生成横跨多次练习的进步报告,这是 8k 模型做不到的。\n
\n\n \n

\n 字节跳动 豆包 Seed 2.0(2026 年 2 月发布)是 ByteDance Seed 团队推出的新一代通用大模型,覆盖 Pro / Lite / Mini / Code 多种规格,\n 通过 火山方舟(Volcano Ark) 提供 OpenAI 兼容的 /api/v3/chat/completions 接口,\n 原生支持 Function Calling、JSON Schema 结构化输出、深度思考(Chain-of-Thought)模式,\n 接驰声 MCP 几乎无须改动业务代码。\n

\n\n \n 豆包 Seed 2.0 的优势在 深度思考 + 工具编排:让模型一次性规划\"先调 en.sent.score,看完弱项再调 en.word.score 进一步定位音素\",\n 适合做\"多步评测 + 自动纠音\"这类 Agent 场景。\n 默认开启思考模式,可通过 {'thinking: { type: \"disabled\" }'} 关闭以节省时延。\n \n\n

推荐版本

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n
model规格推荐用途
doubao-seed-2-0-pro-260215Pro · 旗舰多步评测 + 深度诊断 + 复杂 Agent 编排
doubao-seed-2-0-lite-260215Lite · 平衡在线辅导单轮评测 + 自然语言反馈,性价比首选
doubao-seed-2-0-mini-260215Mini · 极小高并发 / 边缘部署 / 移动端实时反馈
doubao-seed-2-0-code-preview-260215Code · 预览代码生成 / 工具编排 DSL,对评测场景非主推
\n
\n\n

环境准备

\n {`# 火山方舟控制台 → API Key 管理\nARK_API_KEY=ak-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python · 动态 tools + 折返跑)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# 火山方舟 OpenAI 兼容端点\nclient = OpenAI(\n api_key=os.environ[\"ARK_API_KEY\"],\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n)\n\nMODEL = \"doubao-seed-2-0-pro-260215\" # 也可换成 lite / mini\n\nasync def evaluate_with_doubao(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # ① 把驰声 16 个评测工具的 schema 动态注入豆包\n tools = (await mcp.list_tools()).tools\n ark_tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n },\n } for t in tools]\n\n messages = [\n {\"role\": \"system\",\n \"content\": \"你是一位专业的英语口语教练,会主动调用驰声评测工具获取真实分数。\"},\n {\"role\": \"user\",\n \"content\": f\"请评测这段录音,audio_id={audio_id},参考文本:{ref_text}。\"\n f\"先做句子级评测,弱项再追加单词级定位。\"},\n ]\n\n # ② 第一轮 —— 让豆包根据 prompt 自主选工具\n resp = client.chat.completions.create(\n model=MODEL,\n messages=messages,\n tools=ark_tools,\n tool_choice=\"auto\",\n # extra_body={\"thinking\": {\"type\": \"disabled\"}}, # 需要时可关思考\n )\n\n msg = resp.choices[0].message\n messages.append(msg)\n\n # ③ 折返跑:豆包可能一次发起多个 tool_calls,全部回填\n for call in (msg.tool_calls or []):\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n # ④ 第二轮 —— 让豆包基于真实评测 JSON 输出诊断 / 练习建议\n final = client.chat.completions.create(\n model=MODEL,\n messages=messages,\n )\n return final.choices[0].message.content\n\nprint(asyncio.run(evaluate_with_doubao(\n audio_id=\"audio_abc123\",\n ref_text=\"The quick brown fox jumps over the lazy dog.\",\n)))`}\n\n

深度思考模式(可选)

\n

\n 豆包 Seed 2.0 默认开启 thinking 模式,会在内部生成思维链再产出答案,\n 对\"多步评测编排 / 复杂诊断\"质量明显更好;但会增加 30%~80% 的端到端延迟。\n 在 extra_body 里可显式控制:\n

\n {`# 关闭思考(更快、适合实时反馈)\nclient.chat.completions.create(\n model=\"doubao-seed-2-0-lite-260215\",\n messages=messages,\n tools=ark_tools,\n extra_body={\"thinking\": {\"type\": \"disabled\"}},\n)\n\n# 开启思考(默认,适合 Pro 模型 + 多步 Agent)\nclient.chat.completions.create(\n model=\"doubao-seed-2-0-pro-260215\",\n messages=messages,\n tools=ark_tools,\n extra_body={\"thinking\": {\"type\": \"enabled\"}},\n)`}\n\n \n 选型建议:\n 课堂 / 培训类一对一辅导用 doubao-seed-2-0-lite + 关思考;\n K12 / 考试场景需要\"多题型联动 + 升级建议\"时用 doubao-seed-2-0-pro + 开思考;\n 移动端实时口语对话用 doubao-seed-2-0-mini 控制成本与时延。\n \n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
模型推荐版本base_urlFunction Calling适合场景
DeepSeek V3deepseek-chatapi.deepseek.com✓ 支持评测调用 + 诊断,性价比最高
DeepSeek R1deepseek-reasonerapi.deepseek.com✗ 不支持深度分析(需先用 V3 调工具)
GLM-4-Flashglm-4-flashopen.bigmodel.cn/…/v4✓ 支持开发测试(免费额度)
GLM-4-Plusglm-4-plusopen.bigmodel.cn/…/v4✓ 支持生产诊断报告,指令遵循强
KIMI 8kmoonshot-v1-8kapi.moonshot.cn/v1✓ 支持单次评测 + 即时反馈
KIMI 128kmoonshot-v1-128kapi.moonshot.cn/v1✓ 支持多轮历史 + 学习进度报告
豆包 Seed 2.0 Prodoubao-seed-2-0-pro-260215ark.cn-beijing.volces.com/api/v3✓ 支持(含深度思考)多步评测编排 + 深度诊断 Agent
豆包 Seed 2.0 Litedoubao-seed-2-0-lite-260215ark.cn-beijing.volces.com/api/v3✓ 支持在线辅导 + 单轮诊断,性价比首选
豆包 Seed 2.0 Minidoubao-seed-2-0-mini-260215ark.cn-beijing.volces.com/api/v3✓ 支持移动端 / 边缘部署 / 低延迟实时反馈
\n
\n 所有模型均通过 OpenAI Python SDK(openai 包)调用,仅需替换 base_url 和 api_key,驰声 MCP 侧代码无需改动。\n
\n\n \n

大部分落地场景其实是:你已有一个业务后端(教育 SaaS / 培训系统 / 客服平台),只需要新增一个「语音评测」能力。推荐架构:

\n\n
\n
\n 前端录音 / 上传\n →\n 业务后端\n →\n MCP Client(常驻连接)\n →\n 驰声 MCP\n ↘\n LLM(诊断 / 出题)\n
\n
\n\n

FastAPI 示例(生产最小骨架)

\n {`from fastapi import FastAPI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\nfrom contextlib import asynccontextmanager\n\nmcp_session: ClientSession | None = None\n\n@asynccontextmanager\nasync def lifespan(app):\n global mcp_session\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as s:\n await s.initialize()\n mcp_session = s\n yield\n mcp_session = None\n\napp = FastAPI(lifespan=lifespan)\n\n@app.post(\"/api/evaluate\")\nasync def evaluate(audio_id: str, ref_text: str):\n # 直接选一个最合适的工具执行(不经 LLM,延迟最低)\n r = await mcp_session.call_tool(\"evaluate_english_sentence\",\n {\"audioId\": audio_id, \"sentence\": ref_text})\n return {\"result\": r.content[0].text}`}\n\n 关键优化:① MCP 连接在 lifespan 里做成长连接,不要每次请求都重连;② 对延迟敏感的场景可以「跳过 LLM 直接调 tool」,把 LLM 放到「生成诊断报告」那一步。\n
\n\n
\n

方案选型速查

\n
\n \n \n \n \n \n \n \n \n \n \n \n
场景推荐方案
AI 对话 / Copilot 类产品,LLM 供应商可能会换① 官方 MCP 客户端库
已有 LangChain / Mastra / Agents SDK 技术栈② Agent 框架 + adapter
火山方舟 / 千帆控制台直连,最小侵入③ chat.completions + tools
教育 SaaS / 培训 / 客服等业务后端集成④ 自研后端 Agent
\n
\n
\n
\n\n {/* ══════ 评测模式 ══════ */}\n \n\n \n

通过本地麦克风实时录音,音频以 WebSocket 流式推送到评测服务,无需生成中间文件。这是最灵活、延迟最低的评测方式,特别适合交互式口语练习场景。

\n 实时录音评测需要安装 SoX 并使用本地代理模式(Claude Desktop / Claude Code)。Cursor 等远程直连模式暂不支持实时录音。\n\n

需要按顺序调用三个工具:

\n\n
\n
\n

create_stream_session — 创建流式评测会话

\n \n

返回 session_id,后续步骤需使用。

\n
\n\n
\n

start_recording — 开始麦克风录音

\n \n

调用后自动启动麦克风,音频通过 WebSocket 实时推送到评测服务。

\n
\n\n
\n

stop_recording — 停止录音并获取结果

\n \n
\n
\n
\n\n \n
\n \n

用户:"请评测我的英文发音,文本是 Hello"

\n

AI 调用 create_stream_session(core_type="en.word.score", ref_text="Hello")

\n

→ 获得 session_id

\n
\n \n

AI 调用 start_recording(session_id=xxx)

\n

麦克风开始录音,音频通过 WebSocket 实时推送到评测服务

\n
\n \n

用户说完后告知 AI "结束"

\n

AI 调用 stop_recording(session_id=xxx)

\n

→ 返回评测结果(总分、准确度、流利度、音素得分等)

\n
\n
\n
\n\n \n

适用于已有音频文件的评测场景,支持三种输入方式:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
参数说明适用场景
audio_file_path本地文件路径代理自动读取并转为 Base64,最便捷
audio_base64Base64 编码数据已有编码数据时使用
audio_url音频文件 URL音频托管在云存储时使用
\n
\n 推荐使用 audio_file_path,只需传入本地文件路径,代理会自动处理编码和上传。\n

支持的音频格式:mp3, wav, ogg, m4a, aac, pcm

\n

限制:单文件最大 50MB,大于 500KB 的文件自动压缩为 16kHz / 单声道 / 32kbps。

\n
\n
\n\n {/* ══════ API 参考 ══════ */}\n \n\n \n \n\n

通用参数:所有英文评测工具均支持以下参数。

\n \n
\n\n \n \n\n

通用参数:

\n \n
\n\n \n

所有评测工具返回统一的结构化结果:

\n {`{\n \"overall\": 85,\n \"accuracy\": 82,\n \"pron\": 88,\n \"fluency\": {\n \"overall\": 78,\n \"speed\": 65,\n \"pause\": 2\n },\n \"integrity\": 95,\n \"details\": [\n {\n \"char\": \"hello\",\n \"score\": 85,\n \"phone\": [\n { \"phoneme\": \"h\", \"score\": 90 },\n { \"phoneme\": \"ɛ\", \"score\": 82 },\n { \"phoneme\": \"l\", \"score\": 88 },\n { \"phoneme\": \"oʊ\", \"score\": 80 }\n ]\n }\n ]\n}`}\n
\n \n \n \n \n \n \n \n {[\n ['overall', '0–100', '综合总分,反映整体语音质量'],\n ['accuracy', '0–100', '准确度,音素级别的发音准确率'],\n ['pron', '0–100', '发音得分,整体发音质量评价'],\n ['fluency.overall', '0–100', '流利度,语流的自然度与平滑度'],\n ['fluency.speed', '0–100', '语速得分,每分钟词/音节计量'],\n ['fluency.pause', 'number', '不自然停顿次数'],\n ['integrity', '0–100', '完整度,是否完整朗读了参考文本'],\n ['details[].phone[]', 'array', '每个音素的独立评分,可定位具体弱项'],\n ['details[].stress[]', 'array', '重音得分,检测重弱读是否正确'],\n ].map(([field, range, desc]) => (\n \n \n \n \n \n ))}\n \n
字段范围说明
{field}{range}{desc}
\n
\n
\n\n \n
\n \n \n \n \n \n \n \n {[\n ['音频 ID 无效或已过期', '音频上传后 5 分钟内有效,评测完成后自动删除', '重新上传音频'],\n ['服务器繁忙', '当前请求过多,排队已满', '稍后重试,使用指数退避策略'],\n ['存储空间已满', '服务器临时音频存储已满', '稍后重试,系统会自动清理'],\n ['音频格式不支持', '上传了不支持的文件类型', '使用 mp3/wav/ogg/m4a/aac/pcm'],\n ['音频时长超限', '超过该题型最大时长限制', '裁剪音频后重试'],\n ['WebSocket 连接断开', '网络不稳定导致流式连接中断', '代理会自动重连,如持续失败请检查网络'],\n ].map(([scene, reason, fix]) => (\n \n \n \n \n \n ))}\n \n
场景原因解决方式
{scene}{reason}{fix}
\n
\n
\n
\n\n {/* ══════ 最佳实践 ══════ */}\n \n\n \n

\n 下面这些模板与{' '}\n 免费体验{' '}\n Demo 中实际使用的「教练 Prompt」一脉相承,全部围绕 角色 / 任务 / 方法 / 输出格式 / 语气 五段式结构,并使用占位符{' '}\n {'{mcp_response}'} 直接拼接 MCP 工具返回的 JSON。\n 推荐在 system 消息里挂载,再把工具返回原文塞进\n user 消息,由 LLM 基于真实分数和音素生成可读诊断 / 练习材料。\n

\n\n \n 使用建议:\n
    \n
  • 把 MCP 工具调用的完整 JSON(含 overall / dp_type / phonemes 等字段)原样塞入 {'{mcp_response}'},不要预先做汇总——细节越完整诊断越具体。
  • \n
  • 「诊断」类模板让 LLM 输出 Markdown 给最终用户阅读;「练习」类模板要求 LLM 输出严格 JSON 给前端渲染。两步分开调用,效果远好于一次性混合。
  • \n
  • 题型决定 prompt:单词题用音素级、句子题加韵律、段落题加 chunk / 整体性,半开放题套四维评级。下面按这 6 类分别给出。
  • \n
\n
\n\n {/* ─── A. 诊断类 · 输出 Markdown 给学习者阅读 ─── */}\n

\n A. 二次诊断 · 输出 Markdown\n

\n
\n
\n

\n 1. 单词级 · 音素诊断\n

\n

\n 适用工具:en.word.score / cn.word.raw。围绕 phonemes[].dp_type 找出错读音。\n

\n {`你是一位专业的英语发音教练。下面是驰声 MCP(en.word.score)返回的单词级评测数据:\n一个目标词、总分与发音分、以及带有 dp_type 的音素数组。\n\n## 任务\n为学习者写一份 **可直接阅读** 的发音诊断,每一条都要引用音素分数(写出 IPA 符号)。\n\n## 方法\n- 按 dp_type 分组:先看 mispron,再补充 normal 但分数 < 70 的\"边缘音\"。\n- 每个问题音素:① 典型母语干扰 → ② 你听到的声音 → ③ 一条具体的发音修正动作(下颌 / 舌位 / 气流 / 唇形)。\n- 重音符号 ˈ 标记的音节,重音错位也要单独列出(即便音素本身分数尚可)。\n- 最多列 4 条,按 **影响力从弱到强** 排序。\n\n## 输出\n精简 Markdown:可选一句总结 → 编号列表 → 单行 **🎯 优先级** 排序。\n\n## 语气\n友善、具体、可执行,不要空喊\"加油\"。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 2. 句子级 · 节奏 + 重音诊断\n

\n

\n 适用工具:en.sent.score。开头先给一行\"计分牌\",再从 phones → words → prosody。\n

\n {`你是一位专业的英语口语教练。下面是驰声 MCP(en.sent.score)返回的句子级数据:refText、总分、发音子分(accuracy / integrity / fluency / rhythm)、可选 speed(WPM),以及 details[] 中的逐词得分、dp_type 与可选 phonemes[]。\n\n## 任务\n开头给一行紧凑的 **计分牌**(总分 + 各子分 + 速度),再按 **音素 → 词 → 韵律** 顺序展开诊断。\n\n## 检查清单(每项都要覆盖;不适用则写\"无明显问题\")\n1. **音素级**:每个 score < 70 或 dp_type ≠ normal 的词,展开 phonemes,命名典型错误(如 /ð/ → /d/)并给一条修正动作。\n2. **漏读 / 多读**:标注 dp_type=omit / insert,解释如何拉低 integrity。\n3. **韵律**:基于 rhythm + 错读词的重音,指出重音错位、陈述句调型平直、断句过多等。\n4. **流利度 vs 准确度**:若 fluency 高但 accuracy 低,明确指出,让学习者知道优先改哪一项。\n\n## 输出格式\nMarkdown 子标题:**Pronunciation / Prosody / Study priority**(最后一行简短排序,按 ROI 从高到低)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 3. 段落级 · 音素族归并 + 完整度\n

\n

\n 适用工具:en.pred.score。把同类错音合并为\"音素族\",避免逐词复述。\n

\n {`你是一位专业的英语口语教练。下面是驰声 MCP(en.pred.score)返回的段落级数据:长 refText、总分、发音子分、可选 speed / integrity,以及大量 details[](同一个词可能在不同子句中重复出现;空 char + dp_type=omit 表示漏读)。\n\n## 任务\n对整段做 **整体诊断**:\n(a) 完整度 / 漏读,\n(b) 反复出现的 **音素族**,\n(c) 节奏与断句,\n(d) 各子分之间是否相互印证。\n\n## 检查清单\n1. **integrity / dp_type**:列出每个 omit / insert,并给出所在子句;解释长读时为什么虚词容易被吞。\n2. **音素聚类**:将弱词按共同音素问题归族(/θ/ 链、/e/ 链、/ɒ/ 等),引用 details 中的实例。\n3. **韵律**:结合 rhythm 与标点 —— 短语内停顿过多?子句边界缺失?\n4. **整体一致性**:若 fluency 正常但 accuracy 差(或反之),点明并指出对练习设计的影响。\n\n## 输出格式\nMarkdown 章节:**Summary / Completeness / Pronunciation (families) / Rhythm / Study priorities**(最后一项最多 4 条,按影响力排序)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 4. 半开放题 · IELTS 风格四维评级\n

\n

\n 适用工具:en.pqan.score。结合学习者 transcript + 四维分数,给出可教学的\"升档建议\"。\n

\n {`你是一位 **IELTS / 课堂口语风格** 的口语教练。下面是驰声 MCP(en.pqan.score)返回的半开放题数据:题目 refText、学习者 transcript、overall、四个维度分(grammar / content / fluency / pron)、speed(WPM)、以及结构化的 issues[] 标记。\n\n## 任务\n给出 **基于 rubric 的诊断**:先用一句话给出 0–100 的整体段位估计,再 **逐维度** 解释,并 **引用 transcript 中的短句**(不要复述全文)。最后给 3–5 条 **可执行的\"升档建议\"**(句型 / 模板,而不是\"多练一点\")。\n\n## 权重(要明确告诉学习者)\n- **Content ~30%** — 想法深度、举例、具体程度\n- **Grammar ~25%** — 句型多样性、主谓一致、从句\n- **Fluency ~25%** — 语速、停顿、口头禅、衔接\n- **Pronunciation ~20%** — 音素 + 可懂度\n\n## 跨维度检查\n- 若 content 最低,先给\"展开模板\",不要先抠音素。\n- 若 fluency 低 + WPM 低,区分\"思考型停顿\"与\"发音卡顿\"。\n- 若 pron 标出特定音,绑定到 transcript 里 **真实出现过的词**。\n\n## 输出格式\nMarkdown:**段位估计** → 紧凑的 **得分表格** → **\"To reach the next band\"** 编号列表(每条给出可仿写的句型)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 5. 中文专项 · 声调 / 儿化 / 变调\n

\n

\n 适用工具:cn.word.raw / cn.sent.raw / cn.pred.raw。中文评测最大权重在 **声调**,必须单独检查。\n

\n {`你是一位专业的普通话口语教练。下面是驰声 MCP(cn.sent.raw)返回的中文句子评测数据:整句分数 + 逐字 details + 可选 phonemes + 流利 / 节奏分。\n\n## 中文评测的权重\n- **声调错误权重最高** —— 声调读错可能直接改变词义\n- dp_type=mispron 多来自:声调错、平翘舌混用、前后鼻音混用\n- 拼音对、声调错,听感仍是\"洋腔洋调\"\n\n## 检查清单(缺则写\"无明显问题\")\n1. **儿化**:phonemes 出现 r(儿化) 或 dp_type 提示时,确认是否被读成\"主音节 + 单独儿\"两拍。\n2. **轻声**:叠词、词缀、句末语气词 —— 第二字应短促轻读,无完整声调曲线。\n3. **变调**:三声连读、不 + 后字、一 + 后字,是否符合普通话规则。\n4. **节奏**:用 rhythm + 逗号位置,标记停顿过长或过碎,建议 chunk 边界。\n\n## 输出\nMarkdown 子标题:**总览 / 儿化 / 轻声 / 变调 / 节奏 / 学习优先级**(最后一项 1–3 条,按\"听感自然度提升\"排序)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n {/* ─── B. 练习类 · 输出 JSON 给前端渲染 ─── */}\n

\n B. 微练习生成 · 输出严格 JSON\n

\n
\n
\n

\n 6. 单词 / 句子 · 微练习\n

\n

\n 建议在 诊断完成后 第二轮调用:让 LLM 严格按弱项音素生成,避免\"通用绕口令包\"。\n

\n {`你仍是这位学习者的发音教练。**第二轮诊断已经完成** —— 现在严格基于诊断里点名的弱音素,生成 **1:1 对应** 的微练习(不要给通用题)。\n\n## 输出(仅返回一段合法 JSON 数组,外层不要任何文字)\n根节点必须是数组,每个元素含 category(字符串)、icon(单个 emoji)、items({ \"label\", \"content\" } 数组)。\n\\`\\`\\`json\n[\n { \"category\": \"Phoneme drills\", \"icon\": \"🎯\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Awareness\", \"icon\": \"🗣️\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Whole word\", \"icon\": \"📝\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] }\n]\n\\`\\`\\`\n\n## 规则\n- **Phoneme drills**:诊断里每个 mispron 音素至少给一对最小对立对 + 一句短绕口令 / 重复句。\n- **Awareness**:当重音偏弱时,给一条 stress / 舌位 / 下颌姿态提示。\n- **Whole word**:2–3 句自然句,目标词分别出现在句首 / 句中 / 句末。\n- 所有 content 必须可念出声;字符串内不要再嵌套 JSON。\n\n## 上下文\n诊断结论:{previous_diagnosis}\n原始 MCP:\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 7. 段落 · Chunk Map + 元认知\n

\n

\n 段落级练习要从\"音素\"上升到\"短语 / 整段 / 元认知录回放\"。直接对应 en.pred.score 的诊断结果。\n

\n {`你仍是这位学习者的口语教练。**段落级二次诊断** 已经列出了漏读位置和音素族 —— 现在请生成 **整段练习**:把弱音素串成\"族\"练习、用 chunk map 把虚词粘回短语,并附一条录音 → 回放 → 对照 MCP details 的元认知步骤。\n\n## 输出(仅返回一段合法 JSON 数组)\n\\`\\`\\`json\n[\n { \"category\": \"Phoneme families\", \"icon\": \"🎯\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Chunking\", \"icon\": \"🎵\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Metacognition\", \"icon\": \"🧠\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] }\n]\n\\`\\`\\`\n\n## 规则\n- **Phoneme families**:至少 3 条,按诊断里的音素族(/θ/、/e/、/ɒ/ 等)组织最小对立对 / 词链。\n- **Chunking**:① 给一行用 [ ] 和 / 标注的 chunk map(可加大致停顿秒数);② 给一句\"把漏掉的虚词嵌入短语\"的练习(不要孤立练)。\n- **Metacognition**:一条\"录音 → 回放 → 对照 MCP details\"的 N 遍练习(N 写明,2–3 之间)。\n- 字符串只能是纯展示文本,禁止嵌套 JSON。\n\n## 上下文\n诊断结论:{previous_diagnosis}\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n {/* ─── C. 跨题 / 运营 ─── */}\n

\n C. 跨题 / 运营\n

\n
\n
\n

\n 8. 多日学习报告\n

\n

\n 把过去 N 天的 MCP 评测结果聚合后丢给 LLM,输出适合发给学生 / 家长的周报。\n

\n {`你是一位英语口语学习顾问。下面是这位学习者过去 7 天的驰声 MCP 评测历史(按时间顺序),每条包含题型、coreType、overall、子分、weak_phonemes 摘要。\n\n## 任务\n为学习者生成一份 **周报**,目标读者:本人 + 家长 / 老师。\n强调 **趋势** 与 **下一步计划**,不要复述每一次具体分数。\n\n## 必须包含\n1. **整体趋势**:进步 / 持平 / 退步(一句话 + 简短依据)\n2. **维度变化**:accuracy / fluency / rhythm / integrity / speed 任意有数据的维度,给出\"本周均分 vs 上周\"\n3. **本周高光**:分数提升最大的题型 / 音素 / 句型\n4. **顽固问题**:连续 3 次以上未达 70 的音素或维度\n5. **下周计划**:3 条具体动作(每条对应一个 MCP 工具或一个练习类型)\n6. **结尾**:1–2 句鼓励性总结,避免空话\n\n## 风格\n- 像一位认真但不啰嗦的私教\n- 出现学生姓名时使用占位 {student_name}\n- 数字一律保留整数\n\n## 评测历史\n\\`\\`\\`json\n{history}\n\\`\\`\\``}\n
\n\n
\n

\n 9. 错误归因 · JSON 摘要\n

\n

\n 用于后端聚合 / 数据看板:让 LLM 把一次评测压缩成结构化摘要,方便入库统计。\n

\n {`你是一个评测结果归类器。下面是驰声 MCP 一次评测的完整返回。请抽取关键信息并 **仅返回合法 JSON**(不要任何解释文字)。\n\n## Schema\n\\`\\`\\`json\n{\n \"core_type\": \"string,例如 en.sent.score\",\n \"overall\": 0,\n \"sub_scores\": { \"accuracy\": 0, \"integrity\": 0, \"fluency\": 0, \"rhythm\": 0 },\n \"weak_phonemes\": [\n { \"ipa\": \"string\", \"avg_score\": 0, \"occur\": 0, \"example_word\": \"string\" }\n ],\n \"omissions\": [{ \"after\": \"string\", \"missing\": \"string\" }],\n \"stress_issues\": [{ \"word\": \"string\", \"expected\": \"string\", \"actual\": \"string\" }],\n \"primary_issue_tag\": \"phoneme|stress|fluency|integrity|content|none\",\n \"next_action_hint\": \"string,10 字以内,例如 \\\"练 /θ/ 对立对\\\"\"\n}\n\\`\\`\\`\n\n## 规则\n- weak_phonemes 只收 avg_score < 70 的项,最多 5 项,按 occur 降序。\n- 不要复述 refText,不要 markdown。\n- 字段缺失时使用 null 或空数组,不要省略 key。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n \n 怎么接到 MCP 工具调用?\n
\n 以「直调 chat.completions + 动态 tools」为例:第一轮 LLM 调出 en.sent.score 工具,把工具 result(即 tool 消息内容)原样填入上面任意「诊断」模板的{' '}\n {'{mcp_response}'},作为第二轮 user 消息发回;拿到诊断结论再走第三轮,套「微练习」模板得到 JSON。三轮调用即可串起 评测 → 诊断 → 练习 全链路。\n
\n
\n\n \n
    \n
  • 音频过期:上传后 5 分钟内有效。建议在上传后 3 分钟内完成评测。
  • \n
  • 服务繁忙:使用指数退避策略重试(1s → 2s → 4s),最多 3 次。
  • \n
  • 录音中断:WebSocket 断线后代理会自动重连。如持续失败,检查网络连接和 SoX 安装。
  • \n
\n
\n\n \n
    \n
  • 优先使用流式评测:实时录音模式跳过了文件上传环节,端到端延迟比文件评测低 30-50%。
  • \n
  • 音频压缩:文件评测时,上传前将音频转为 16kHz 单声道 mp3,可减少 60-80% 的上传体积。
  • \n
  • 选择合适的工具:单词评测比段落评测快 3-5 倍。如只需单词级分数,不要用句子评测。
  • \n
  • 本地文件路径最便捷:使用 audio_file_path 参数传入本地路径,代理自动处理编码,无需手动转 Base64。
  • \n
\n
\n
\n\n {/* ══════ 服务信息 ══════ */}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n
端点方法说明
/uploadPOST音频文件上传
/mcpPOSTMCP JSON-RPC 接口(Streamable HTTP)
/healthGET健康检查
\n
\n
\n \n
\n \n \n \n \n \n \n \n {[\n ['存储限制', '500MB', '最大音频存储空间'],\n ['最大排队', '10', '等待处理的请求数'],\n ['最大并发', '3', '同时处理的评测数'],\n ['音频有效期', '5 分钟', '上传后未评测自动过期'],\n ['文件大小限制', '50MB', '单个音频文件最大'],\n ].map(([k, v, d]) => (\n \n ))}\n \n
配置项默认值说明
{k}{v}{d}
\n
\n

\n 上表为托管侧技术默认;计费与试用/商用调用配额、并发档位以{' '}\n \n 会员套餐\n \n 说明为准,与上表独立。\n

\n
\n \n \n 当前线上版本:v1.0.0(网站未正式上线)。以下变更项为开发阶段规划记录,以正式发布公告为准。\n \n
\n {[\n { ver: 'v1.0.0', date: 'TBD', desc: '当前线上版本(网站未正式上线)' },\n ].map(l => (\n
\n {l.ver}\n {l.date}\n {l.desc}\n
\n ))}\n
\n
\n
\n\n \n );\n}\n\nexport default function DocsPage() {\n const locale = useLocale();\n return locale.startsWith('zh') ? : ;\n}\n"}, "f6779e85462691f3c58b16e2b4652c6092bac434": {"t": 1785765798.5010319, "n": 114093, "h": "70f80afe4a363010", "c": "'use client';\n\nimport { useLocale } from 'next-intl';\nimport { Link } from '@/i18n/routing';\nimport { DocsShell, type NavGroup } from './docs-shell';\nimport {\n CodeBlock,\n DocSection,\n SubDoc,\n ParamTable,\n Callout,\n FlowStep,\n ToolTable,\n} from './docs-shared';\nimport { DocsEnglishBody } from './docs-content-en';\nimport {\n BookOpen,\n Code2,\n Zap,\n FileText,\n Terminal,\n Globe,\n Mic,\n MessageSquare,\n BarChart3,\n AlertTriangle,\n Radio,\n FolderOpen,\n Workflow,\n Sparkles,\n Plug,\n Bot,\n Building2,\n Check,\n Sparkle,\n Languages,\n GraduationCap,\n Notebook,\n Gauge,\n ListChecks,\n} from 'lucide-react';\n\n/* ─── Navigation Structure ─── */\n\nconst NAV = [\n { id: 'concept', icon: Workflow, label: 'MCP 工作原理', children: [\n { id: 'why-mcp', label: '为什么需要 MCP' },\n { id: 'scenario-walkthrough', label: '场景走查 · 6 步' },\n { id: 'dev-responsibility', label: '开发者只做两件事' },\n { id: 'integration-paths', label: '三种接入姿势' },\n ]},\n { id: 'architecture', icon: Terminal, label: '架构说明', children: [\n { id: 'arch-diagram', label: '架构图' },\n { id: 'transport', label: '传输协议' },\n ]},\n { id: 'quick-start', icon: Zap, label: '快速开始', children: [\n { id: 'overview', label: '概述' },\n { id: 'requirements', label: '系统要求' },\n { id: 'install', label: '安装方式' },\n { id: 'env-vars', label: '环境变量' },\n ]},\n { id: 'config', icon: Plug, label: '接入 · 直接用(零代码)', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: '扣子(Coze)' },\n { id: 'config-coze-workflow', label: 'Coze 工作流' },\n { id: 'config-ai-workspace', label: 'AI 工作台 · 豆包 / 飞书 / WorkBuddy / 钉钉' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: '其他 MCP 客户端' },\n ]},\n { id: 'config-code', icon: Code2, label: '接入 · 编程用(SDK / 代码)', children: [\n { id: 'code-mcp-sdk', label: '官方 MCP 客户端库' },\n { id: 'code-agent-frameworks', label: 'LangChain / Mastra / Agents SDK' },\n { id: 'code-function-calling', label: '直调 chat.completions · 上传与动态 tools' },\n { id: 'llm-deepseek', label: 'DeepSeek' },\n { id: 'llm-glm', label: 'GLM(智谱)' },\n { id: 'llm-kimi', label: 'KIMI(Moonshot)' },\n { id: 'llm-comparison', label: '模型对比速查' },\n { id: 'code-selfhosted-agent', label: '自研后端 Agent' },\n ]},\n { id: 'eval-modes', icon: Radio, label: '评测模式', children: [\n { id: 'stream-eval', label: '实时录音评测' },\n { id: 'stream-flow', label: '流式评测流程' },\n { id: 'file-eval', label: '音频文件评测' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API 参考', children: [\n { id: 'tools-en', label: '英文评测工具' },\n { id: 'tools-cn', label: '中文评测工具' },\n { id: 'result-fields', label: '评测结果字段' },\n { id: 'error-codes', label: '错误码' },\n ]},\n { id: 'best-practices', icon: FileText, label: '最佳实践', children: [\n { id: 'prompt-templates', label: 'Prompt 模板' },\n { id: 'error-handling', label: '错误处理' },\n { id: 'performance', label: '性能优化' },\n ]},\n { id: 'service-info', icon: Globe, label: '服务信息', children: [\n { id: 'endpoints', label: '服务端点' },\n { id: 'limits', label: '服务限制' },\n { id: 'changelog', label: '更新日志' },\n ]},\n];\n\nconst NAV_EN: NavGroup[] = [\n { id: 'concept', icon: Workflow, label: 'How MCP works', children: [\n { id: 'why-mcp', label: 'Why MCP' },\n { id: 'scenario-walkthrough', label: 'Scenario · 6 steps' },\n { id: 'dev-responsibility', label: 'Two developer tasks' },\n { id: 'integration-paths', label: 'Three integration styles' },\n ]},\n { id: 'architecture', icon: Terminal, label: 'Architecture', children: [\n { id: 'arch-diagram', label: 'Diagram' },\n { id: 'transport', label: 'Transports' },\n ]},\n { id: 'quick-start', icon: Zap, label: 'Quick start', children: [\n { id: 'overview', label: 'Overview' },\n { id: 'requirements', label: 'Requirements' },\n { id: 'install', label: 'Install' },\n { id: 'env-vars', label: 'Environment' },\n ]},\n { id: 'config', icon: Plug, label: 'Zero-code clients', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: 'Coze' },\n { id: 'config-coze-workflow', label: 'Coze workflows' },\n { id: 'config-ai-workspace', label: 'Enterprise AI workspaces' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: 'Other MCP clients' },\n ]},\n { id: 'config-code', icon: Code2, label: 'SDK / code integration', children: [\n { id: 'code-mcp-sdk', label: 'Official MCP SDK' },\n { id: 'code-agent-frameworks', label: 'Agent frameworks' },\n { id: 'code-function-calling', label: 'chat.completions · upload & tools' },\n { id: 'llm-deepseek', label: 'DeepSeek' },\n { id: 'llm-glm', label: 'GLM (Zhipu)' },\n { id: 'llm-kimi', label: 'KIMI (Moonshot)' },\n { id: 'llm-comparison', label: 'Model comparison' },\n { id: 'code-selfhosted-agent', label: 'Custom backend' },\n ]},\n { id: 'eval-modes', icon: Radio, label: 'Evaluation modes', children: [\n { id: 'stream-eval', label: 'Streaming mic' },\n { id: 'stream-flow', label: 'Streaming flow' },\n { id: 'file-eval', label: 'Audio files' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API reference', children: [\n { id: 'tools-en', label: 'English tools' },\n { id: 'tools-cn', label: 'Chinese tools' },\n { id: 'result-fields', label: 'Result fields' },\n { id: 'error-codes', label: 'Errors' },\n ]},\n { id: 'best-practices', icon: FileText, label: 'Best practices', children: [\n { id: 'prompt-templates', label: 'Prompt templates' },\n { id: 'error-handling', label: 'Errors & retries' },\n { id: 'performance', label: 'Performance' },\n ]},\n { id: 'service-info', icon: Globe, label: 'Service info', children: [\n { id: 'endpoints', label: 'Endpoints' },\n { id: 'limits', label: 'Limits' },\n { id: 'changelog', label: 'Changelog' },\n ]},\n];\n\n/* ─── Page(英文 / 中文拆成两个组件,避免切换语言时 Hooks 数量变化导致白屏)─── */\n\nfunction DocsPageEn() {\n return (\n \n \n \n );\n}\n\nfunction DocsPageZh() {\n return (\n \n {/* ══════ MCP 工作原理 ══════ */}\n \n\n \n

\n 大模型(GPT / Claude / Gemini / 通义千问 等)本质上是文字大脑:它擅长读和写,但天生听不到音频、打不开你的数据库、调不通第三方 API。\n

\n

\n MCP(Model Context Protocol)是一套由 Anthropic 主导、业界共同推进的开放协议,它像一根\"对讲机\":让大模型可以在需要时主动去调用外部能力(工具、数据源、服务),然后把结果接回来继续对话。\n

\n
\n
\n
\n \n 没有 MCP 的做法\n
\n
    \n
  • · 研究评测服务的 REST 文档
  • \n
  • · 自己写鉴权 / 上传 / 轮询代码
  • \n
  • · 把结果序列化后塞进 prompt
  • \n
  • · 每换一个大模型都得重写一遍
  • \n
\n
\n
\n
\n \n 用驰声 MCP 之后\n
\n
    \n
  • · 填一行 MCP Server 地址
  • \n
  • · 大模型自动发现&调用评测工具
  • \n
  • · 换任何支持 MCP 的大模型都能用
  • \n
  • · 不写一行调用代码
  • \n
\n
\n
\n \n MCP 让\"接入语音评测\"从一个\"后端工程\"变成了一个\"配置项\"。这也是为什么 Cursor、Claude Desktop、Dify、Coze、字节豆包、飞书智能助手都已经原生支持 MCP。\n \n
\n\n \n

\n 想象一个具体场景:一位开发者用 Claude 做了一款 「AI 雅思口语陪练」小程序,接入驰声语音评测 MCP。当用户发来一段录音,整个链路是这样的:\n

\n
\n \n

配置阶段(开发者 · 一次性)

\n

在 AI 后端的配置文件里填一行驰声 MCP Server 地址。大模型启动时自动发现:「我多了一个叫语音评测的工具」。

\n
\n \n

接收用户指令(终端用户)

\n

小程序用户发来一段自我介绍录音:「帮我听听,发音哪里有问题?」后端把「文字 + 录音链接」打包给大模型。

\n
\n \n

大模型自主思考(LLM · 最核心的魔法)

\n
\n 「用户让我听发音。」
\n 「但我只是文字大脑,我听不到。」
\n 「等等 —— 开发者给了我一个叫 chivox_voice_eval 的 MCP 工具!」\n
\n
\n \n

MCP 协议 · 自动调用(LLM → 驰声)

\n

大模型自动按 MCP 标准构造 tools/call 请求,把录音链接和参考文本发到驰声服务。开发者不需要写任何调用代码。

\n
\n \n

驰声服务处理(评测引擎)

\n

驰声对音频进行考试级打分,把结构化结果通过 MCP 原路返回:overall 85、/θ/ 音发音错误、流利度 88。

\n
\n \n

大模型整合并输出反馈(LLM)

\n

大模型把冷冰冰的分数翻译成温柔反馈:

\n
\n 「你的自我介绍很棒!综合 85 分 🎉 不过 think 这个词的 /θ/ 咬舌音不太标准,我们一起来练一下……」\n
\n
\n
\n \n 整条链路里,MCP 只出现在 ① 和 ④:① 让开发者一次性告诉大模型「你多了一个工具」,④ 让大模型可以自动调用它。这两步的标准化,就是 MCP 的全部价值。\n \n
\n\n \n

听起来复杂,但对开发者来说只需要两件事:

\n
\n
\n
\n 1\n 填一次 MCP 配置\n
\n

\n 在 AI 后端的配置里填入驰声 MCP Server 地址和 API Key,就这一次,以后新加评测能力完全免开发。\n

\n {`{\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"apiKey\": \"sk-••••••••••\"\n }\n}`}\n
\n
\n
\n 2\n 写一段 System Prompt\n
\n

\n 告诉大模型这个工具是做什么的、什么时候调用、结果怎么转成用户友好的反馈。\n

\n {`你是一位英语口语教练。\n当用户发来录音时:\n1. 调用 chivox_voice_eval 评分\n2. 聚焦 <70 分的音素家族\n3. 用高情商话术给出练习建议`}\n
\n
\n

\n 其余所有事情 —— 音频上传、鉴权、工具发现、调用时机、返回格式、结果整合 —— 都由 MCP 协议和大模型自己搞定。\n

\n
\n\n \n

根据你的技术栈,有三种等价的接入方式,底层都走完全相同的 MCP 协议:

\n\n {/* ── 姿势一:可视化 ── */}\n
\n
\n \n

姿势一 · 可视化拖拽(扣子 / Coze / 飞书智能助手)

\n
\n

\n 适合产品经理、运营、不写后端代码的开发者。整个过程像在手机上装 App。\n

\n
    \n
  1. 找到入口:在扣子平台的 「插件 / 工具」 配置区,点击「添加 MCP 服务」。
  2. \n
  3. 填两个字段(这也是你未来会从驰声这边拿到的):\n
    \n \n \n \n \n \n
    服务器地址https://speech-eval.site/mcp
    鉴权密钥sk-•••••••••• (由驰声分配,用于计费与识别)
    \n
    \n
  4. \n
  5. 平台自动发现能力:扣子会访问你填的地址,读取 MCP Server 自描述的\"说明书\"。瞬间明白:「这是个语音评测工具,需要传音频,会返发音分」。
  6. \n
  7. 右侧测试:在平台的聊天框里发一段语音,大模型就会自动调用工具。整个过程不需要写一行代码。
  8. \n
\n
\n\n {/* ── 姿势二:代码框架 ── */}\n
\n
\n \n

姿势二 · 代码框架配置(Dify / LangChain / 自研后端)

\n
\n

\n 适合做独立 APP / 小程序、用 Dify 或 LangChain 写 Agent 的极客开发者。核心就是往配置文件里加一段 JSON。\n

\n
    \n
  1. 打开配置文件(项目根目录下的 mcp.json 或框架指定的配置路径)。
  2. \n
  3. 在 mcpServers 下增加一个节点:\n {`{\n \"mcpServers\": {\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"env\": {\n \"API_KEY\": \"你的专属密钥\"\n }\n }\n }\n}`}\n
  4. \n
  5. 重启后端服务。大模型的底层调度器会在启动时自动连上驰声 MCP Server,把 16 种评测工具注册成随时待命的 tools。
  6. \n
  7. 触发调用:用户发来录音后,大模型看到 system prompt 的引导,自动选择合适的工具(单词/句子/段落/半开放)调用。
  8. \n
\n
\n\n {/* ── 姿势三:Function Calling 直连(分 A / B 两种做法) ── */}\n
\n
\n \n

姿势三 · 原生 Function Calling(豆包 / DeepSeek / OpenAI 兼容 API)

\n
\n

\n 适合不用任何 Agent 框架、直接调用 LLM API 的后端开发者。豆包 1.5+ / DeepSeek / GPT / Qwen 等模型都走标准 chat.completions 的 tools 参数。这里又分 A / B 两种做法,B 才是生产推荐。\n

\n\n \n 常见疑问:\"要不要手写一个 tool 定义?\"
\n — 姿势一 / 二不用(Coze、Dify、火山方舟控制台、Claude Desktop 会自动从 MCP Server 拉工具列表)。
\n — 姿势三看你选 A 还是 B:A 要手写,B 用 MCP 客户端库自动拉。\n
\n\n {/* ── 3-A:手写 tool schema ── */}\n
\n
\n

3-A · 手写 tool schema(最快验证,不推荐生产)

\n 快速 Demo\n
\n

\n 自己写一段 JSON Schema 告诉豆包\"有个工具叫 xxx,参数长这样\",豆包返回 tool_call 后你再手动去调驰声 MCP。缺点:驰声有 16 个评测工具,你每加一个题型都要改代码。\n

\n {`import os, json\nfrom openai import OpenAI\n\nclient = OpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv('ARK_API_KEY'),\n)\n\n# ─── 手写一段 tool schema(不推荐:16 个工具就要写 16 段)───\ntools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": \"en_word_eval\",\n \"description\": \"英语单词发音评测。当用户让你评价英语发音并提供录音链接时调用。\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"audio_url\": {\"type\": \"string\", \"description\": \"录音 URL\"},\n \"reference_text\": {\"type\": \"string\", \"description\": \"参考文本,如 Apple\"},\n },\n \"required\": [\"audio_url\", \"reference_text\"]\n }\n }\n}]\n\nresp = client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,拿到评测结果后温柔地反馈,不要直接报分数。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n)\n\nmsg = resp.choices[0].message\nif msg.tool_calls:\n args = json.loads(msg.tool_calls[0].function.arguments)\n # ↓↓↓ 这里手动调驰声 MCP,再把结果回填给豆包做第二趟 ↓↓↓\n # result = requests.post(\"https://speech-eval.site/mcp\", json={...})`}\n
\n\n {/* ── 3-B:MCP 自动发现 ── */}\n
\n
\n

\n 3-B · 用 MCP 客户端库自动发现 \n

\n 生产推荐\n
\n

\n 启动时连上驰声 MCP Server,调一次 tools/list,把 16 个评测工具自动转成 Function Calling 的 tools 格式。驰声加新工具,你代码不用改。这才是 MCP 协议的真正价值。\n

\n {`import asyncio, os\nfrom openai import AsyncOpenAI\nfrom mcp import ClientSession\nfrom mcp.client.streamable_http import streamablehttp_client\n\nclient = AsyncOpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv(\"ARK_API_KEY\"),\n)\n\nasync def main():\n # ─── 1. 连驰声 MCP Server,自动拉取全部 16 个工具 ───\n async with streamablehttp_client(\n \"https://speech-eval.site/mcp\",\n headers={\"Authorization\": f\"Bearer {os.getenv('CHIVOX_KEY')}\"},\n ) as (read, write, _):\n async with ClientSession(read, write) as session:\n await session.initialize()\n mcp_tools = (await session.list_tools()).tools # ← 一行拿到全部工具\n\n # ─── 2. MCP schema → OpenAI Function Calling schema ───\n tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema, # MCP 直接给 JSON Schema\n }\n } for t in mcp_tools]\n\n # ─── 3. 正常调豆包,tools 由 MCP 动态注入 ───\n resp = await client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,收到评测结果后温柔反馈。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n )\n\n # ─── 4. 折返跑:豆包选好工具后,直接走 MCP 调驰声 ───\n msg = resp.choices[0].message\n if msg.tool_calls:\n call = msg.tool_calls[0]\n result = await session.call_tool(\n call.function.name,\n arguments=__import__(\"json\").loads(call.function.arguments),\n )\n # 把 result 回填给豆包做第二趟 chat.completions 即可\n\nasyncio.run(main())`}\n

\n 想要更省心?直接用 官方 mcp python sdk、mcp-use、openai-agents,或火山官方 Arkitect 高代码 SDK,它们都把上面这段\"MCP → Function Calling\"的桥接封装好了。\n

\n
\n
\n\n \n 三种姿势走的是完全相同的 MCP 协议,能力完全等价。选型建议:产品经理 / 原型验证用姿势一(Coze 填表单);AI 客户端用户用姿势二(Cursor / Claude Desktop 填 mcp.json);后端生产服务用姿势三-B(MCP 客户端库自动发现工具,不要手写 tool schema)。\n \n
\n\n
\n\n {/* ══════ 架构说明 ══════ */}\n \n\n \n
\n
\n

AI 客户端

\n

Claude Desktop
Claude Code
Cursor

\n
\n
\n

⇄

\n

stdio

\n
\n
\n

chivox-local-mcp

\n

本地代理
SoX 录音

\n
\n
\n

⇄

\n

HTTP / WS

\n
\n
\n

Remote Chivox

\n

MCP Server
评测引擎

\n
\n
\n
\n\n \n
    \n
  • \n \n stdio — AI 客户端通过标准输入输出与本地代理通信,这是 MCP 的标准传输方式\n
  • \n
  • \n \n HTTP — 音频文件评测工具通过 HTTP 代理到远程服务,适用于非流式场景\n
  • \n
  • \n \n WebSocket — 实时录音音频通过 WebSocket 流式推送,支持断线自动重连\n
  • \n
\n
\n
\n\n {/* ══════ 快速开始 ══════ */}\n \n\n \n

chivox-local-mcp 是驰声语音评测的 MCP 本地代理,通过 Model Context Protocol 将远程驰声评测服务桥接到本地,让 AI 助手(Claude Desktop、Claude Code、Cursor 等)直接调用语音评测能力。

\n

它支持两种评测模式,覆盖从即时交互到批量处理的全部场景:

\n
\n
\n
\n \n 实时录音评测\n
\n

通过麦克风边录边评,音频以 WebSocket 流式推送,无需生成中间文件,延迟更低、体验更佳。

\n
\n
\n
\n \n 音频文件评测\n
\n

支持本地文件路径、Base64 编码、URL 三种输入,适合已有音频的批量评测场景。

\n
\n
\n 当前支持 16 种评测工具:英文 10 种(单词、句子、段落、纠音、自然拼读、口语选择、半开放题等)+ 中文 6 种(汉字、拼音、词句、段落、有限分支、AI Talk)。\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n
依赖版本说明
Node.js{'>'}= 18运行时必须
SoXany仅实时录音功能需要(处理麦克风音频流)
\n
\n

安装 SoX(仅在使用实时录音时需要):

\n {`# macOS\nbrew install sox\n\n# Ubuntu / Debian\nsudo apt-get install sox`}\n
\n\n \n

方式一:npm 全局安装(推荐)

\n {`npm install -g chivox-local-mcp`}\n\n

方式二:npx 免安装运行

\n {`MCP_REMOTE_URL=http://your-server:8080 npx chivox-local-mcp`}\n\n

方式三:从源码构建

\n {`git clone https://git.chivox.com/CLOUD_DEV/cvx_local_mcp.git\ncd cvx_local_mcp\nbash scripts/build.sh`}\n
\n\n \n \n \n
\n\n {/* ══════ 接入 · 直接用(零代码) ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 不用写代码、不用装 SDK,只在客户端的「MCP 配置」或「扩展」里填一段 JSON / URL
  • \n
  • 保存后 LLM 自动发现 16 个评测工具,并在对话 / Agent 中自主调用
  • \n
  • 覆盖 IDE 编程助手、桌面 AI 客户端、企业 AI 工作台、可视化 Bot / 工作流平台四大生态
  • \n
\n
\n\n\n \n
    \n
  1. 打开 Cursor 设置(Cmd + ,)
  2. \n
  3. 左侧选择 MCP(或搜索 "MCP")
  4. \n
  5. 点击 Add new MCP server
  6. \n
  7. 填写配置并保存:
  8. \n
\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n}`}\n Cursor 使用远程 Streamable HTTP 模式直连,无需安装本地代理。如需实时录音功能,请使用下方 Claude Desktop 的本地代理配置。\n
\n\n \n

编辑配置文件(macOS:~/Library/Application Support/Claude/claude_desktop_config.json):

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"chivox-local-mcp\",\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\",\n \"MCP_API_KEY\": \"your-api-key\"\n }\n }\n }\n}`}\n

如果是从源码构建:

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/cvx_local_mcp/dist/index.js\"],\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\"\n }\n }\n }\n}`}\n Claude Desktop 使用本地代理模式(stdio),支持实时录音评测。本地代理会自动桥接远程服务。\n
\n\n \n {`# npm 全局安装后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 chivox-local-mcp\n\n# 源码构建后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 node /path/to/cvx_local_mcp/dist/index.js`}\n \n\n \n

除了 Cursor 和 Claude Code,主流的 AI 编程 IDE 都原生支持 MCP。以下客户端使用完全一致的 Streamable HTTP 配置,区别只在配置入口:

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
客户端配置入口备注
Windsurf (Codeium)Settings → Cascade → MCP Servers直接贴下方 JSON
Zed~/.config/zed/settings.json 的 context_serversAssistant Panel 自动发现
Continue (VS Code / JetBrains)config.yaml 的 mcpServersv0.9+ 支持
通义灵码 / CodeGeeX / 文心快码插件设置 → MCP 服务2026 Q1 起陆续支持
Cline (原 Claude Dev)MCP Servers 面板 → 编辑配置VS Code 扩展
\n
\n {`{\n \"mcpServers\": {\n \"chivox-speech-eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n }\n }\n}`}\n 所有 IDE 类客户端都走远程 Streamable HTTP,零本地依赖。需要实时录音才需切到 Claude Desktop 的本地代理模式。\n
\n\n \n

扣子(Coze)是字节跳动推出的 AI 应用开发平台,支持通过 MCP 扩展为 Agent 赋予外部工具能力。接入驰声语音评测后,你可以构建口语练习 Bot、发音诊断助手等应用。

\n

方式一:扣子空间 MCP 扩展(推荐)

\n
    \n
  1. 打开 扣子空间(space.coze.cn)
  2. \n
  3. 在对话框下方点击 「添加扩展」
  4. \n
  5. 选择 「自定义」 标签,点击添加新的 MCP 服务
  6. \n
  7. 填入以下配置信息:
  8. \n
\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
名称chivox-speech-eval
传输类型streamable-http
URLhttps://speech-eval.site/mcp
\n
\n
    \n
  1. 保存后,在对话中输入 「帮我评测这段英文发音」 即可触发 Agent 调用
  2. \n
\n 添加 MCP 扩展后,扣子空间的 Agent 会自动识别并调用评测工具。你可以在 Agent 的思考过程中看到具体的工具调用细节。\n\n

方式二:在 Coze 开发平台的 Bot 中使用

\n
    \n
  1. 进入 Coze 开发平台,创建或编辑 Bot
  2. \n
  3. 在 Bot 的 「插件」 或 「工具」 面板中,添加 MCP 工具
  4. \n
  5. 选择 Streamable HTTP 类型,填入 URL:https://speech-eval.site/mcp
  6. \n
  7. Bot 将自动发现所有可用的评测工具(如 evaluate_english_word 等)
  8. \n
  9. 在 Bot 的人设提示词中,添加语音评测相关的引导语
  10. \n
\n {`你是一位专业的英语口语教练。当用户上传音频并请求评测时:\n1. 使用 evaluate_english_word / evaluate_english_sentence 等工具进行评测\n2. 根据评测结果(overall、accuracy、fluency 等分数)给出专业分析\n3. 针对得分较低的维度提供具体改进建议\n4. 鼓励用户持续练习`}\n
\n\n \n

如果你需要在 Coze 工作流中集成语音评测能力,可以通过 HTTP Request 节点调用评测 API:

\n\n

步骤 1:上传音频

\n

在工作流中添加一个 HTTP Request 节点,配置如下:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
配置项值
方法POST
URLhttps://speech-eval.site/upload
Content-Typeaudio/mp3
Body音频文件二进制数据
\n
\n

响应中获取 {'{{audioId}}'},传递给下一步。

\n\n

步骤 2:调用评测

\n

添加第二个 HTTP Request 节点,通过 MCP 接口调用评测工具:

\n {`{\n \"jsonrpc\": \"2.0\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"evaluate_english_sentence\",\n \"arguments\": {\n \"audioId\": \"{{audioId}}\",\n \"sentence\": \"{{ref_text}}\"\n }\n },\n \"id\": 1\n}`}\n\n

步骤 3:处理结果

\n

评测结果通过 JSON 格式返回,可使用 Coze 的 代码节点 或 LLM 节点 对结果进行解析和二次处理(如生成学习建议、计算进步趋势等)。

\n\n 工作流方式适合需要固定流程的场景(如批量评测、定时任务、与其他系统联动)。如果是交互式场景,推荐使用上方的 MCP 扩展方式,Agent 会自动选择合适的工具。\n\n
\n

完整工作流示意

\n
\n 用户输入音频\n →\n HTTP: 上传音频\n →\n HTTP: 调用评测\n →\n LLM: 分析结果\n →\n 输出反馈\n
\n
\n
\n\n \n

这一类是面向「上班族」的企业 / 日常 AI 助手,产品形态是个聊天框 + 插件市场 / 扩展面板。接入后,员工在 App 里打字「帮我评一下这段录音」就能自动触发驰声评测,不用写任何代码。

\n\n
\n
\n

豆包(Doubao)App / 桌面版

\n

字节跳动官方 AI 助手,2026 年起桌面版支持 MCP 扩展。

\n
    \n
  1. 桌面版设置 → 「智能体扩展」 → 添加 MCP 服务
  2. \n
  3. 类型选 streamable-http,URL 填 https://speech-eval.site/mcp
  4. \n
  5. 对话中直接说「帮我评测」即可自动调用
  6. \n
\n
\n\n
\n

飞书智能伙伴(My AI)

\n

飞书企业 AI,支持以 MCP / Function Calling 挂载外部工具给团队 Bot。

\n
    \n
  1. 飞书开发者后台 → 创建应用 → 「AI 能力 / 智能伙伴」
  2. \n
  3. 在「工具」中选 外部 MCP 服务,填入上方 URL
  4. \n
  5. 把智能伙伴拉进群聊,@ 它提交音频即可评测
  6. \n
\n
\n\n
\n

WorkBuddy / 企业智能助手

\n

字节 WorkBuddy、腾讯会议 AI、企业微信智能助手等企业 AI 工作台场景。

\n
    \n
  1. 在工作台的「技能 / 扩展」后台新增一个 MCP 连接器
  2. \n
  3. 传输协议选 Streamable HTTP,地址填 https://speech-eval.site/mcp
  4. \n
  5. 把技能发布到指定部门 / 群组,HR、培训、销售口语陪练场景即可直接用
  6. \n
\n
\n\n
\n

钉钉 AI 助理 / 通义千问 App

\n

阿里生态:钉钉 AI 助理支持自定义插件,通义 App 可通过「AI 工具箱」挂载 MCP。

\n
    \n
  1. 钉钉开发者后台 → AI 助理 → 「插件开发 / MCP 接入」
  2. \n
  3. 选 HTTP Streamable,填入驰声 MCP URL 并开启鉴权(可选)
  4. \n
  5. 在钉钉群 @AI 助理上传音频,自动返回评测卡片
  6. \n
\n
\n
\n\n 典型场景 · 小龙虾们的共同剧本:销售口语陪练 → 外语培训 → 主持 / 播音岗位考核 → K12 英语作业批改 → 客服话术复盘。这些「上班族 AI 工作台」接入驰声 MCP 后,员工 / 学员只要对着话筒说话,AI 就能自动打分并给出个性化改进建议,运营 / 培训 / 教研团队零开发即可上线。\n
\n\n \n

如果你需要把语音评测编排进多步业务流(例如:学员录音 → 评测 → 生成错题集 → 推送到 CRM),可视化工作流平台比聊天 Bot 更合适。

\n\n
\n
\n

Dify

\n

开源 LLMOps,v0.15+ 原生 MCP 工具。

\n
    \n
  • 「工具」→「自定义 MCP」→ 填 URL
  • \n
  • 在 Chatflow / Workflow 节点里直接拖用
  • \n
\n
\n
\n

n8n

\n

工作流自动化,用 MCP Client 节点。

\n
    \n
  • 添加 MCP Client 节点
  • \n
  • Transport 选 HTTP Stream,URL 贴驰声地址
  • \n
  • Tool 下拉自动列出 16 个评测能力
  • \n
\n
\n
\n

Flowise / LangFlow

\n

可视化 LangChain Agent 编排。

\n
    \n
  • 拖出 MCP Tool 节点
  • \n
  • 连到 AgentExecutor 即可
  • \n
\n
\n
\n\n 可视化平台的好处是流程可追溯、可回放,适合教育机构 / 培训部门做批量评测 + 报表导出;缺点是单步延迟略高于直接 MCP 调用,对延迟敏感的交互场景建议用 Cursor / Claude Desktop 直连。\n
\n\n \n

任何遵循 MCP 协议的客户端都可以接入,统一使用以下配置:

\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
传输类型streamable-http
URLhttps://speech-eval.site/mcp
鉴权(可选)Header:Authorization: Bearer <MCP_API_KEY>
\n
\n

还没找到你用的客户端?任何支持 Model Context Protocol 的终端都通用。找不到入口?下一小节「编程用 MCP」里用 SDK 直接接即可。

\n
\n
\n\n {/* ══════ 接入 · 编程用 MCP ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 你在写一段真正的后端服务:一个 Agent Worker、一个 API、一个自动化脚本
  • \n
  • 业务里的「语音评测」是其中一个步骤,需要由代码 决定何时调用、如何解析结果
  • \n
  • 三种主流写法:① 官方 MCP 客户端库 → ② Agent 框架自动桥接 → ③ 退化到 chat.completions + tools 参数
  • \n
\n

💡 强烈推荐①或②:驰声有 16 个评测工具,让 MCP 自动注入 tool schema,每新增一个题型不用改一行业务代码。

\n
\n\n \n

最底层、也最推荐的方式。由 Anthropic 官方维护,一次连接自动拿到全部工具的 JSON Schema,然后交给任意 LLM。

\n\n

Python:mcp

\n {`# pip install mcp openai\nimport asyncio, os\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nMCP_URL = \"https://speech-eval.site/mcp\"\nllm = OpenAI(api_key=os.getenv(\"DOUBAO_KEY\"),\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\") # 豆包 / DeepSeek / OpenAI 同构\n\nasync def main(audio_id: str, ref: str):\n async with streamablehttp_client(MCP_URL) as (reader, writer, _):\n async with ClientSession(reader, writer) as sess:\n await sess.initialize()\n\n tools = await sess.list_tools()\n openai_tools = [{\n \"type\": \"function\",\n \"function\": {\"name\": t.name, \"description\": t.description,\n \"parameters\": t.inputSchema},\n } for t in tools.tools]\n\n resp = llm.chat.completions.create(\n model=\"doubao-1-5-pro-32k\",\n messages=[{\"role\": \"user\",\n \"content\": f\"帮我评测 audioId={audio_id},参考文本:{ref}\"}],\n tools=openai_tools,\n )\n\n for call in resp.choices[0].message.tool_calls or []:\n result = await sess.call_tool(call.function.name,\n arguments=eval(call.function.arguments))\n print(call.function.name, \"→\", result.content[0].text[:200])\n\nasyncio.run(main(\"abc123\", \"I think therefore I am\"))`}\n\n

TypeScript / Node.js:@modelcontextprotocol/sdk

\n {`// npm i @modelcontextprotocol/sdk openai\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport OpenAI from \"openai\";\n\nconst mcp = new Client({ name: \"chivox-biz\", version: \"1.0.0\" });\nawait mcp.connect(new StreamableHTTPClientTransport(new URL(\"https://speech-eval.site/mcp\")));\n\nconst { tools } = await mcp.listTools();\nconst openai = new OpenAI({ apiKey: process.env.DEEPSEEK_KEY, baseURL: \"https://api.deepseek.com\" });\n\nconst resp = await openai.chat.completions.create({\n model: \"deepseek-chat\",\n messages: [{ role: \"user\", content: \"评测 audioId=abc123, 参考 I think therefore I am\" }],\n tools: tools.map(t => ({ type: \"function\", function: {\n name: t.name, description: t.description, parameters: t.inputSchema\n }})),\n});\n\nfor (const call of resp.choices[0].message.tool_calls ?? []) {\n const r = await mcp.callTool({ name: call.function.name,\n arguments: JSON.parse(call.function.arguments) });\n console.log(call.function.name, r.content);\n}`}\n 这种写法 LLM 供应商可换(豆包 / DeepSeek / GPT / Qwen / Moonshot),工具自动更新(驰声新增题型无需改业务代码),适合生产后端。\n
\n\n \n

如果项目已经在用 Agent 框架,几行 adapter 就能把驰声 MCP 塞进去,框架本身会接管 tool-calling 循环、重试、日志。

\n\n
\n
\n

LangChain / LangGraph(Python)

\n {`# pip install langchain-mcp-adapters langgraph\nfrom langchain_mcp_adapters.client import MultiServerMCPClient\nfrom langgraph.prebuilt import create_react_agent\n\nclient = MultiServerMCPClient({\n \"chivox\": {\n \"transport\": \"streamable_http\",\n \"url\": \"https://speech-eval.site/mcp\",\n }\n})\ntools = await client.get_tools()\n\nagent = create_react_agent(\"openai:gpt-4o-mini\", tools)\nresult = await agent.ainvoke({\"messages\":\n [(\"user\", \"评测 audioId=abc123 参考 think\")]})\nprint(result[\"messages\"][-1].content)`}\n
\n\n
\n

Mastra(TypeScript)

\n {`// npm i @mastra/core @mastra/mcp\nimport { MCPClient } from \"@mastra/mcp\";\nimport { Agent } from \"@mastra/core/agent\";\nimport { openai } from \"@ai-sdk/openai\";\n\nconst mcp = new MCPClient({ servers: {\n chivox: { url: new URL(\"https://speech-eval.site/mcp\") }\n}});\n\nexport const speechCoach = new Agent({\n name: \"speech-coach\",\n instructions: \"你是口语教练,用 chivox 工具评测并给改进建议。\",\n model: openai(\"gpt-4o-mini\"),\n tools: await mcp.getTools(),\n});`}\n
\n\n
\n

OpenAI Agents SDK(Python)

\n {`# pip install openai-agents\nfrom agents import Agent, Runner\nfrom agents.mcp import MCPServerStreamableHttp\n\nchivox = MCPServerStreamableHttp(\n params={\"url\": \"https://speech-eval.site/mcp\"},\n name=\"chivox-speech-eval\",\n)\n\nasync with chivox:\n agent = Agent(name=\"coach\",\n instructions=\"专业口语教练\",\n mcp_servers=[chivox])\n r = await Runner.run(agent, \"评测 audioId=abc123\")\n print(r.final_output)`}\n
\n\n
\n

LlamaIndex / AutoGen / CrewAI

\n

这些框架都有官方或社区 MCP adapter,用法与上述类似:

\n
    \n
  • LlamaIndex:llama-index-tools-mcp
  • \n
  • AutoGen:autogen-ext[mcp]
  • \n
  • CrewAI:crewai-tools 的 MCPServerAdapter
  • \n
  • Spring AI(Java):spring-ai-mcp-client
  • \n
\n
\n
\n
\n\n \n

\n DeepSeek、GLM(智谱)、KIMI(Moonshot)、豆包(火山方舟)、千帆、DashScope 等若提供 OpenAI 兼容的 HTTP API,接入驰声 MCP 的套路一致:用 MCP 客户端拉取工具列表 → 转为{' '}\n tools → 模型决策 tool_calls → MCP 执行并回填 → 再让模型生成诊断话术。\n

\n
\n
\n ① MCP list_tools()\n →\n ② 转 OpenAI tools 格式\n →\n ③ LLM 决策 tool_calls\n →\n ④ MCP call_tool()\n →\n ⑤ 评测结果回填 → LLM 诊断\n
\n
\n 各厂商仅需替换 base_url 与 api_key,驰声 MCP 与 tools 桥接代码可原样复用。\n\n

先上传音频,拿到 audioId

\n

文件评测工具通常需要 audioId(或路径参数,视工具而定)。下面是用 HTTP 上传的最小示例:

\n {`import requests\n\nwith open('audio.mp3', 'rb') as f:\n r = requests.post(\n 'https://speech-eval.site/upload',\n data=f,\n headers={'Content-Type': 'audio/mp3'}\n )\n\nresult = r.json()\nprint(f\"audioId: {result['audioId']}\")\nprint(f\"size: {result['size']} bytes\")\nprint(f\"expires: {result['expiresIn']}\")`}\n {`const fs = require('fs');\n\nconst audioData = fs.readFileSync('audio.mp3');\n\nconst res = await fetch('https://speech-eval.site/upload', {\n method: 'POST',\n headers: { 'Content-Type': 'audio/mp3' },\n body: audioData,\n});\n\nconst result = await res.json();\nconsole.log('audioId:', result.audioId);`}\n\n

再以豆包为例:MCP 动态 tools + chat.completions 折返跑

\n

当你用的 LLM SDK 还没有原生 MCP 支持(比如老版本的火山方舟 / 百度千帆 / 通义 DashScope),退化方案是:用 MCP 客户端一次性拉到 tool schema,然后按 OpenAI Function Calling 格式喂给 LLM。

\n {`# 适用:豆包(火山方舟)/ DeepSeek / Qwen / Moonshot / GLM 等 OpenAI 兼容 API\n# 核心思路:MCP 列工具 → 转 OpenAI tools → LLM 决策 → MCP 执行 → 回填\n\nasync with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n\n # ① 用 MCP 拉到的 schema 自动转 OpenAI 格式\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 喂给豆包\n messages = [{\"role\": \"user\", \"content\": \"评测一下 audioId=abc123\"}]\n resp = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages, tools=oa_tools,\n )\n\n # ③ LLM 回 tool_calls → 折返跑到 MCP 执行\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for c in msg.tool_calls:\n result = await mcp.call_tool(\n c.function.name, arguments=json.loads(c.function.arguments))\n messages.append({\"role\": \"tool\", \"tool_call_id\": c.id,\n \"content\": result.content[0].text})\n # ④ 再喂一轮,让豆包根据评测结果产出自然语言诊断\n final = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages)\n print(final.choices[0].message.content)`}\n 千万别手写 tool schema!驰声共 16 个评测工具(英文 10 + 中文 6),每个工具参数较多,手写既容易错也难维护。一定用 MCP list_tools() 动态拿。\n
\n\n \n

DeepSeek 提供与 OpenAI 完全兼容的 API,推荐使用 deepseek-chat(V3)或 deepseek-reasoner(R1)。

\n\n

环境准备

\n {`DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\n# DeepSeek 客户端(OpenAI 兼容)\nclient = OpenAI(\n api_key=os.environ[\"DEEPSEEK_API_KEY\"],\n base_url=\"https://api.deepseek.com\",\n)\n\nasync def evaluate_with_deepseek(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n\n # ① 拉取驰声 MCP 工具列表\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 调用 DeepSeek,让它选择合适的评测工具\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段英文录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"deepseek-chat\", # 或 deepseek-reasoner\n messages=messages,\n tools=oa_tools,\n )\n\n # ③ 执行 tool_calls\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n\n # ④ 让 DeepSeek 根据评测结果生成自然语言诊断\n final = client.chat.completions.create(\n model=\"deepseek-chat\",\n messages=messages,\n )\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_deepseek(\"audio_abc123\", \"Hello, nice to meet you.\"))`}\n 推荐使用 deepseek-chat(V3)处理评测结果诊断,速度快、成本低;若需要深度分析或出题逻辑,可换用 deepseek-reasoner(R1),但注意 R1 不支持 Function Calling,需先用 V3 做工具调用再将结果交给 R1 分析。\n
\n\n \n

智谱 AI 提供 glm-4、glm-4-flash(免费)等模型,支持 OpenAI 兼容接口,同时也有官方 Python SDK。

\n\n

环境准备

\n {`ZHIPU_API_KEY=xxxxxxxx.xxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

方式一:OpenAI 兼容接口(推荐)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = OpenAI(\n api_key=os.environ[\"ZHIPU_API_KEY\"],\n base_url=\"https://open.bigmodel.cn/api/paas/v4/\",\n)\n\nasync def evaluate_with_glm(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"glm-4-flash\", # 免费模型;生产可换 glm-4 或 glm-4-plus\n messages=messages,\n tools=oa_tools,\n )\n\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n final = client.chat.completions.create(\n model=\"glm-4-flash\", messages=messages)\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_glm(\"audio_abc123\", \"How are you today?\"))`}\n\n

方式二:官方 zhipuai SDK

\n {`from zhipuai import ZhipuAI\n\nclient = ZhipuAI(api_key=os.environ[\"ZHIPU_API_KEY\"])\n\n# 其余逻辑与方式一相同,仅替换 client 实例\nresp = client.chat.completions.create(\n model=\"glm-4-flash\",\n messages=messages,\n tools=oa_tools,\n)`}\n glm-4-flash 免费,适合开发测试;glm-4-plus 上下文更长、指令遵循更准,适合生产环境中的诊断报告生成。\n
\n\n \n

Moonshot AI 的 KIMI 模型同样兼容 OpenAI API,支持超长上下文(最高 128k),特别适合需要分析多段录音历史或生成详细学习报告的场景。

\n\n

环境准备

\n {`MOONSHOT_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx\nCHIVOX_APP_KEY=your_chivox_app_key\nCHIVOX_SECRET_KEY=your_chivox_secret_key`}\n\n

完整示例(Python)

\n {`import os, json, asyncio\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nclient = OpenAI(\n api_key=os.environ[\"MOONSHOT_API_KEY\"],\n base_url=\"https://api.moonshot.cn/v1\",\n)\n\nasync def evaluate_with_kimi(audio_id: str, ref_text: str):\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n messages = [{\"role\": \"user\", \"content\":\n f\"请评测这段英文录音,audioId={audio_id},参考文本:{ref_text}\"}]\n\n resp = client.chat.completions.create(\n model=\"moonshot-v1-8k\", # 也可选 moonshot-v1-32k / moonshot-v1-128k\n messages=messages,\n tools=oa_tools,\n )\n\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for call in msg.tool_calls:\n result = await mcp.call_tool(\n call.function.name,\n arguments=json.loads(call.function.arguments),\n )\n messages.append({\n \"role\": \"tool\",\n \"tool_call_id\": call.id,\n \"content\": result.content[0].text,\n })\n final = client.chat.completions.create(\n model=\"moonshot-v1-8k\", messages=messages)\n return final.choices[0].message.content\n\nasyncio.run(evaluate_with_kimi(\"audio_abc123\", \"Nice to meet you.\"))`}\n KIMI 的长上下文特别适合「多轮口语练习 + 历史分析」场景:把用户过去 10 次的评测 JSON 全部塞进 messages,让 KIMI 生成横跨多次练习的进步报告,这是 8k 模型做不到的。\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
模型推荐版本base_urlFunction Calling适合场景
DeepSeek V3deepseek-chatapi.deepseek.com✓ 支持评测调用 + 诊断,性价比最高
DeepSeek R1deepseek-reasonerapi.deepseek.com✗ 不支持深度分析(需先用 V3 调工具)
GLM-4-Flashglm-4-flashopen.bigmodel.cn/…/v4✓ 支持开发测试(免费额度)
GLM-4-Plusglm-4-plusopen.bigmodel.cn/…/v4✓ 支持生产诊断报告,指令遵循强
KIMI 8kmoonshot-v1-8kapi.moonshot.cn/v1✓ 支持单次评测 + 即时反馈
KIMI 128kmoonshot-v1-128kapi.moonshot.cn/v1✓ 支持多轮历史 + 学习进度报告
\n
\n 所有模型均通过 OpenAI Python SDK(openai 包)调用,仅需替换 base_url 和 api_key,驰声 MCP 侧代码无需改动。\n
\n\n \n

大部分落地场景其实是:你已有一个业务后端(教育 SaaS / 培训系统 / 客服平台),只需要新增一个「语音评测」能力。推荐架构:

\n\n
\n
\n 前端录音 / 上传\n →\n 业务后端\n →\n MCP Client(常驻连接)\n →\n 驰声 MCP\n ↘\n LLM(诊断 / 出题)\n
\n
\n\n

FastAPI 示例(生产最小骨架)

\n {`from fastapi import FastAPI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\nfrom contextlib import asynccontextmanager\n\nmcp_session: ClientSession | None = None\n\n@asynccontextmanager\nasync def lifespan(app):\n global mcp_session\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as s:\n await s.initialize()\n mcp_session = s\n yield\n mcp_session = None\n\napp = FastAPI(lifespan=lifespan)\n\n@app.post(\"/api/evaluate\")\nasync def evaluate(audio_id: str, ref_text: str):\n # 直接选一个最合适的工具执行(不经 LLM,延迟最低)\n r = await mcp_session.call_tool(\"evaluate_english_sentence\",\n {\"audioId\": audio_id, \"sentence\": ref_text})\n return {\"result\": r.content[0].text}`}\n\n 关键优化:① MCP 连接在 lifespan 里做成长连接,不要每次请求都重连;② 对延迟敏感的场景可以「跳过 LLM 直接调 tool」,把 LLM 放到「生成诊断报告」那一步。\n
\n\n
\n

方案选型速查

\n
\n \n \n \n \n \n \n \n \n \n \n \n
场景推荐方案
AI 对话 / Copilot 类产品,LLM 供应商可能会换① 官方 MCP 客户端库
已有 LangChain / Mastra / Agents SDK 技术栈② Agent 框架 + adapter
火山方舟 / 千帆控制台直连,最小侵入③ chat.completions + tools
教育 SaaS / 培训 / 客服等业务后端集成④ 自研后端 Agent
\n
\n
\n
\n\n {/* ══════ 评测模式 ══════ */}\n \n\n \n

通过本地麦克风实时录音,音频以 WebSocket 流式推送到评测服务,无需生成中间文件。这是最灵活、延迟最低的评测方式,特别适合交互式口语练习场景。

\n 实时录音评测需要安装 SoX 并使用本地代理模式(Claude Desktop / Claude Code)。Cursor 等远程直连模式暂不支持实时录音。\n\n

需要按顺序调用三个工具:

\n\n
\n
\n

create_stream_session — 创建流式评测会话

\n \n

返回 session_id,后续步骤需使用。

\n
\n\n
\n

start_recording — 开始麦克风录音

\n \n

调用后自动启动麦克风,音频通过 WebSocket 实时推送到评测服务。

\n
\n\n
\n

stop_recording — 停止录音并获取结果

\n \n
\n
\n
\n\n \n
\n \n

用户:"请评测我的英文发音,文本是 Hello"

\n

AI 调用 create_stream_session(core_type="en.word.score", ref_text="Hello")

\n

→ 获得 session_id

\n
\n \n

AI 调用 start_recording(session_id=xxx)

\n

麦克风开始录音,音频通过 WebSocket 实时推送到评测服务

\n
\n \n

用户说完后告知 AI "结束"

\n

AI 调用 stop_recording(session_id=xxx)

\n

→ 返回评测结果(总分、准确度、流利度、音素得分等)

\n
\n
\n
\n\n \n

适用于已有音频文件的评测场景,支持三种输入方式:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
参数说明适用场景
audio_file_path本地文件路径代理自动读取并转为 Base64,最便捷
audio_base64Base64 编码数据已有编码数据时使用
audio_url音频文件 URL音频托管在云存储时使用
\n
\n 推荐使用 audio_file_path,只需传入本地文件路径,代理会自动处理编码和上传。\n

支持的音频格式:mp3, wav, ogg, m4a, aac, pcm

\n

限制:单文件最大 50MB,大于 500KB 的文件自动压缩为 16kHz / 单声道 / 32kbps。

\n
\n
\n\n {/* ══════ API 参考 ══════ */}\n \n\n \n \n\n

通用参数:所有英文评测工具均支持以下参数。

\n \n
\n\n \n \n\n

通用参数:

\n \n
\n\n \n

所有评测工具返回统一的结构化结果:

\n {`{\n \"overall\": 85,\n \"accuracy\": 82,\n \"pron\": 88,\n \"fluency\": {\n \"overall\": 78,\n \"speed\": 65,\n \"pause\": 2\n },\n \"integrity\": 95,\n \"details\": [\n {\n \"char\": \"hello\",\n \"score\": 85,\n \"phone\": [\n { \"phoneme\": \"h\", \"score\": 90 },\n { \"phoneme\": \"ɛ\", \"score\": 82 },\n { \"phoneme\": \"l\", \"score\": 88 },\n { \"phoneme\": \"oʊ\", \"score\": 80 }\n ]\n }\n ]\n}`}\n
\n \n \n \n \n \n \n \n {[\n ['overall', '0–100', '综合总分,反映整体语音质量'],\n ['accuracy', '0–100', '准确度,音素级别的发音准确率'],\n ['pron', '0–100', '发音得分,整体发音质量评价'],\n ['fluency.overall', '0–100', '流利度,语流的自然度与平滑度'],\n ['fluency.speed', '0–100', '语速得分,每分钟词/音节计量'],\n ['fluency.pause', 'number', '不自然停顿次数'],\n ['integrity', '0–100', '完整度,是否完整朗读了参考文本'],\n ['details[].phone[]', 'array', '每个音素的独立评分,可定位具体弱项'],\n ['details[].stress[]', 'array', '重音得分,检测重弱读是否正确'],\n ].map(([field, range, desc]) => (\n \n \n \n \n \n ))}\n \n
字段范围说明
{field}{range}{desc}
\n
\n
\n\n \n
\n \n \n \n \n \n \n \n {[\n ['音频 ID 无效或已过期', '音频上传后 5 分钟内有效,评测完成后自动删除', '重新上传音频'],\n ['服务器繁忙', '当前请求过多,排队已满', '稍后重试,使用指数退避策略'],\n ['存储空间已满', '服务器临时音频存储已满', '稍后重试,系统会自动清理'],\n ['音频格式不支持', '上传了不支持的文件类型', '使用 mp3/wav/ogg/m4a/aac/pcm'],\n ['音频时长超限', '超过该题型最大时长限制', '裁剪音频后重试'],\n ['WebSocket 连接断开', '网络不稳定导致流式连接中断', '代理会自动重连,如持续失败请检查网络'],\n ].map(([scene, reason, fix]) => (\n \n \n \n \n \n ))}\n \n
场景原因解决方式
{scene}{reason}{fix}
\n
\n
\n
\n\n {/* ══════ 最佳实践 ══════ */}\n \n\n \n

\n 下面这些模板与{' '}\n 免费体验{' '}\n Demo 中实际使用的「教练 Prompt」一脉相承,全部围绕 角色 / 任务 / 方法 / 输出格式 / 语气 五段式结构,并使用占位符{' '}\n {'{mcp_response}'} 直接拼接 MCP 工具返回的 JSON。\n 推荐在 system 消息里挂载,再把工具返回原文塞进\n user 消息,由 LLM 基于真实分数和音素生成可读诊断 / 练习材料。\n

\n\n \n 使用建议:\n
    \n
  • 把 MCP 工具调用的完整 JSON(含 overall / dp_type / phonemes 等字段)原样塞入 {'{mcp_response}'},不要预先做汇总——细节越完整诊断越具体。
  • \n
  • 「诊断」类模板让 LLM 输出 Markdown 给最终用户阅读;「练习」类模板要求 LLM 输出严格 JSON 给前端渲染。两步分开调用,效果远好于一次性混合。
  • \n
  • 题型决定 prompt:单词题用音素级、句子题加韵律、段落题加 chunk / 整体性,半开放题套四维评级。下面按这 6 类分别给出。
  • \n
\n
\n\n {/* ─── A. 诊断类 · 输出 Markdown 给学习者阅读 ─── */}\n

\n A. 二次诊断 · 输出 Markdown\n

\n
\n
\n

\n 1. 单词级 · 音素诊断\n

\n

\n 适用工具:en.word.score / cn.word.raw。围绕 phonemes[].dp_type 找出错读音。\n

\n {`你是一位专业的英语发音教练。下面是驰声 MCP(en.word.score)返回的单词级评测数据:\n一个目标词、总分与发音分、以及带有 dp_type 的音素数组。\n\n## 任务\n为学习者写一份 **可直接阅读** 的发音诊断,每一条都要引用音素分数(写出 IPA 符号)。\n\n## 方法\n- 按 dp_type 分组:先看 mispron,再补充 normal 但分数 < 70 的\"边缘音\"。\n- 每个问题音素:① 典型母语干扰 → ② 你听到的声音 → ③ 一条具体的发音修正动作(下颌 / 舌位 / 气流 / 唇形)。\n- 重音符号 ˈ 标记的音节,重音错位也要单独列出(即便音素本身分数尚可)。\n- 最多列 4 条,按 **影响力从弱到强** 排序。\n\n## 输出\n精简 Markdown:可选一句总结 → 编号列表 → 单行 **🎯 优先级** 排序。\n\n## 语气\n友善、具体、可执行,不要空喊\"加油\"。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 2. 句子级 · 节奏 + 重音诊断\n

\n

\n 适用工具:en.sent.score。开头先给一行\"计分牌\",再从 phones → words → prosody。\n

\n {`你是一位专业的英语口语教练。下面是驰声 MCP(en.sent.score)返回的句子级数据:refText、总分、发音子分(accuracy / integrity / fluency / rhythm)、可选 speed(WPM),以及 details[] 中的逐词得分、dp_type 与可选 phonemes[]。\n\n## 任务\n开头给一行紧凑的 **计分牌**(总分 + 各子分 + 速度),再按 **音素 → 词 → 韵律** 顺序展开诊断。\n\n## 检查清单(每项都要覆盖;不适用则写\"无明显问题\")\n1. **音素级**:每个 score < 70 或 dp_type ≠ normal 的词,展开 phonemes,命名典型错误(如 /ð/ → /d/)并给一条修正动作。\n2. **漏读 / 多读**:标注 dp_type=omit / insert,解释如何拉低 integrity。\n3. **韵律**:基于 rhythm + 错读词的重音,指出重音错位、陈述句调型平直、断句过多等。\n4. **流利度 vs 准确度**:若 fluency 高但 accuracy 低,明确指出,让学习者知道优先改哪一项。\n\n## 输出格式\nMarkdown 子标题:**Pronunciation / Prosody / Study priority**(最后一行简短排序,按 ROI 从高到低)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 3. 段落级 · 音素族归并 + 完整度\n

\n

\n 适用工具:en.pred.score。把同类错音合并为\"音素族\",避免逐词复述。\n

\n {`你是一位专业的英语口语教练。下面是驰声 MCP(en.pred.score)返回的段落级数据:长 refText、总分、发音子分、可选 speed / integrity,以及大量 details[](同一个词可能在不同子句中重复出现;空 char + dp_type=omit 表示漏读)。\n\n## 任务\n对整段做 **整体诊断**:\n(a) 完整度 / 漏读,\n(b) 反复出现的 **音素族**,\n(c) 节奏与断句,\n(d) 各子分之间是否相互印证。\n\n## 检查清单\n1. **integrity / dp_type**:列出每个 omit / insert,并给出所在子句;解释长读时为什么虚词容易被吞。\n2. **音素聚类**:将弱词按共同音素问题归族(/θ/ 链、/e/ 链、/ɒ/ 等),引用 details 中的实例。\n3. **韵律**:结合 rhythm 与标点 —— 短语内停顿过多?子句边界缺失?\n4. **整体一致性**:若 fluency 正常但 accuracy 差(或反之),点明并指出对练习设计的影响。\n\n## 输出格式\nMarkdown 章节:**Summary / Completeness / Pronunciation (families) / Rhythm / Study priorities**(最后一项最多 4 条,按影响力排序)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 4. 半开放题 · IELTS 风格四维评级\n

\n

\n 适用工具:en.pqan.score。结合学习者 transcript + 四维分数,给出可教学的\"升档建议\"。\n

\n {`你是一位 **IELTS / 课堂口语风格** 的口语教练。下面是驰声 MCP(en.pqan.score)返回的半开放题数据:题目 refText、学习者 transcript、overall、四个维度分(grammar / content / fluency / pron)、speed(WPM)、以及结构化的 issues[] 标记。\n\n## 任务\n给出 **基于 rubric 的诊断**:先用一句话给出 0–100 的整体段位估计,再 **逐维度** 解释,并 **引用 transcript 中的短句**(不要复述全文)。最后给 3–5 条 **可执行的\"升档建议\"**(句型 / 模板,而不是\"多练一点\")。\n\n## 权重(要明确告诉学习者)\n- **Content ~30%** — 想法深度、举例、具体程度\n- **Grammar ~25%** — 句型多样性、主谓一致、从句\n- **Fluency ~25%** — 语速、停顿、口头禅、衔接\n- **Pronunciation ~20%** — 音素 + 可懂度\n\n## 跨维度检查\n- 若 content 最低,先给\"展开模板\",不要先抠音素。\n- 若 fluency 低 + WPM 低,区分\"思考型停顿\"与\"发音卡顿\"。\n- 若 pron 标出特定音,绑定到 transcript 里 **真实出现过的词**。\n\n## 输出格式\nMarkdown:**段位估计** → 紧凑的 **得分表格** → **\"To reach the next band\"** 编号列表(每条给出可仿写的句型)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 5. 中文专项 · 声调 / 儿化 / 变调\n

\n

\n 适用工具:cn.word.raw / cn.sent.raw / cn.pred.raw。中文评测最大权重在 **声调**,必须单独检查。\n

\n {`你是一位专业的普通话口语教练。下面是驰声 MCP(cn.sent.raw)返回的中文句子评测数据:整句分数 + 逐字 details + 可选 phonemes + 流利 / 节奏分。\n\n## 中文评测的权重\n- **声调错误权重最高** —— 声调读错可能直接改变词义\n- dp_type=mispron 多来自:声调错、平翘舌混用、前后鼻音混用\n- 拼音对、声调错,听感仍是\"洋腔洋调\"\n\n## 检查清单(缺则写\"无明显问题\")\n1. **儿化**:phonemes 出现 r(儿化) 或 dp_type 提示时,确认是否被读成\"主音节 + 单独儿\"两拍。\n2. **轻声**:叠词、词缀、句末语气词 —— 第二字应短促轻读,无完整声调曲线。\n3. **变调**:三声连读、不 + 后字、一 + 后字,是否符合普通话规则。\n4. **节奏**:用 rhythm + 逗号位置,标记停顿过长或过碎,建议 chunk 边界。\n\n## 输出\nMarkdown 子标题:**总览 / 儿化 / 轻声 / 变调 / 节奏 / 学习优先级**(最后一项 1–3 条,按\"听感自然度提升\"排序)。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n {/* ─── B. 练习类 · 输出 JSON 给前端渲染 ─── */}\n

\n B. 微练习生成 · 输出严格 JSON\n

\n
\n
\n

\n 6. 单词 / 句子 · 微练习\n

\n

\n 建议在 诊断完成后 第二轮调用:让 LLM 严格按弱项音素生成,避免\"通用绕口令包\"。\n

\n {`你仍是这位学习者的发音教练。**第二轮诊断已经完成** —— 现在严格基于诊断里点名的弱音素,生成 **1:1 对应** 的微练习(不要给通用题)。\n\n## 输出(仅返回一段合法 JSON 数组,外层不要任何文字)\n根节点必须是数组,每个元素含 category(字符串)、icon(单个 emoji)、items({ \"label\", \"content\" } 数组)。\n\\`\\`\\`json\n[\n { \"category\": \"Phoneme drills\", \"icon\": \"🎯\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Awareness\", \"icon\": \"🗣️\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Whole word\", \"icon\": \"📝\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] }\n]\n\\`\\`\\`\n\n## 规则\n- **Phoneme drills**:诊断里每个 mispron 音素至少给一对最小对立对 + 一句短绕口令 / 重复句。\n- **Awareness**:当重音偏弱时,给一条 stress / 舌位 / 下颌姿态提示。\n- **Whole word**:2–3 句自然句,目标词分别出现在句首 / 句中 / 句末。\n- 所有 content 必须可念出声;字符串内不要再嵌套 JSON。\n\n## 上下文\n诊断结论:{previous_diagnosis}\n原始 MCP:\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n\n
\n

\n 7. 段落 · Chunk Map + 元认知\n

\n

\n 段落级练习要从\"音素\"上升到\"短语 / 整段 / 元认知录回放\"。直接对应 en.pred.score 的诊断结果。\n

\n {`你仍是这位学习者的口语教练。**段落级二次诊断** 已经列出了漏读位置和音素族 —— 现在请生成 **整段练习**:把弱音素串成\"族\"练习、用 chunk map 把虚词粘回短语,并附一条录音 → 回放 → 对照 MCP details 的元认知步骤。\n\n## 输出(仅返回一段合法 JSON 数组)\n\\`\\`\\`json\n[\n { \"category\": \"Phoneme families\", \"icon\": \"🎯\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Chunking\", \"icon\": \"🎵\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] },\n { \"category\": \"Metacognition\", \"icon\": \"🧠\", \"items\": [ { \"label\": \"…\", \"content\": \"…\" } ] }\n]\n\\`\\`\\`\n\n## 规则\n- **Phoneme families**:至少 3 条,按诊断里的音素族(/θ/、/e/、/ɒ/ 等)组织最小对立对 / 词链。\n- **Chunking**:① 给一行用 [ ] 和 / 标注的 chunk map(可加大致停顿秒数);② 给一句\"把漏掉的虚词嵌入短语\"的练习(不要孤立练)。\n- **Metacognition**:一条\"录音 → 回放 → 对照 MCP details\"的 N 遍练习(N 写明,2–3 之间)。\n- 字符串只能是纯展示文本,禁止嵌套 JSON。\n\n## 上下文\n诊断结论:{previous_diagnosis}\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n {/* ─── C. 跨题 / 运营 ─── */}\n

\n C. 跨题 / 运营\n

\n
\n
\n

\n 8. 多日学习报告\n

\n

\n 把过去 N 天的 MCP 评测结果聚合后丢给 LLM,输出适合发给学生 / 家长的周报。\n

\n {`你是一位英语口语学习顾问。下面是这位学习者过去 7 天的驰声 MCP 评测历史(按时间顺序),每条包含题型、coreType、overall、子分、weak_phonemes 摘要。\n\n## 任务\n为学习者生成一份 **周报**,目标读者:本人 + 家长 / 老师。\n强调 **趋势** 与 **下一步计划**,不要复述每一次具体分数。\n\n## 必须包含\n1. **整体趋势**:进步 / 持平 / 退步(一句话 + 简短依据)\n2. **维度变化**:accuracy / fluency / rhythm / integrity / speed 任意有数据的维度,给出\"本周均分 vs 上周\"\n3. **本周高光**:分数提升最大的题型 / 音素 / 句型\n4. **顽固问题**:连续 3 次以上未达 70 的音素或维度\n5. **下周计划**:3 条具体动作(每条对应一个 MCP 工具或一个练习类型)\n6. **结尾**:1–2 句鼓励性总结,避免空话\n\n## 风格\n- 像一位认真但不啰嗦的私教\n- 出现学生姓名时使用占位 {student_name}\n- 数字一律保留整数\n\n## 评测历史\n\\`\\`\\`json\n{history}\n\\`\\`\\``}\n
\n\n
\n

\n 9. 错误归因 · JSON 摘要\n

\n

\n 用于后端聚合 / 数据看板:让 LLM 把一次评测压缩成结构化摘要,方便入库统计。\n

\n {`你是一个评测结果归类器。下面是驰声 MCP 一次评测的完整返回。请抽取关键信息并 **仅返回合法 JSON**(不要任何解释文字)。\n\n## Schema\n\\`\\`\\`json\n{\n \"core_type\": \"string,例如 en.sent.score\",\n \"overall\": 0,\n \"sub_scores\": { \"accuracy\": 0, \"integrity\": 0, \"fluency\": 0, \"rhythm\": 0 },\n \"weak_phonemes\": [\n { \"ipa\": \"string\", \"avg_score\": 0, \"occur\": 0, \"example_word\": \"string\" }\n ],\n \"omissions\": [{ \"after\": \"string\", \"missing\": \"string\" }],\n \"stress_issues\": [{ \"word\": \"string\", \"expected\": \"string\", \"actual\": \"string\" }],\n \"primary_issue_tag\": \"phoneme|stress|fluency|integrity|content|none\",\n \"next_action_hint\": \"string,10 字以内,例如 \\\"练 /θ/ 对立对\\\"\"\n}\n\\`\\`\\`\n\n## 规则\n- weak_phonemes 只收 avg_score < 70 的项,最多 5 项,按 occur 降序。\n- 不要复述 refText,不要 markdown。\n- 字段缺失时使用 null 或空数组,不要省略 key。\n\n## MCP 数据\n\\`\\`\\`json\n{mcp_response}\n\\`\\`\\``}\n
\n
\n\n \n 怎么接到 MCP 工具调用?\n
\n 以「直调 chat.completions + 动态 tools」为例:第一轮 LLM 调出 en.sent.score 工具,把工具 result(即 tool 消息内容)原样填入上面任意「诊断」模板的{' '}\n {'{mcp_response}'},作为第二轮 user 消息发回;拿到诊断结论再走第三轮,套「微练习」模板得到 JSON。三轮调用即可串起 评测 → 诊断 → 练习 全链路。\n
\n
\n\n \n
    \n
  • 音频过期:上传后 5 分钟内有效。建议在上传后 3 分钟内完成评测。
  • \n
  • 服务繁忙:使用指数退避策略重试(1s → 2s → 4s),最多 3 次。
  • \n
  • 录音中断:WebSocket 断线后代理会自动重连。如持续失败,检查网络连接和 SoX 安装。
  • \n
\n
\n\n \n
    \n
  • 优先使用流式评测:实时录音模式跳过了文件上传环节,端到端延迟比文件评测低 30-50%。
  • \n
  • 音频压缩:文件评测时,上传前将音频转为 16kHz 单声道 mp3,可减少 60-80% 的上传体积。
  • \n
  • 选择合适的工具:单词评测比段落评测快 3-5 倍。如只需单词级分数,不要用句子评测。
  • \n
  • 本地文件路径最便捷:使用 audio_file_path 参数传入本地路径,代理自动处理编码,无需手动转 Base64。
  • \n
\n
\n
\n\n {/* ══════ 服务信息 ══════ */}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n
端点方法说明
/uploadPOST音频文件上传
/mcpPOSTMCP JSON-RPC 接口(Streamable HTTP)
/healthGET健康检查
\n
\n
\n \n
\n \n \n \n \n \n \n \n {[\n ['存储限制', '500MB', '最大音频存储空间'],\n ['最大排队', '10', '等待处理的请求数'],\n ['最大并发', '3', '同时处理的评测数'],\n ['音频有效期', '5 分钟', '上传后未评测自动过期'],\n ['文件大小限制', '50MB', '单个音频文件最大'],\n ].map(([k, v, d]) => (\n \n ))}\n \n
配置项默认值说明
{k}{v}{d}
\n
\n

\n 上表为托管侧技术默认;计费与试用/商用调用配额、并发档位以{' '}\n \n 会员套餐\n \n 说明为准,与上表独立。\n

\n
\n \n \n 当前线上版本:v1.0.0(网站未正式上线)。以下变更项为开发阶段规划记录,以正式发布公告为准。\n \n
\n {[\n { ver: 'v1.0.0', date: 'TBD', desc: '当前线上版本(网站未正式上线)' },\n ].map(l => (\n
\n {l.ver}\n {l.date}\n {l.desc}\n
\n ))}\n
\n
\n
\n\n \n );\n}\n\nexport default function DocsPage() {\n const locale = useLocale();\n return locale.startsWith('zh') ? : ;\n}\n"}, "48038d7e90e26ecc97c74b118f4445ce86cd45c1": {"t": 1785765800.678828, "n": 85736, "h": "d3b98ac9016dafb0", "c": "'use client';\n\nimport { useLocale } from 'next-intl';\nimport { DocsShell, type NavGroup } from './docs-shell';\nimport {\n CodeBlock,\n DocSection,\n SubDoc,\n ParamTable,\n Callout,\n FlowStep,\n ToolTable,\n} from './docs-shared';\nimport { DocsEnglishBody } from './docs-content-en';\nimport {\n BookOpen,\n Code2,\n Zap,\n FileText,\n Terminal,\n Globe,\n Mic,\n MessageSquare,\n BarChart3,\n AlertTriangle,\n Radio,\n FolderOpen,\n Workflow,\n Sparkles,\n Plug,\n Bot,\n Building2,\n Check,\n} from 'lucide-react';\n\n/* ─── Navigation Structure ─── */\n\nconst NAV = [\n { id: 'concept', icon: Workflow, label: 'MCP 工作原理', children: [\n { id: 'why-mcp', label: '为什么需要 MCP' },\n { id: 'scenario-walkthrough', label: '场景走查 · 6 步' },\n { id: 'dev-responsibility', label: '开发者只做两件事' },\n { id: 'integration-paths', label: '三种接入姿势' },\n ]},\n { id: 'quick-start', icon: Zap, label: '快速开始', children: [\n { id: 'overview', label: '概述' },\n { id: 'requirements', label: '系统要求' },\n { id: 'install', label: '安装方式' },\n { id: 'env-vars', label: '环境变量' },\n ]},\n { id: 'config', icon: Plug, label: '接入 · 直接用(零代码)', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: '扣子(Coze)' },\n { id: 'config-coze-workflow', label: 'Coze 工作流' },\n { id: 'config-ai-workspace', label: 'AI 工作台 · 豆包 / 飞书 / WorkBuddy / 钉钉' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: '其他 MCP 客户端' },\n ]},\n { id: 'config-code', icon: Code2, label: '接入 · 编程用(SDK / 代码)', children: [\n { id: 'code-mcp-sdk', label: '官方 MCP 客户端库' },\n { id: 'code-agent-frameworks', label: 'LangChain / Mastra / Agents SDK' },\n { id: 'code-function-calling', label: '直调 chat.completions · tools' },\n { id: 'code-selfhosted-agent', label: '自研后端 Agent' },\n ]},\n { id: 'eval-modes', icon: Radio, label: '评测模式', children: [\n { id: 'stream-eval', label: '实时录音评测' },\n { id: 'stream-flow', label: '流式评测流程' },\n { id: 'file-eval', label: '音频文件评测' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API 参考', children: [\n { id: 'tools-en', label: '英文评测工具' },\n { id: 'tools-cn', label: '中文评测工具' },\n { id: 'result-fields', label: '评测结果字段' },\n { id: 'error-codes', label: '错误码' },\n ]},\n { id: 'architecture', icon: Terminal, label: '架构说明', children: [\n { id: 'arch-diagram', label: '架构图' },\n { id: 'transport', label: '传输协议' },\n ]},\n { id: 'integration', icon: Code2, label: '示例代码', children: [\n { id: 'code-python', label: 'Python' },\n { id: 'code-javascript', label: 'JavaScript' },\n ]},\n { id: 'best-practices', icon: FileText, label: '最佳实践', children: [\n { id: 'prompt-templates', label: 'Prompt 模板' },\n { id: 'error-handling', label: '错误处理' },\n { id: 'performance', label: '性能优化' },\n ]},\n { id: 'service-info', icon: Globe, label: '服务信息', children: [\n { id: 'endpoints', label: '服务端点' },\n { id: 'limits', label: '服务限制' },\n { id: 'changelog', label: '更新日志' },\n ]},\n];\n\nconst NAV_EN: NavGroup[] = [\n { id: 'concept', icon: Workflow, label: 'How MCP works', children: [\n { id: 'why-mcp', label: 'Why MCP' },\n { id: 'scenario-walkthrough', label: 'Scenario · 6 steps' },\n { id: 'dev-responsibility', label: 'Two developer tasks' },\n { id: 'integration-paths', label: 'Three integration styles' },\n ]},\n { id: 'quick-start', icon: Zap, label: 'Quick start', children: [\n { id: 'overview', label: 'Overview' },\n { id: 'requirements', label: 'Requirements' },\n { id: 'install', label: 'Install' },\n { id: 'env-vars', label: 'Environment' },\n ]},\n { id: 'config', icon: Plug, label: 'Zero-code clients', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: 'Coze' },\n { id: 'config-coze-workflow', label: 'Coze workflows' },\n { id: 'config-ai-workspace', label: 'Enterprise AI workspaces' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: 'Other MCP clients' },\n ]},\n { id: 'config-code', icon: Code2, label: 'SDK / code integration', children: [\n { id: 'code-mcp-sdk', label: 'Official MCP SDK' },\n { id: 'code-agent-frameworks', label: 'Agent frameworks' },\n { id: 'code-function-calling', label: 'chat.completions + tools' },\n { id: 'code-selfhosted-agent', label: 'Custom backend' },\n ]},\n { id: 'eval-modes', icon: Radio, label: 'Evaluation modes', children: [\n { id: 'stream-eval', label: 'Streaming mic' },\n { id: 'stream-flow', label: 'Streaming flow' },\n { id: 'file-eval', label: 'Audio files' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API reference', children: [\n { id: 'tools-en', label: 'English tools' },\n { id: 'tools-cn', label: 'Chinese tools' },\n { id: 'result-fields', label: 'Result fields' },\n { id: 'error-codes', label: 'Errors' },\n ]},\n { id: 'architecture', icon: Terminal, label: 'Architecture', children: [\n { id: 'arch-diagram', label: 'Diagram' },\n { id: 'transport', label: 'Transports' },\n ]},\n { id: 'integration', icon: Code2, label: 'Sample code', children: [\n { id: 'code-python', label: 'Python' },\n { id: 'code-javascript', label: 'JavaScript' },\n ]},\n { id: 'best-practices', icon: FileText, label: 'Best practices', children: [\n { id: 'prompt-templates', label: 'Prompt templates' },\n { id: 'error-handling', label: 'Errors & retries' },\n { id: 'performance', label: 'Performance' },\n ]},\n { id: 'service-info', icon: Globe, label: 'Service info', children: [\n { id: 'endpoints', label: 'Endpoints' },\n { id: 'limits', label: 'Limits' },\n { id: 'changelog', label: 'Changelog' },\n ]},\n];\n\n/* ─── Page(英文 / 中文拆成两个组件,避免切换语言时 Hooks 数量变化导致白屏)─── */\n\nfunction DocsPageEn() {\n return (\n \n \n \n );\n}\n\nfunction DocsPageZh() {\n return (\n \n {/* ══════ MCP 工作原理 ══════ */}\n \n\n \n

\n 大模型(GPT / Claude / Gemini / 通义千问 等)本质上是文字大脑:它擅长读和写,但天生听不到音频、打不开你的数据库、调不通第三方 API。\n

\n

\n MCP(Model Context Protocol)是一套由 Anthropic 主导、业界共同推进的开放协议,它像一根\"对讲机\":让大模型可以在需要时主动去调用外部能力(工具、数据源、服务),然后把结果接回来继续对话。\n

\n
\n
\n
\n \n 没有 MCP 的做法\n
\n
    \n
  • · 研究评测服务的 REST 文档
  • \n
  • · 自己写鉴权 / 上传 / 轮询代码
  • \n
  • · 把结果序列化后塞进 prompt
  • \n
  • · 每换一个大模型都得重写一遍
  • \n
\n
\n
\n
\n \n 用驰声 MCP 之后\n
\n
    \n
  • · 填一行 MCP Server 地址
  • \n
  • · 大模型自动发现&调用评测工具
  • \n
  • · 换任何支持 MCP 的大模型都能用
  • \n
  • · 不写一行调用代码
  • \n
\n
\n
\n \n MCP 让\"接入语音评测\"从一个\"后端工程\"变成了一个\"配置项\"。这也是为什么 Cursor、Claude Desktop、Dify、Coze、字节豆包、飞书智能助手都已经原生支持 MCP。\n \n
\n\n \n

\n 想象一个具体场景:一位开发者用 Claude 做了一款 「AI 雅思口语陪练」小程序,接入驰声语音评测 MCP。当用户发来一段录音,整个链路是这样的:\n

\n
\n \n

配置阶段(开发者 · 一次性)

\n

在 AI 后端的配置文件里填一行驰声 MCP Server 地址。大模型启动时自动发现:「我多了一个叫语音评测的工具」。

\n
\n \n

接收用户指令(终端用户)

\n

小程序用户发来一段自我介绍录音:「帮我听听,发音哪里有问题?」后端把「文字 + 录音链接」打包给大模型。

\n
\n \n

大模型自主思考(LLM · 最核心的魔法)

\n
\n 「用户让我听发音。」
\n 「但我只是文字大脑,我听不到。」
\n 「等等 —— 开发者给了我一个叫 chivox_voice_eval 的 MCP 工具!」\n
\n
\n \n

MCP 协议 · 自动调用(LLM → 驰声)

\n

大模型自动按 MCP 标准构造 tools/call 请求,把录音链接和参考文本发到驰声服务。开发者不需要写任何调用代码。

\n
\n \n

驰声服务处理(评测引擎)

\n

驰声对音频进行考试级打分,把结构化结果通过 MCP 原路返回:overall 85、/θ/ 音发音错误、流利度 88。

\n
\n \n

大模型整合并输出反馈(LLM)

\n

大模型把冷冰冰的分数翻译成温柔反馈:

\n
\n 「你的自我介绍很棒!综合 85 分 🎉 不过 think 这个词的 /θ/ 咬舌音不太标准,我们一起来练一下……」\n
\n
\n
\n \n 整条链路里,MCP 只出现在 ① 和 ④:① 让开发者一次性告诉大模型「你多了一个工具」,④ 让大模型可以自动调用它。这两步的标准化,就是 MCP 的全部价值。\n \n
\n\n \n

听起来复杂,但对开发者来说只需要两件事:

\n
\n
\n
\n 1\n 填一次 MCP 配置\n
\n

\n 在 AI 后端的配置里填入驰声 MCP Server 地址和 API Key,就这一次,以后新加评测能力完全免开发。\n

\n {`{\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"apiKey\": \"sk-••••••••••\"\n }\n}`}\n
\n
\n
\n 2\n 写一段 System Prompt\n
\n

\n 告诉大模型这个工具是做什么的、什么时候调用、结果怎么转成用户友好的反馈。\n

\n {`你是一位英语口语教练。\n当用户发来录音时:\n1. 调用 chivox_voice_eval 评分\n2. 聚焦 <70 分的音素家族\n3. 用高情商话术给出练习建议`}\n
\n
\n

\n 其余所有事情 —— 音频上传、鉴权、工具发现、调用时机、返回格式、结果整合 —— 都由 MCP 协议和大模型自己搞定。\n

\n
\n\n \n

根据你的技术栈,有三种等价的接入方式,底层都走完全相同的 MCP 协议:

\n\n {/* ── 姿势一:可视化 ── */}\n
\n
\n \n

姿势一 · 可视化拖拽(扣子 / Coze / 飞书智能助手)

\n
\n

\n 适合产品经理、运营、不写后端代码的开发者。整个过程像在手机上装 App。\n

\n
    \n
  1. 找到入口:在扣子平台的 「插件 / 工具」 配置区,点击「添加 MCP 服务」。
  2. \n
  3. 填两个字段(这也是你未来会从驰声这边拿到的):\n
    \n \n \n \n \n \n
    服务器地址https://speech-eval.site/mcp
    鉴权密钥sk-•••••••••• (由驰声分配,用于计费与识别)
    \n
    \n
  4. \n
  5. 平台自动发现能力:扣子会访问你填的地址,读取 MCP Server 自描述的\"说明书\"。瞬间明白:「这是个语音评测工具,需要传音频,会返发音分」。
  6. \n
  7. 右侧测试:在平台的聊天框里发一段语音,大模型就会自动调用工具。整个过程不需要写一行代码。
  8. \n
\n
\n\n {/* ── 姿势二:代码框架 ── */}\n
\n
\n \n

姿势二 · 代码框架配置(Dify / LangChain / 自研后端)

\n
\n

\n 适合做独立 APP / 小程序、用 Dify 或 LangChain 写 Agent 的极客开发者。核心就是往配置文件里加一段 JSON。\n

\n
    \n
  1. 打开配置文件(项目根目录下的 mcp.json 或框架指定的配置路径)。
  2. \n
  3. 在 mcpServers 下增加一个节点:\n {`{\n \"mcpServers\": {\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"env\": {\n \"API_KEY\": \"你的专属密钥\"\n }\n }\n }\n}`}\n
  4. \n
  5. 重启后端服务。大模型的底层调度器会在启动时自动连上驰声 MCP Server,把 16 种评测工具注册成随时待命的 tools。
  6. \n
  7. 触发调用:用户发来录音后,大模型看到 system prompt 的引导,自动选择合适的工具(单词/句子/段落/半开放)调用。
  8. \n
\n
\n\n {/* ── 姿势三:Function Calling 直连(分 A / B 两种做法) ── */}\n
\n
\n \n

姿势三 · 原生 Function Calling(豆包 / DeepSeek / OpenAI 兼容 API)

\n
\n

\n 适合不用任何 Agent 框架、直接调用 LLM API 的后端开发者。豆包 1.5+ / DeepSeek / GPT / Qwen 等模型都走标准 chat.completions 的 tools 参数。这里又分 A / B 两种做法,B 才是生产推荐。\n

\n\n \n 常见疑问:\"要不要手写一个 tool 定义?\"
\n — 姿势一 / 二不用(Coze、Dify、火山方舟控制台、Claude Desktop 会自动从 MCP Server 拉工具列表)。
\n — 姿势三看你选 A 还是 B:A 要手写,B 用 MCP 客户端库自动拉。\n
\n\n {/* ── 3-A:手写 tool schema ── */}\n
\n
\n

3-A · 手写 tool schema(最快验证,不推荐生产)

\n 快速 Demo\n
\n

\n 自己写一段 JSON Schema 告诉豆包\"有个工具叫 xxx,参数长这样\",豆包返回 tool_call 后你再手动去调驰声 MCP。缺点:驰声有 16 个评测工具,你每加一个题型都要改代码。\n

\n {`import os, json\nfrom openai import OpenAI\n\nclient = OpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv('ARK_API_KEY'),\n)\n\n# ─── 手写一段 tool schema(不推荐:16 个工具就要写 16 段)───\ntools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": \"en_word_eval\",\n \"description\": \"英语单词发音评测。当用户让你评价英语发音并提供录音链接时调用。\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"audio_url\": {\"type\": \"string\", \"description\": \"录音 URL\"},\n \"reference_text\": {\"type\": \"string\", \"description\": \"参考文本,如 Apple\"},\n },\n \"required\": [\"audio_url\", \"reference_text\"]\n }\n }\n}]\n\nresp = client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,拿到评测结果后温柔地反馈,不要直接报分数。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n)\n\nmsg = resp.choices[0].message\nif msg.tool_calls:\n args = json.loads(msg.tool_calls[0].function.arguments)\n # ↓↓↓ 这里手动调驰声 MCP,再把结果回填给豆包做第二趟 ↓↓↓\n # result = requests.post(\"https://speech-eval.site/mcp\", json={...})`}\n
\n\n {/* ── 3-B:MCP 自动发现 ── */}\n
\n
\n

\n 3-B · 用 MCP 客户端库自动发现 \n

\n 生产推荐\n
\n

\n 启动时连上驰声 MCP Server,调一次 tools/list,把 16 个评测工具自动转成 Function Calling 的 tools 格式。驰声加新工具,你代码不用改。这才是 MCP 协议的真正价值。\n

\n {`import asyncio, os\nfrom openai import AsyncOpenAI\nfrom mcp import ClientSession\nfrom mcp.client.streamable_http import streamablehttp_client\n\nclient = AsyncOpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv(\"ARK_API_KEY\"),\n)\n\nasync def main():\n # ─── 1. 连驰声 MCP Server,自动拉取全部 16 个工具 ───\n async with streamablehttp_client(\n \"https://speech-eval.site/mcp\",\n headers={\"Authorization\": f\"Bearer {os.getenv('CHIVOX_KEY')}\"},\n ) as (read, write, _):\n async with ClientSession(read, write) as session:\n await session.initialize()\n mcp_tools = (await session.list_tools()).tools # ← 一行拿到全部工具\n\n # ─── 2. MCP schema → OpenAI Function Calling schema ───\n tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema, # MCP 直接给 JSON Schema\n }\n } for t in mcp_tools]\n\n # ─── 3. 正常调豆包,tools 由 MCP 动态注入 ───\n resp = await client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,收到评测结果后温柔反馈。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n )\n\n # ─── 4. 折返跑:豆包选好工具后,直接走 MCP 调驰声 ───\n msg = resp.choices[0].message\n if msg.tool_calls:\n call = msg.tool_calls[0]\n result = await session.call_tool(\n call.function.name,\n arguments=__import__(\"json\").loads(call.function.arguments),\n )\n # 把 result 回填给豆包做第二趟 chat.completions 即可\n\nasyncio.run(main())`}\n

\n 想要更省心?直接用 官方 mcp python sdk、mcp-use、openai-agents,或火山官方 Arkitect 高代码 SDK,它们都把上面这段\"MCP → Function Calling\"的桥接封装好了。\n

\n
\n
\n\n \n 三种姿势走的是完全相同的 MCP 协议,能力完全等价。选型建议:产品经理 / 原型验证用姿势一(Coze 填表单);AI 客户端用户用姿势二(Cursor / Claude Desktop 填 mcp.json);后端生产服务用姿势三-B(MCP 客户端库自动发现工具,不要手写 tool schema)。\n \n
\n\n
\n\n {/* ══════ 快速开始 ══════ */}\n \n\n \n

chivox-local-mcp 是驰声语音评测的 MCP 本地代理,通过 Model Context Protocol 将远程驰声评测服务桥接到本地,让 AI 助手(Claude Desktop、Claude Code、Cursor 等)直接调用语音评测能力。

\n

它支持两种评测模式,覆盖从即时交互到批量处理的全部场景:

\n
\n
\n
\n \n 实时录音评测\n
\n

通过麦克风边录边评,音频以 WebSocket 流式推送,无需生成中间文件,延迟更低、体验更佳。

\n
\n
\n
\n \n 音频文件评测\n
\n

支持本地文件路径、Base64 编码、URL 三种输入,适合已有音频的批量评测场景。

\n
\n
\n 当前支持 16 种评测工具:英文 10 种(单词、句子、段落、纠音、自然拼读、口语选择、半开放题等)+ 中文 6 种(汉字、拼音、词句、段落、有限分支、AI Talk)。\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n
依赖版本说明
Node.js{'>'}= 18运行时必须
SoXany仅实时录音功能需要(处理麦克风音频流)
\n
\n

安装 SoX(仅在使用实时录音时需要):

\n {`# macOS\nbrew install sox\n\n# Ubuntu / Debian\nsudo apt-get install sox`}\n
\n\n \n

方式一:npm 全局安装(推荐)

\n {`npm install -g chivox-local-mcp`}\n\n

方式二:npx 免安装运行

\n {`MCP_REMOTE_URL=http://your-server:8080 npx chivox-local-mcp`}\n\n

方式三:从源码构建

\n {`git clone https://git.chivox.com/CLOUD_DEV/cvx_local_mcp.git\ncd cvx_local_mcp\nbash scripts/build.sh`}\n
\n\n \n \n \n
\n\n {/* ══════ 接入 · 直接用(零代码) ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 不用写代码、不用装 SDK,只在客户端的「MCP 配置」或「扩展」里填一段 JSON / URL
  • \n
  • 保存后 LLM 自动发现 16 个评测工具,并在对话 / Agent 中自主调用
  • \n
  • 覆盖 IDE 编程助手、桌面 AI 客户端、企业 AI 工作台、可视化 Bot / 工作流平台四大生态
  • \n
\n
\n\n\n \n
    \n
  1. 打开 Cursor 设置(Cmd + ,)
  2. \n
  3. 左侧选择 MCP(或搜索 "MCP")
  4. \n
  5. 点击 Add new MCP server
  6. \n
  7. 填写配置并保存:
  8. \n
\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n}`}\n Cursor 使用远程 Streamable HTTP 模式直连,无需安装本地代理。如需实时录音功能,请使用下方 Claude Desktop 的本地代理配置。\n
\n\n \n

编辑配置文件(macOS:~/Library/Application Support/Claude/claude_desktop_config.json):

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"chivox-local-mcp\",\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\",\n \"MCP_API_KEY\": \"your-api-key\"\n }\n }\n }\n}`}\n

如果是从源码构建:

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/cvx_local_mcp/dist/index.js\"],\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\"\n }\n }\n }\n}`}\n Claude Desktop 使用本地代理模式(stdio),支持实时录音评测。本地代理会自动桥接远程服务。\n
\n\n \n {`# npm 全局安装后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 chivox-local-mcp\n\n# 源码构建后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 node /path/to/cvx_local_mcp/dist/index.js`}\n \n\n \n

除了 Cursor 和 Claude Code,主流的 AI 编程 IDE 都原生支持 MCP。以下客户端使用完全一致的 Streamable HTTP 配置,区别只在配置入口:

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
客户端配置入口备注
Windsurf (Codeium)Settings → Cascade → MCP Servers直接贴下方 JSON
Zed~/.config/zed/settings.json 的 context_serversAssistant Panel 自动发现
Continue (VS Code / JetBrains)config.yaml 的 mcpServersv0.9+ 支持
通义灵码 / CodeGeeX / 文心快码插件设置 → MCP 服务2026 Q1 起陆续支持
Cline (原 Claude Dev)MCP Servers 面板 → 编辑配置VS Code 扩展
\n
\n {`{\n \"mcpServers\": {\n \"chivox-speech-eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n }\n }\n}`}\n 所有 IDE 类客户端都走远程 Streamable HTTP,零本地依赖。需要实时录音才需切到 Claude Desktop 的本地代理模式。\n
\n\n \n

扣子(Coze)是字节跳动推出的 AI 应用开发平台,支持通过 MCP 扩展为 Agent 赋予外部工具能力。接入驰声语音评测后,你可以构建口语练习 Bot、发音诊断助手等应用。

\n

方式一:扣子空间 MCP 扩展(推荐)

\n
    \n
  1. 打开 扣子空间(space.coze.cn)
  2. \n
  3. 在对话框下方点击 「添加扩展」
  4. \n
  5. 选择 「自定义」 标签,点击添加新的 MCP 服务
  6. \n
  7. 填入以下配置信息:
  8. \n
\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
名称chivox-speech-eval
传输类型streamable-http
URLhttps://speech-eval.site/mcp
\n
\n
    \n
  1. 保存后,在对话中输入 「帮我评测这段英文发音」 即可触发 Agent 调用
  2. \n
\n 添加 MCP 扩展后,扣子空间的 Agent 会自动识别并调用评测工具。你可以在 Agent 的思考过程中看到具体的工具调用细节。\n\n

方式二:在 Coze 开发平台的 Bot 中使用

\n
    \n
  1. 进入 Coze 开发平台,创建或编辑 Bot
  2. \n
  3. 在 Bot 的 「插件」 或 「工具」 面板中,添加 MCP 工具
  4. \n
  5. 选择 Streamable HTTP 类型,填入 URL:https://speech-eval.site/mcp
  6. \n
  7. Bot 将自动发现所有可用的评测工具(如 evaluate_english_word 等)
  8. \n
  9. 在 Bot 的人设提示词中,添加语音评测相关的引导语
  10. \n
\n {`你是一位专业的英语口语教练。当用户上传音频并请求评测时:\n1. 使用 evaluate_english_word / evaluate_english_sentence 等工具进行评测\n2. 根据评测结果(overall、accuracy、fluency 等分数)给出专业分析\n3. 针对得分较低的维度提供具体改进建议\n4. 鼓励用户持续练习`}\n
\n\n \n

如果你需要在 Coze 工作流中集成语音评测能力,可以通过 HTTP Request 节点调用评测 API:

\n\n

步骤 1:上传音频

\n

在工作流中添加一个 HTTP Request 节点,配置如下:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
配置项值
方法POST
URLhttps://speech-eval.site/upload
Content-Typeaudio/mp3
Body音频文件二进制数据
\n
\n

响应中获取 {'{{audioId}}'},传递给下一步。

\n\n

步骤 2:调用评测

\n

添加第二个 HTTP Request 节点,通过 MCP 接口调用评测工具:

\n {`{\n \"jsonrpc\": \"2.0\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"evaluate_english_sentence\",\n \"arguments\": {\n \"audioId\": \"{{audioId}}\",\n \"sentence\": \"{{ref_text}}\"\n }\n },\n \"id\": 1\n}`}\n\n

步骤 3:处理结果

\n

评测结果通过 JSON 格式返回,可使用 Coze 的 代码节点 或 LLM 节点 对结果进行解析和二次处理(如生成学习建议、计算进步趋势等)。

\n\n 工作流方式适合需要固定流程的场景(如批量评测、定时任务、与其他系统联动)。如果是交互式场景,推荐使用上方的 MCP 扩展方式,Agent 会自动选择合适的工具。\n\n
\n

完整工作流示意

\n
\n 用户输入音频\n →\n HTTP: 上传音频\n →\n HTTP: 调用评测\n →\n LLM: 分析结果\n →\n 输出反馈\n
\n
\n
\n\n \n

这一类是面向「上班族」的企业 / 日常 AI 助手,产品形态是个聊天框 + 插件市场 / 扩展面板。接入后,员工在 App 里打字「帮我评一下这段录音」就能自动触发驰声评测,不用写任何代码。

\n\n
\n
\n

豆包(Doubao)App / 桌面版

\n

字节跳动官方 AI 助手,2026 年起桌面版支持 MCP 扩展。

\n
    \n
  1. 桌面版设置 → 「智能体扩展」 → 添加 MCP 服务
  2. \n
  3. 类型选 streamable-http,URL 填 https://speech-eval.site/mcp
  4. \n
  5. 对话中直接说「帮我评测」即可自动调用
  6. \n
\n
\n\n
\n

飞书智能伙伴(My AI)

\n

飞书企业 AI,支持以 MCP / Function Calling 挂载外部工具给团队 Bot。

\n
    \n
  1. 飞书开发者后台 → 创建应用 → 「AI 能力 / 智能伙伴」
  2. \n
  3. 在「工具」中选 外部 MCP 服务,填入上方 URL
  4. \n
  5. 把智能伙伴拉进群聊,@ 它提交音频即可评测
  6. \n
\n
\n\n
\n

WorkBuddy / 企业智能助手

\n

字节 WorkBuddy、腾讯会议 AI、企业微信智能助手等企业 AI 工作台场景。

\n
    \n
  1. 在工作台的「技能 / 扩展」后台新增一个 MCP 连接器
  2. \n
  3. 传输协议选 Streamable HTTP,地址填 https://speech-eval.site/mcp
  4. \n
  5. 把技能发布到指定部门 / 群组,HR、培训、销售口语陪练场景即可直接用
  6. \n
\n
\n\n
\n

钉钉 AI 助理 / 通义千问 App

\n

阿里生态:钉钉 AI 助理支持自定义插件,通义 App 可通过「AI 工具箱」挂载 MCP。

\n
    \n
  1. 钉钉开发者后台 → AI 助理 → 「插件开发 / MCP 接入」
  2. \n
  3. 选 HTTP Streamable,填入驰声 MCP URL 并开启鉴权(可选)
  4. \n
  5. 在钉钉群 @AI 助理上传音频,自动返回评测卡片
  6. \n
\n
\n
\n\n 典型场景 · 小龙虾们的共同剧本:销售口语陪练 → 外语培训 → 主持 / 播音岗位考核 → K12 英语作业批改 → 客服话术复盘。这些「上班族 AI 工作台」接入驰声 MCP 后,员工 / 学员只要对着话筒说话,AI 就能自动打分并给出个性化改进建议,运营 / 培训 / 教研团队零开发即可上线。\n
\n\n \n

如果你需要把语音评测编排进多步业务流(例如:学员录音 → 评测 → 生成错题集 → 推送到 CRM),可视化工作流平台比聊天 Bot 更合适。

\n\n
\n
\n

Dify

\n

开源 LLMOps,v0.15+ 原生 MCP 工具。

\n
    \n
  • 「工具」→「自定义 MCP」→ 填 URL
  • \n
  • 在 Chatflow / Workflow 节点里直接拖用
  • \n
\n
\n
\n

n8n

\n

工作流自动化,用 MCP Client 节点。

\n
    \n
  • 添加 MCP Client 节点
  • \n
  • Transport 选 HTTP Stream,URL 贴驰声地址
  • \n
  • Tool 下拉自动列出 16 个评测能力
  • \n
\n
\n
\n

Flowise / LangFlow

\n

可视化 LangChain Agent 编排。

\n
    \n
  • 拖出 MCP Tool 节点
  • \n
  • 连到 AgentExecutor 即可
  • \n
\n
\n
\n\n 可视化平台的好处是流程可追溯、可回放,适合教育机构 / 培训部门做批量评测 + 报表导出;缺点是单步延迟略高于直接 MCP 调用,对延迟敏感的交互场景建议用 Cursor / Claude Desktop 直连。\n
\n\n \n

任何遵循 MCP 协议的客户端都可以接入,统一使用以下配置:

\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
传输类型streamable-http
URLhttps://speech-eval.site/mcp
鉴权(可选)Header:Authorization: Bearer <MCP_API_KEY>
\n
\n

还没找到你用的客户端?任何支持 Model Context Protocol 的终端都通用。找不到入口?下一小节「编程用 MCP」里用 SDK 直接接即可。

\n
\n
\n\n {/* ══════ 接入 · 编程用 MCP ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 你在写一段真正的后端服务:一个 Agent Worker、一个 API、一个自动化脚本
  • \n
  • 业务里的「语音评测」是其中一个步骤,需要由代码 决定何时调用、如何解析结果
  • \n
  • 三种主流写法:① 官方 MCP 客户端库 → ② Agent 框架自动桥接 → ③ 退化到 chat.completions + tools 参数
  • \n
\n

💡 强烈推荐①或②:驰声有 16 个评测工具,让 MCP 自动注入 tool schema,每新增一个题型不用改一行业务代码。

\n
\n\n \n

最底层、也最推荐的方式。由 Anthropic 官方维护,一次连接自动拿到全部工具的 JSON Schema,然后交给任意 LLM。

\n\n

Python:mcp

\n {`# pip install mcp openai\nimport asyncio, os\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nMCP_URL = \"https://speech-eval.site/mcp\"\nllm = OpenAI(api_key=os.getenv(\"DOUBAO_KEY\"),\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\") # 豆包 / DeepSeek / OpenAI 同构\n\nasync def main(audio_id: str, ref: str):\n async with streamablehttp_client(MCP_URL) as (reader, writer, _):\n async with ClientSession(reader, writer) as sess:\n await sess.initialize()\n\n tools = await sess.list_tools()\n openai_tools = [{\n \"type\": \"function\",\n \"function\": {\"name\": t.name, \"description\": t.description,\n \"parameters\": t.inputSchema},\n } for t in tools.tools]\n\n resp = llm.chat.completions.create(\n model=\"doubao-1-5-pro-32k\",\n messages=[{\"role\": \"user\",\n \"content\": f\"帮我评测 audioId={audio_id},参考文本:{ref}\"}],\n tools=openai_tools,\n )\n\n for call in resp.choices[0].message.tool_calls or []:\n result = await sess.call_tool(call.function.name,\n arguments=eval(call.function.arguments))\n print(call.function.name, \"→\", result.content[0].text[:200])\n\nasyncio.run(main(\"abc123\", \"I think therefore I am\"))`}\n\n

TypeScript / Node.js:@modelcontextprotocol/sdk

\n {`// npm i @modelcontextprotocol/sdk openai\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport OpenAI from \"openai\";\n\nconst mcp = new Client({ name: \"chivox-biz\", version: \"1.0.0\" });\nawait mcp.connect(new StreamableHTTPClientTransport(new URL(\"https://speech-eval.site/mcp\")));\n\nconst { tools } = await mcp.listTools();\nconst openai = new OpenAI({ apiKey: process.env.DEEPSEEK_KEY, baseURL: \"https://api.deepseek.com\" });\n\nconst resp = await openai.chat.completions.create({\n model: \"deepseek-chat\",\n messages: [{ role: \"user\", content: \"评测 audioId=abc123, 参考 I think therefore I am\" }],\n tools: tools.map(t => ({ type: \"function\", function: {\n name: t.name, description: t.description, parameters: t.inputSchema\n }})),\n});\n\nfor (const call of resp.choices[0].message.tool_calls ?? []) {\n const r = await mcp.callTool({ name: call.function.name,\n arguments: JSON.parse(call.function.arguments) });\n console.log(call.function.name, r.content);\n}`}\n 这种写法 LLM 供应商可换(豆包 / DeepSeek / GPT / Qwen / Moonshot),工具自动更新(驰声新增题型无需改业务代码),适合生产后端。\n
\n\n \n

如果项目已经在用 Agent 框架,几行 adapter 就能把驰声 MCP 塞进去,框架本身会接管 tool-calling 循环、重试、日志。

\n\n
\n
\n

LangChain / LangGraph(Python)

\n {`# pip install langchain-mcp-adapters langgraph\nfrom langchain_mcp_adapters.client import MultiServerMCPClient\nfrom langgraph.prebuilt import create_react_agent\n\nclient = MultiServerMCPClient({\n \"chivox\": {\n \"transport\": \"streamable_http\",\n \"url\": \"https://speech-eval.site/mcp\",\n }\n})\ntools = await client.get_tools()\n\nagent = create_react_agent(\"openai:gpt-4o-mini\", tools)\nresult = await agent.ainvoke({\"messages\":\n [(\"user\", \"评测 audioId=abc123 参考 think\")]})\nprint(result[\"messages\"][-1].content)`}\n
\n\n
\n

Mastra(TypeScript)

\n {`// npm i @mastra/core @mastra/mcp\nimport { MCPClient } from \"@mastra/mcp\";\nimport { Agent } from \"@mastra/core/agent\";\nimport { openai } from \"@ai-sdk/openai\";\n\nconst mcp = new MCPClient({ servers: {\n chivox: { url: new URL(\"https://speech-eval.site/mcp\") }\n}});\n\nexport const speechCoach = new Agent({\n name: \"speech-coach\",\n instructions: \"你是口语教练,用 chivox 工具评测并给改进建议。\",\n model: openai(\"gpt-4o-mini\"),\n tools: await mcp.getTools(),\n});`}\n
\n\n
\n

OpenAI Agents SDK(Python)

\n {`# pip install openai-agents\nfrom agents import Agent, Runner\nfrom agents.mcp import MCPServerStreamableHttp\n\nchivox = MCPServerStreamableHttp(\n params={\"url\": \"https://speech-eval.site/mcp\"},\n name=\"chivox-speech-eval\",\n)\n\nasync with chivox:\n agent = Agent(name=\"coach\",\n instructions=\"专业口语教练\",\n mcp_servers=[chivox])\n r = await Runner.run(agent, \"评测 audioId=abc123\")\n print(r.final_output)`}\n
\n\n
\n

LlamaIndex / AutoGen / CrewAI

\n

这些框架都有官方或社区 MCP adapter,用法与上述类似:

\n
    \n
  • LlamaIndex:llama-index-tools-mcp
  • \n
  • AutoGen:autogen-ext[mcp]
  • \n
  • CrewAI:crewai-tools 的 MCPServerAdapter
  • \n
  • Spring AI(Java):spring-ai-mcp-client
  • \n
\n
\n
\n
\n\n \n

当你用的 LLM SDK 还没有原生 MCP 支持(比如老版本的火山方舟 / 百度千帆 / 通义 DashScope),退化方案是:用 MCP 客户端一次性拉到 tool schema,然后按 OpenAI Function Calling 格式喂给 LLM。

\n {`# 适用:豆包(火山方舟)/ DeepSeek / Qwen / Moonshot / GLM 等 OpenAI 兼容 API\n# 核心思路:MCP 列工具 → 转 OpenAI tools → LLM 决策 → MCP 执行 → 回填\n\nasync with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n\n # ① 用 MCP 拉到的 schema 自动转 OpenAI 格式\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 喂给豆包\n messages = [{\"role\": \"user\", \"content\": \"评测一下 audioId=abc123\"}]\n resp = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages, tools=oa_tools,\n )\n\n # ③ LLM 回 tool_calls → 折返跑到 MCP 执行\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for c in msg.tool_calls:\n result = await mcp.call_tool(\n c.function.name, arguments=json.loads(c.function.arguments))\n messages.append({\"role\": \"tool\", \"tool_call_id\": c.id,\n \"content\": result.content[0].text})\n # ④ 再喂一轮,让豆包根据评测结果产出自然语言诊断\n final = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages)\n print(final.choices[0].message.content)`}\n 千万别手写 tool schema!驰声 16 个评测工具每个都有几十个字段,手写既容易错也难维护。一定用 MCP list_tools() 动态拿。\n
\n\n \n

大部分落地场景其实是:你已有一个业务后端(教育 SaaS / 培训系统 / 客服平台),只需要新增一个「语音评测」能力。推荐架构:

\n\n
\n
\n 前端录音 / 上传\n →\n 业务后端\n →\n MCP Client(常驻连接)\n →\n 驰声 MCP\n ↘\n LLM(诊断 / 出题)\n
\n
\n\n

FastAPI 示例(生产最小骨架)

\n {`from fastapi import FastAPI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\nfrom contextlib import asynccontextmanager\n\nmcp_session: ClientSession | None = None\n\n@asynccontextmanager\nasync def lifespan(app):\n global mcp_session\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as s:\n await s.initialize()\n mcp_session = s\n yield\n mcp_session = None\n\napp = FastAPI(lifespan=lifespan)\n\n@app.post(\"/api/evaluate\")\nasync def evaluate(audio_id: str, ref_text: str):\n # 直接选一个最合适的工具执行(不经 LLM,延迟最低)\n r = await mcp_session.call_tool(\"evaluate_english_sentence\",\n {\"audioId\": audio_id, \"sentence\": ref_text})\n return {\"result\": r.content[0].text}`}\n\n 关键优化:① MCP 连接在 lifespan 里做成长连接,不要每次请求都重连;② 对延迟敏感的场景可以「跳过 LLM 直接调 tool」,把 LLM 放到「生成诊断报告」那一步。\n
\n\n
\n

方案选型速查

\n
\n \n \n \n \n \n \n \n \n \n \n \n
场景推荐方案
AI 对话 / Copilot 类产品,LLM 供应商可能会换① 官方 MCP 客户端库
已有 LangChain / Mastra / Agents SDK 技术栈② Agent 框架 + adapter
火山方舟 / 千帆控制台直连,最小侵入③ chat.completions + tools
教育 SaaS / 培训 / 客服等业务后端集成④ 自研后端 Agent
\n
\n
\n
\n\n {/* ══════ 评测模式 ══════ */}\n \n\n \n

通过本地麦克风实时录音,音频以 WebSocket 流式推送到评测服务,无需生成中间文件。这是最灵活、延迟最低的评测方式,特别适合交互式口语练习场景。

\n 实时录音评测需要安装 SoX 并使用本地代理模式(Claude Desktop / Claude Code)。Cursor 等远程直连模式暂不支持实时录音。\n\n

需要按顺序调用三个工具:

\n\n
\n
\n

create_stream_session — 创建流式评测会话

\n \n

返回 session_id,后续步骤需使用。

\n
\n\n
\n

start_recording — 开始麦克风录音

\n \n

调用后自动启动麦克风,音频通过 WebSocket 实时推送到评测服务。

\n
\n\n
\n

stop_recording — 停止录音并获取结果

\n \n
\n
\n
\n\n \n
\n \n

用户:"请评测我的英文发音,文本是 Hello"

\n

AI 调用 create_stream_session(core_type="en.word.score", ref_text="Hello")

\n

→ 获得 session_id

\n
\n \n

AI 调用 start_recording(session_id=xxx)

\n

麦克风开始录音,音频通过 WebSocket 实时推送到评测服务

\n
\n \n

用户说完后告知 AI "结束"

\n

AI 调用 stop_recording(session_id=xxx)

\n

→ 返回评测结果(总分、准确度、流利度、音素得分等)

\n
\n
\n
\n\n \n

适用于已有音频文件的评测场景,支持三种输入方式:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
参数说明适用场景
audio_file_path本地文件路径代理自动读取并转为 Base64,最便捷
audio_base64Base64 编码数据已有编码数据时使用
audio_url音频文件 URL音频托管在云存储时使用
\n
\n 推荐使用 audio_file_path,只需传入本地文件路径,代理会自动处理编码和上传。\n

支持的音频格式:mp3, wav, ogg, m4a, aac, pcm

\n

限制:单文件最大 50MB,大于 500KB 的文件自动压缩为 16kHz / 单声道 / 32kbps。

\n
\n
\n\n {/* ══════ API 参考 ══════ */}\n \n\n \n \n\n

通用参数:所有英文评测工具均支持以下参数。

\n \n
\n\n \n \n\n

通用参数:

\n \n
\n\n \n

所有评测工具返回统一的结构化结果:

\n {`{\n \"overall\": 85,\n \"accuracy\": 82,\n \"pron\": 88,\n \"fluency\": {\n \"overall\": 78,\n \"speed\": 65,\n \"pause\": 2\n },\n \"integrity\": 95,\n \"details\": [\n {\n \"char\": \"hello\",\n \"score\": 85,\n \"phone\": [\n { \"phoneme\": \"h\", \"score\": 90 },\n { \"phoneme\": \"ɛ\", \"score\": 82 },\n { \"phoneme\": \"l\", \"score\": 88 },\n { \"phoneme\": \"oʊ\", \"score\": 80 }\n ]\n }\n ]\n}`}\n
\n \n \n \n \n \n \n \n {[\n ['overall', '0–100', '综合总分,反映整体语音质量'],\n ['accuracy', '0–100', '准确度,音素级别的发音准确率'],\n ['pron', '0–100', '发音得分,整体发音质量评价'],\n ['fluency.overall', '0–100', '流利度,语流的自然度与平滑度'],\n ['fluency.speed', '0–100', '语速得分,每分钟词/音节计量'],\n ['fluency.pause', 'number', '不自然停顿次数'],\n ['integrity', '0–100', '完整度,是否完整朗读了参考文本'],\n ['details[].phone[]', 'array', '每个音素的独立评分,可定位具体弱项'],\n ['details[].stress[]', 'array', '重音得分,检测重弱读是否正确'],\n ].map(([field, range, desc]) => (\n \n \n \n \n \n ))}\n \n
字段范围说明
{field}{range}{desc}
\n
\n
\n\n \n
\n \n \n \n \n \n \n \n {[\n ['音频 ID 无效或已过期', '音频上传后 5 分钟内有效,评测完成后自动删除', '重新上传音频'],\n ['服务器繁忙', '当前请求过多,排队已满', '稍后重试,使用指数退避策略'],\n ['存储空间已满', '服务器临时音频存储已满', '稍后重试,系统会自动清理'],\n ['音频格式不支持', '上传了不支持的文件类型', '使用 mp3/wav/ogg/m4a/aac/pcm'],\n ['音频时长超限', '超过该题型最大时长限制', '裁剪音频后重试'],\n ['WebSocket 连接断开', '网络不稳定导致流式连接中断', '代理会自动重连,如持续失败请检查网络'],\n ].map(([scene, reason, fix]) => (\n \n \n \n \n \n ))}\n \n
场景原因解决方式
{scene}{reason}{fix}
\n
\n
\n
\n\n {/* ══════ 架构说明 ══════ */}\n \n\n \n
\n
\n

AI 客户端

\n

Claude Desktop
Claude Code
Cursor

\n
\n
\n

⇄

\n

stdio

\n
\n
\n

chivox-local-mcp

\n

本地代理
SoX 录音

\n
\n
\n

⇄

\n

HTTP / WS

\n
\n
\n

Remote Chivox

\n

MCP Server
评测引擎

\n
\n
\n
\n\n \n
    \n
  • \n \n stdio — AI 客户端通过标准输入输出与本地代理通信,这是 MCP 的标准传输方式\n
  • \n
  • \n \n HTTP — 音频文件评测工具通过 HTTP 代理到远程服务,适用于非流式场景\n
  • \n
  • \n \n WebSocket — 实时录音音频通过 WebSocket 流式推送,支持断线自动重连\n
  • \n
\n
\n
\n\n {/* ══════ 示例代码 ══════ */}\n \n\n \n {`import requests\n\nwith open('audio.mp3', 'rb') as f:\n r = requests.post(\n 'https://speech-eval.site/upload',\n data=f,\n headers={'Content-Type': 'audio/mp3'}\n )\n\nresult = r.json()\nprint(f\"audioId: {result['audioId']}\")\nprint(f\"size: {result['size']} bytes\")\nprint(f\"expires: {result['expiresIn']}\")`}\n \n\n \n {`const fs = require('fs');\n\nconst audioData = fs.readFileSync('audio.mp3');\n\nconst res = await fetch('https://speech-eval.site/upload', {\n method: 'POST',\n headers: { 'Content-Type': 'audio/mp3' },\n body: audioData,\n});\n\nconst result = await res.json();\nconsole.log('audioId:', result.audioId);`}\n \n \n\n {/* ══════ 最佳实践 ══════ */}\n \n\n \n

以下模板帮助你引导 LLM 对评测结果进行深度分析:

\n
\n
\n

发音诊断

\n {`你是一位专业的英语口语教练。请根据以下 MCP 评测结果分析学生的发音表现:\n\n评测结果:{evaluation_result}\n\n请按以下格式输出:\n1. 总体评价(一句话)\n2. 优势项(>80 分的指标)\n3. 弱项分析(<70 分的指标,定位到具体音素)\n4. 针对性练习建议(2-3 条可操作的建议)`}\n
\n
\n

练习生成

\n {`根据以下弱项列表,为学生生成针对性的口语练习材料:\n\n弱项:{weak_points}\n\n请生成:\n1. 3 个绕口令(专门针对弱项音素)\n2. 5 个包含目标音素的常用短句(标注重音和连读)\n3. 1 段跟读练习段落(50-80 词)`}\n
\n
\n

学习报告

\n {`请根据学生近 7 天的评测历史生成学习报告:\n\n评测历史:{history}\n\n报告要求:\n1. 整体趋势(进步/持平/退步)\n2. 各维度变化(准确度、流利度、语速)\n3. 本周最大进步项\n4. 下周重点练习建议\n5. 鼓励性总结`}\n
\n
\n
\n\n \n
    \n
  • 音频过期:上传后 5 分钟内有效。建议在上传后 3 分钟内完成评测。
  • \n
  • 服务繁忙:使用指数退避策略重试(1s → 2s → 4s),最多 3 次。
  • \n
  • 录音中断:WebSocket 断线后代理会自动重连。如持续失败,检查网络连接和 SoX 安装。
  • \n
\n
\n\n \n
    \n
  • 优先使用流式评测:实时录音模式跳过了文件上传环节,端到端延迟比文件评测低 30-50%。
  • \n
  • 音频压缩:文件评测时,上传前将音频转为 16kHz 单声道 mp3,可减少 60-80% 的上传体积。
  • \n
  • 选择合适的工具:单词评测比段落评测快 3-5 倍。如只需单词级分数,不要用句子评测。
  • \n
  • 本地文件路径最便捷:使用 audio_file_path 参数传入本地路径,代理自动处理编码,无需手动转 Base64。
  • \n
\n
\n
\n\n {/* ══════ 服务信息 ══════ */}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n
端点方法说明
/uploadPOST音频文件上传
/mcpPOSTMCP JSON-RPC 接口(Streamable HTTP)
/healthGET健康检查
\n
\n
\n \n
\n \n \n \n \n \n \n \n {[\n ['存储限制', '500MB', '最大音频存储空间'],\n ['最大排队', '10', '等待处理的请求数'],\n ['最大并发', '3', '同时处理的评测数'],\n ['音频有效期', '5 分钟', '上传后未评测自动过期'],\n ['文件大小限制', '50MB', '单个音频文件最大'],\n ].map(([k, v, d]) => (\n \n ))}\n \n
配置项默认值说明
{k}{v}{d}
\n
\n
\n \n
\n {[\n { ver: 'v3.0.0', date: '2026-04-16', desc: '新增本地代理模式,支持实时录音流式评测,工具扩展至 16 种' },\n { ver: 'v2.3.0', date: '2026-03-25', desc: '支持 HTTPS,域名 speech-eval.site' },\n { ver: 'v2.2.0', date: '2026-03-24', desc: '添加 MCP 配置指南(Cursor / Claude Desktop)' },\n { ver: 'v2.1.0', date: '2026-03-24', desc: '简化上传流程,统一使用 HTTP API' },\n { ver: 'v2.0.0', date: '2026-03-24', desc: '初始版本,支持多种评测类型' },\n ].map(l => (\n
\n {l.ver}\n {l.date}\n {l.desc}\n
\n ))}\n
\n
\n
\n\n \n );\n}\n\nexport default function DocsPage() {\n const locale = useLocale();\n return locale.startsWith('zh') ? : ;\n}\n"}, "32fd97e4c3e451e9645b39a311fe3e4e0b8ebd50": {"t": 1785765804.3718727, "n": 95760, "h": "eabab60f01cf5d60", "c": "'use client';\n\nimport { useState, useEffect, useMemo, useRef, useCallback } from 'react';\nimport { Link } from '@/i18n/routing';\nimport { ArrowLeft, BookOpen, Code2, Zap, FileText, Copy, Check, Terminal, Globe, Mic, MessageSquare, BarChart3, AlertTriangle, Lightbulb, Radio, FolderOpen, Settings, Workflow, Sparkles, Plug, Bot, Building2 } from 'lucide-react';\n\n/* ─── Reusable Components ─── */\n\nfunction CopyButton({ text }: { text: string }) {\n const [copied, setCopied] = useState(false);\n return (\n { navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000); }}\n className=\"absolute top-3 right-3 p-1.5 rounded-md bg-white/5 hover:bg-white/10 transition-colors text-zinc-400 hover:text-zinc-200\"\n >\n {copied ? : }\n \n );\n}\n\nfunction CodeBlock({ filename, lang, children }: { filename?: string; lang?: string; children: string }) {\n return (\n
\n {filename && (\n
\n \n \n \n {filename}\n {lang && {lang}}\n
\n )}\n \n
{children.trim()}
\n
左右滑动查看完整代码
\n
\n );\n}\n\nfunction DocSection({ id, icon: Icon, title, children }: { id: string; icon: React.ElementType; title: string; children: React.ReactNode }) {\n return (\n
\n
\n \n

{title}

\n
\n
{children}
\n
\n );\n}\n\nfunction SubDoc({ id, title, children }: { id: string; title: string; children: React.ReactNode }) {\n return (\n
\n

{title}

\n
{children}
\n
\n );\n}\n\nfunction ParamTable({ params }: { params: { name: string; type: string; required: boolean; desc: string }[] }) {\n return (\n
\n \n \n \n \n \n \n \n \n {params.map(p => (\n \n \n \n \n \n \n ))}\n \n
参数类型必填说明
{p.name}{p.type}{p.required ? ✓ : —}{p.desc}
\n
\n );\n}\n\nfunction Callout({ type = 'info', children }: { type?: 'info' | 'warning' | 'tip'; children: React.ReactNode }) {\n const styles = {\n info: 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900 dark:bg-blue-950/30 dark:text-blue-200',\n warning: 'border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-900 dark:bg-amber-950/30 dark:text-amber-200',\n tip: 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950/30 dark:text-emerald-200',\n };\n const icons = { info: Globe, warning: AlertTriangle, tip: Lightbulb };\n const Ic = icons[type];\n return (\n
\n \n
{children}
\n
\n );\n}\n\nfunction FlowStep({ title, children }: { title: string; children: React.ReactNode }) {\n return (\n
\n
{title}
\n
{children}
\n
\n );\n}\n\nfunction ToolTable({ tools }: { tools: [string, string, string][] }) {\n return (\n
\n \n \n \n \n \n \n \n {tools.map(([name, desc, scene]) => (\n \n \n \n \n \n ))}\n \n
工具名功能典型场景
{name}{desc}{scene}
\n
\n );\n}\n\n/* ─── Navigation Structure ─── */\n\nconst NAV = [\n { id: 'concept', icon: Workflow, label: 'MCP 工作原理', children: [\n { id: 'why-mcp', label: '为什么需要 MCP' },\n { id: 'scenario-walkthrough', label: '场景走查 · 6 步' },\n { id: 'dev-responsibility', label: '开发者只做两件事' },\n { id: 'integration-paths', label: '三种接入姿势' },\n ]},\n { id: 'quick-start', icon: Zap, label: '快速开始', children: [\n { id: 'overview', label: '概述' },\n { id: 'requirements', label: '系统要求' },\n { id: 'install', label: '安装方式' },\n { id: 'env-vars', label: '环境变量' },\n ]},\n { id: 'config', icon: Plug, label: '接入 · 直接用(零代码)', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: '扣子(Coze)' },\n { id: 'config-coze-workflow', label: 'Coze 工作流' },\n { id: 'config-ai-workspace', label: 'AI 工作台 · 豆包 / 飞书 / WorkBuddy / 钉钉' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: '其他 MCP 客户端' },\n ]},\n { id: 'config-code', icon: Code2, label: '接入 · 编程用(SDK / 代码)', children: [\n { id: 'code-mcp-sdk', label: '官方 MCP 客户端库' },\n { id: 'code-agent-frameworks', label: 'LangChain / Mastra / Agents SDK' },\n { id: 'code-function-calling', label: '直调 chat.completions · tools' },\n { id: 'code-selfhosted-agent', label: '自研后端 Agent' },\n ]},\n { id: 'eval-modes', icon: Radio, label: '评测模式', children: [\n { id: 'stream-eval', label: '实时录音评测' },\n { id: 'stream-flow', label: '流式评测流程' },\n { id: 'file-eval', label: '音频文件评测' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API 参考', children: [\n { id: 'tools-en', label: '英文评测工具' },\n { id: 'tools-cn', label: '中文评测工具' },\n { id: 'result-fields', label: '评测结果字段' },\n { id: 'error-codes', label: '错误码' },\n ]},\n { id: 'architecture', icon: Terminal, label: '架构说明', children: [\n { id: 'arch-diagram', label: '架构图' },\n { id: 'transport', label: '传输协议' },\n ]},\n { id: 'integration', icon: Code2, label: '示例代码', children: [\n { id: 'code-python', label: 'Python' },\n { id: 'code-javascript', label: 'JavaScript' },\n ]},\n { id: 'best-practices', icon: FileText, label: '最佳实践', children: [\n { id: 'prompt-templates', label: 'Prompt 模板' },\n { id: 'error-handling', label: '错误处理' },\n { id: 'performance', label: '性能优化' },\n ]},\n { id: 'service-info', icon: Globe, label: '服务信息', children: [\n { id: 'endpoints', label: '服务端点' },\n { id: 'limits', label: '服务限制' },\n { id: 'changelog', label: '更新日志' },\n ]},\n];\n\n/* ─── Page ─── */\n\nexport default function DocsPage() {\n const [activeId, setActiveId] = useState('quick-start');\n const contentRef = useRef(null);\n const navRef = useRef(null);\n\n // 收集所有可滚动的锚点 id(包含分组和子章节),用于 scroll-spy\n const allIds = useMemo(() => {\n const ids: string[] = [];\n NAV.forEach(g => {\n ids.push(g.id);\n g.children.forEach(c => ids.push(c.id));\n });\n return ids;\n }, []);\n\n const scrollToAnchor = useCallback((id: string) => {\n const target = document.getElementById(id);\n if (!target) return;\n\n const scroller = contentRef.current;\n if (scroller && window.innerWidth >= 1024) {\n const scrollerRect = scroller.getBoundingClientRect();\n const targetRect = target.getBoundingClientRect();\n const delta = targetRect.top - scrollerRect.top;\n const top = scroller.scrollTop + delta - 24;\n scroller.scrollTo({ top, behavior: 'smooth' });\n window.history.replaceState(null, '', `#${id}`);\n return;\n }\n\n window.scrollTo({ top: target.offsetTop - 88, behavior: 'smooth' });\n window.history.replaceState(null, '', `#${id}`);\n }, []);\n\n useEffect(() => {\n const getAnchors = () =>\n allIds\n .map(id => document.getElementById(id))\n .filter((el): el is HTMLElement => el !== null)\n .map(el => ({\n id: el.id,\n top: (() => {\n if (useInnerScroller) {\n const scrollerRect = scroller.getBoundingClientRect();\n const elRect = el.getBoundingClientRect();\n return scroller.scrollTop + (elRect.top - scrollerRect.top);\n }\n // 使用文档绝对坐标,避免 offsetTop 在复杂父级下失真\n return el.getBoundingClientRect().top + window.scrollY;\n })(),\n }))\n .sort((a, b) => a.top - b.top);\n\n let rafId = 0;\n const scroller = contentRef.current;\n const useInnerScroller = !!scroller && window.innerWidth >= 1024;\n\n const computeActive = () => {\n const anchors = getAnchors();\n if (anchors.length === 0) return;\n\n const scrollTop = useInnerScroller ? scroller.scrollTop : window.scrollY;\n const probeY = scrollTop + 170; // 顶栏 + 阅读缓冲\n let currentId = anchors[0].id;\n\n for (const a of anchors) {\n if (a.top <= probeY) currentId = a.id;\n else break;\n }\n\n // 滚到底部时,强制高亮最后一项\n const atBottom = useInnerScroller\n ? scroller.scrollTop + scroller.clientHeight >= scroller.scrollHeight - 4\n : window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - 4;\n if (atBottom) {\n currentId = anchors[anchors.length - 1].id;\n }\n\n setActiveId(prev => (prev === currentId ? prev : currentId));\n };\n\n const onScroll = () => {\n if (rafId) return;\n rafId = window.requestAnimationFrame(() => {\n rafId = 0;\n computeActive();\n });\n };\n\n // 初次与异步内容稳定后各计算一次,避免首屏偏差\n computeActive();\n const t = window.setTimeout(computeActive, 120);\n\n if (useInnerScroller) {\n scroller.addEventListener('scroll', onScroll, { passive: true });\n } else {\n window.addEventListener('scroll', onScroll, { passive: true });\n }\n window.addEventListener('resize', computeActive);\n window.addEventListener('hashchange', computeActive);\n return () => {\n window.clearTimeout(t);\n if (rafId) window.cancelAnimationFrame(rafId);\n if (useInnerScroller) {\n scroller.removeEventListener('scroll', onScroll);\n } else {\n window.removeEventListener('scroll', onScroll);\n }\n window.removeEventListener('resize', computeActive);\n window.removeEventListener('hashchange', computeActive);\n };\n }, [allIds]);\n\n // 根据当前激活的子节点,找出其所属分组 id,用于同步高亮父级\n const activeGroupId = useMemo(() => {\n for (const g of NAV) {\n if (g.id === activeId) return g.id;\n if (g.children.some(c => c.id === activeId)) return g.id;\n }\n return activeId;\n }, [activeId]);\n\n // 左侧目录如果出现滚动,则保证当前激活项自动进入可视区域\n useEffect(() => {\n const nav = navRef.current;\n if (!nav) return;\n if (window.innerWidth < 1024) return;\n\n const target = nav.querySelector(`[data-nav-id=\"${activeId}\"]`);\n if (!target) return;\n\n const navRect = nav.getBoundingClientRect();\n const targetRect = target.getBoundingClientRect();\n const outOfView = targetRect.top < navRect.top + 8 || targetRect.bottom > navRect.bottom - 8;\n\n if (outOfView) {\n target.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }\n }, [activeId]);\n\n return (\n
\n
\n \n 返回首页\n \n\n

开发者文档

\n

驰声语音评测 MCP · chivox-local-mcp

\n\n
\n {/* Sidebar */}\n \n {NAV.map(group => {\n const isGroupActive = activeGroupId === group.id;\n return (\n
\n {\n e.preventDefault();\n setActiveId(group.id);\n scrollToAnchor(group.id);\n }}\n className={`flex items-center gap-2 text-sm font-semibold mb-1.5 transition-colors ${\n isGroupActive ? 'text-foreground' : 'text-foreground/70 hover:text-foreground'\n }`}\n >\n \n {group.label}\n \n
    \n {group.children.map(child => {\n const isActive = activeId === child.id;\n return (\n
  • \n {isActive && (\n \n )}\n {\n e.preventDefault();\n setActiveId(child.id);\n scrollToAnchor(child.id);\n }}\n className={`text-xs block py-0.5 leading-5 transition-colors ${\n isActive\n ? 'text-foreground font-medium'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n >\n {child.label}\n \n
  • \n );\n })}\n
\n
\n );\n })}\n \n\n {/* Content */}\n \n\n {/* ══════ MCP 工作原理 ══════ */}\n \n\n \n

\n 大模型(GPT / Claude / Gemini / 通义千问 等)本质上是文字大脑:它擅长读和写,但天生听不到音频、打不开你的数据库、调不通第三方 API。\n

\n

\n MCP(Model Context Protocol)是一套由 Anthropic 主导、业界共同推进的开放协议,它像一根\"对讲机\":让大模型可以在需要时主动去调用外部能力(工具、数据源、服务),然后把结果接回来继续对话。\n

\n
\n
\n
\n \n 没有 MCP 的做法\n
\n
    \n
  • · 研究评测服务的 REST 文档
  • \n
  • · 自己写鉴权 / 上传 / 轮询代码
  • \n
  • · 把结果序列化后塞进 prompt
  • \n
  • · 每换一个大模型都得重写一遍
  • \n
\n
\n
\n
\n \n 用驰声 MCP 之后\n
\n
    \n
  • · 填一行 MCP Server 地址
  • \n
  • · 大模型自动发现&调用评测工具
  • \n
  • · 换任何支持 MCP 的大模型都能用
  • \n
  • · 不写一行调用代码
  • \n
\n
\n
\n \n MCP 让\"接入语音评测\"从一个\"后端工程\"变成了一个\"配置项\"。这也是为什么 Cursor、Claude Desktop、Dify、Coze、字节豆包、飞书智能助手都已经原生支持 MCP。\n \n
\n\n \n

\n 想象一个具体场景:一位开发者用 Claude 做了一款 「AI 雅思口语陪练」小程序,接入驰声语音评测 MCP。当用户发来一段录音,整个链路是这样的:\n

\n
\n \n

配置阶段(开发者 · 一次性)

\n

在 AI 后端的配置文件里填一行驰声 MCP Server 地址。大模型启动时自动发现:「我多了一个叫语音评测的工具」。

\n
\n \n

接收用户指令(终端用户)

\n

小程序用户发来一段自我介绍录音:「帮我听听,发音哪里有问题?」后端把「文字 + 录音链接」打包给大模型。

\n
\n \n

大模型自主思考(LLM · 最核心的魔法)

\n
\n 「用户让我听发音。」
\n 「但我只是文字大脑,我听不到。」
\n 「等等 —— 开发者给了我一个叫 chivox_voice_eval 的 MCP 工具!」\n
\n
\n \n

MCP 协议 · 自动调用(LLM → 驰声)

\n

大模型自动按 MCP 标准构造 tools/call 请求,把录音链接和参考文本发到驰声服务。开发者不需要写任何调用代码。

\n
\n \n

驰声服务处理(评测引擎)

\n

驰声对音频进行考试级打分,把结构化结果通过 MCP 原路返回:overall 85、/θ/ 音发音错误、流利度 88。

\n
\n \n

大模型整合并输出反馈(LLM)

\n

大模型把冷冰冰的分数翻译成温柔反馈:

\n
\n 「你的自我介绍很棒!综合 85 分 🎉 不过 think 这个词的 /θ/ 咬舌音不太标准,我们一起来练一下……」\n
\n
\n
\n \n 整条链路里,MCP 只出现在 ① 和 ④:① 让开发者一次性告诉大模型「你多了一个工具」,④ 让大模型可以自动调用它。这两步的标准化,就是 MCP 的全部价值。\n \n
\n\n \n

听起来复杂,但对开发者来说只需要两件事:

\n
\n
\n
\n 1\n 填一次 MCP 配置\n
\n

\n 在 AI 后端的配置里填入驰声 MCP Server 地址和 API Key,就这一次,以后新加评测能力完全免开发。\n

\n {`{\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"apiKey\": \"sk-••••••••••\"\n }\n}`}\n
\n
\n
\n 2\n 写一段 System Prompt\n
\n

\n 告诉大模型这个工具是做什么的、什么时候调用、结果怎么转成用户友好的反馈。\n

\n {`你是一位英语口语教练。\n当用户发来录音时:\n1. 调用 chivox_voice_eval 评分\n2. 聚焦 <70 分的音素家族\n3. 用高情商话术给出练习建议`}\n
\n
\n

\n 其余所有事情 —— 音频上传、鉴权、工具发现、调用时机、返回格式、结果整合 —— 都由 MCP 协议和大模型自己搞定。\n

\n
\n\n \n

根据你的技术栈,有三种等价的接入方式,底层都走完全相同的 MCP 协议:

\n\n {/* ── 姿势一:可视化 ── */}\n
\n
\n \n

姿势一 · 可视化拖拽(扣子 / Coze / 飞书智能助手)

\n
\n

\n 适合产品经理、运营、不写后端代码的开发者。整个过程像在手机上装 App。\n

\n
    \n
  1. 找到入口:在扣子平台的 「插件 / 工具」 配置区,点击「添加 MCP 服务」。
  2. \n
  3. 填两个字段(这也是你未来会从驰声这边拿到的):\n
    \n \n \n \n \n \n
    服务器地址https://speech-eval.site/mcp
    鉴权密钥sk-•••••••••• (由驰声分配,用于计费与识别)
    \n
    \n
  4. \n
  5. 平台自动发现能力:扣子会访问你填的地址,读取 MCP Server 自描述的\"说明书\"。瞬间明白:「这是个语音评测工具,需要传音频,会返发音分」。
  6. \n
  7. 右侧测试:在平台的聊天框里发一段语音,大模型就会自动调用工具。整个过程不需要写一行代码。
  8. \n
\n
\n\n {/* ── 姿势二:代码框架 ── */}\n
\n
\n \n

姿势二 · 代码框架配置(Dify / LangChain / 自研后端)

\n
\n

\n 适合做独立 APP / 小程序、用 Dify 或 LangChain 写 Agent 的极客开发者。核心就是往配置文件里加一段 JSON。\n

\n
    \n
  1. 打开配置文件(项目根目录下的 mcp.json 或框架指定的配置路径)。
  2. \n
  3. 在 mcpServers 下增加一个节点:\n {`{\n \"mcpServers\": {\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"env\": {\n \"API_KEY\": \"你的专属密钥\"\n }\n }\n }\n}`}\n
  4. \n
  5. 重启后端服务。大模型的底层调度器会在启动时自动连上驰声 MCP Server,把 16 种评测工具注册成随时待命的 tools。
  6. \n
  7. 触发调用:用户发来录音后,大模型看到 system prompt 的引导,自动选择合适的工具(单词/句子/段落/半开放)调用。
  8. \n
\n
\n\n {/* ── 姿势三:Function Calling 直连(分 A / B 两种做法) ── */}\n
\n
\n \n

姿势三 · 原生 Function Calling(豆包 / DeepSeek / OpenAI 兼容 API)

\n
\n

\n 适合不用任何 Agent 框架、直接调用 LLM API 的后端开发者。豆包 1.5+ / DeepSeek / GPT / Qwen 等模型都走标准 chat.completions 的 tools 参数。这里又分 A / B 两种做法,B 才是生产推荐。\n

\n\n \n 常见疑问:\"要不要手写一个 tool 定义?\"
\n — 姿势一 / 二不用(Coze、Dify、火山方舟控制台、Claude Desktop 会自动从 MCP Server 拉工具列表)。
\n — 姿势三看你选 A 还是 B:A 要手写,B 用 MCP 客户端库自动拉。\n
\n\n {/* ── 3-A:手写 tool schema ── */}\n
\n
\n

3-A · 手写 tool schema(最快验证,不推荐生产)

\n 快速 Demo\n
\n

\n 自己写一段 JSON Schema 告诉豆包\"有个工具叫 xxx,参数长这样\",豆包返回 tool_call 后你再手动去调驰声 MCP。缺点:驰声有 16 个评测工具,你每加一个题型都要改代码。\n

\n {`import os, json\nfrom openai import OpenAI\n\nclient = OpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv('ARK_API_KEY'),\n)\n\n# ─── 手写一段 tool schema(不推荐:16 个工具就要写 16 段)───\ntools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": \"en_word_eval\",\n \"description\": \"英语单词发音评测。当用户让你评价英语发音并提供录音链接时调用。\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"audio_url\": {\"type\": \"string\", \"description\": \"录音 URL\"},\n \"reference_text\": {\"type\": \"string\", \"description\": \"参考文本,如 Apple\"},\n },\n \"required\": [\"audio_url\", \"reference_text\"]\n }\n }\n}]\n\nresp = client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,拿到评测结果后温柔地反馈,不要直接报分数。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n)\n\nmsg = resp.choices[0].message\nif msg.tool_calls:\n args = json.loads(msg.tool_calls[0].function.arguments)\n # ↓↓↓ 这里手动调驰声 MCP,再把结果回填给豆包做第二趟 ↓↓↓\n # result = requests.post(\"https://speech-eval.site/mcp\", json={...})`}\n
\n\n {/* ── 3-B:MCP 自动发现 ── */}\n
\n
\n

\n 3-B · 用 MCP 客户端库自动发现 \n

\n 生产推荐\n
\n

\n 启动时连上驰声 MCP Server,调一次 tools/list,把 16 个评测工具自动转成 Function Calling 的 tools 格式。驰声加新工具,你代码不用改。这才是 MCP 协议的真正价值。\n

\n {`import asyncio, os\nfrom openai import AsyncOpenAI\nfrom mcp import ClientSession\nfrom mcp.client.streamable_http import streamablehttp_client\n\nclient = AsyncOpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv(\"ARK_API_KEY\"),\n)\n\nasync def main():\n # ─── 1. 连驰声 MCP Server,自动拉取全部 16 个工具 ───\n async with streamablehttp_client(\n \"https://speech-eval.site/mcp\",\n headers={\"Authorization\": f\"Bearer {os.getenv('CHIVOX_KEY')}\"},\n ) as (read, write, _):\n async with ClientSession(read, write) as session:\n await session.initialize()\n mcp_tools = (await session.list_tools()).tools # ← 一行拿到全部工具\n\n # ─── 2. MCP schema → OpenAI Function Calling schema ───\n tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema, # MCP 直接给 JSON Schema\n }\n } for t in mcp_tools]\n\n # ─── 3. 正常调豆包,tools 由 MCP 动态注入 ───\n resp = await client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,收到评测结果后温柔反馈。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n )\n\n # ─── 4. 折返跑:豆包选好工具后,直接走 MCP 调驰声 ───\n msg = resp.choices[0].message\n if msg.tool_calls:\n call = msg.tool_calls[0]\n result = await session.call_tool(\n call.function.name,\n arguments=__import__(\"json\").loads(call.function.arguments),\n )\n # 把 result 回填给豆包做第二趟 chat.completions 即可\n\nasyncio.run(main())`}\n

\n 想要更省心?直接用 官方 mcp python sdk、mcp-use、openai-agents,或火山官方 Arkitect 高代码 SDK,它们都把上面这段\"MCP → Function Calling\"的桥接封装好了。\n

\n
\n
\n\n \n 三种姿势走的是完全相同的 MCP 协议,能力完全等价。选型建议:产品经理 / 原型验证用姿势一(Coze 填表单);AI 客户端用户用姿势二(Cursor / Claude Desktop 填 mcp.json);后端生产服务用姿势三-B(MCP 客户端库自动发现工具,不要手写 tool schema)。\n \n
\n\n
\n\n {/* ══════ 快速开始 ══════ */}\n \n\n \n

chivox-local-mcp 是驰声语音评测的 MCP 本地代理,通过 Model Context Protocol 将远程驰声评测服务桥接到本地,让 AI 助手(Claude Desktop、Claude Code、Cursor 等)直接调用语音评测能力。

\n

它支持两种评测模式,覆盖从即时交互到批量处理的全部场景:

\n
\n
\n
\n \n 实时录音评测\n
\n

通过麦克风边录边评,音频以 WebSocket 流式推送,无需生成中间文件,延迟更低、体验更佳。

\n
\n
\n
\n \n 音频文件评测\n
\n

支持本地文件路径、Base64 编码、URL 三种输入,适合已有音频的批量评测场景。

\n
\n
\n 当前支持 16 种评测工具:英文 10 种(单词、句子、段落、纠音、自然拼读、口语选择、半开放题等)+ 中文 6 种(汉字、拼音、词句、段落、有限分支、AI Talk)。\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n
依赖版本说明
Node.js{'>'}= 18运行时必须
SoXany仅实时录音功能需要(处理麦克风音频流)
\n
\n

安装 SoX(仅在使用实时录音时需要):

\n {`# macOS\nbrew install sox\n\n# Ubuntu / Debian\nsudo apt-get install sox`}\n
\n\n \n

方式一:npm 全局安装(推荐)

\n {`npm install -g chivox-local-mcp`}\n\n

方式二:npx 免安装运行

\n {`MCP_REMOTE_URL=http://your-server:8080 npx chivox-local-mcp`}\n\n

方式三:从源码构建

\n {`git clone https://git.chivox.com/CLOUD_DEV/cvx_local_mcp.git\ncd cvx_local_mcp\nbash scripts/build.sh`}\n
\n\n \n \n \n
\n\n {/* ══════ 接入 · 直接用(零代码) ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 不用写代码、不用装 SDK,只在客户端的「MCP 配置」或「扩展」里填一段 JSON / URL
  • \n
  • 保存后 LLM 自动发现 16 个评测工具,并在对话 / Agent 中自主调用
  • \n
  • 覆盖 IDE 编程助手、桌面 AI 客户端、企业 AI 工作台、可视化 Bot / 工作流平台四大生态
  • \n
\n
\n\n\n \n
    \n
  1. 打开 Cursor 设置(Cmd + ,)
  2. \n
  3. 左侧选择 MCP(或搜索 "MCP")
  4. \n
  5. 点击 Add new MCP server
  6. \n
  7. 填写配置并保存:
  8. \n
\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n}`}\n Cursor 使用远程 Streamable HTTP 模式直连,无需安装本地代理。如需实时录音功能,请使用下方 Claude Desktop 的本地代理配置。\n
\n\n \n

编辑配置文件(macOS:~/Library/Application Support/Claude/claude_desktop_config.json):

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"chivox-local-mcp\",\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\",\n \"MCP_API_KEY\": \"your-api-key\"\n }\n }\n }\n}`}\n

如果是从源码构建:

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/cvx_local_mcp/dist/index.js\"],\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\"\n }\n }\n }\n}`}\n Claude Desktop 使用本地代理模式(stdio),支持实时录音评测。本地代理会自动桥接远程服务。\n
\n\n \n {`# npm 全局安装后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 chivox-local-mcp\n\n# 源码构建后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 node /path/to/cvx_local_mcp/dist/index.js`}\n \n\n \n

除了 Cursor 和 Claude Code,主流的 AI 编程 IDE 都原生支持 MCP。以下客户端使用完全一致的 Streamable HTTP 配置,区别只在配置入口:

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
客户端配置入口备注
Windsurf (Codeium)Settings → Cascade → MCP Servers直接贴下方 JSON
Zed~/.config/zed/settings.json 的 context_serversAssistant Panel 自动发现
Continue (VS Code / JetBrains)config.yaml 的 mcpServersv0.9+ 支持
通义灵码 / CodeGeeX / 文心快码插件设置 → MCP 服务2026 Q1 起陆续支持
Cline (原 Claude Dev)MCP Servers 面板 → 编辑配置VS Code 扩展
\n
\n {`{\n \"mcpServers\": {\n \"chivox-speech-eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n }\n }\n}`}\n 所有 IDE 类客户端都走远程 Streamable HTTP,零本地依赖。需要实时录音才需切到 Claude Desktop 的本地代理模式。\n
\n\n \n

扣子(Coze)是字节跳动推出的 AI 应用开发平台,支持通过 MCP 扩展为 Agent 赋予外部工具能力。接入驰声语音评测后,你可以构建口语练习 Bot、发音诊断助手等应用。

\n

方式一:扣子空间 MCP 扩展(推荐)

\n
    \n
  1. 打开 扣子空间(space.coze.cn)
  2. \n
  3. 在对话框下方点击 「添加扩展」
  4. \n
  5. 选择 「自定义」 标签,点击添加新的 MCP 服务
  6. \n
  7. 填入以下配置信息:
  8. \n
\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
名称chivox-speech-eval
传输类型streamable-http
URLhttps://speech-eval.site/mcp
\n
\n
    \n
  1. 保存后,在对话中输入 「帮我评测这段英文发音」 即可触发 Agent 调用
  2. \n
\n 添加 MCP 扩展后,扣子空间的 Agent 会自动识别并调用评测工具。你可以在 Agent 的思考过程中看到具体的工具调用细节。\n\n

方式二:在 Coze 开发平台的 Bot 中使用

\n
    \n
  1. 进入 Coze 开发平台,创建或编辑 Bot
  2. \n
  3. 在 Bot 的 「插件」 或 「工具」 面板中,添加 MCP 工具
  4. \n
  5. 选择 Streamable HTTP 类型,填入 URL:https://speech-eval.site/mcp
  6. \n
  7. Bot 将自动发现所有可用的评测工具(如 evaluate_english_word 等)
  8. \n
  9. 在 Bot 的人设提示词中,添加语音评测相关的引导语
  10. \n
\n {`你是一位专业的英语口语教练。当用户上传音频并请求评测时:\n1. 使用 evaluate_english_word / evaluate_english_sentence 等工具进行评测\n2. 根据评测结果(overall、accuracy、fluency 等分数)给出专业分析\n3. 针对得分较低的维度提供具体改进建议\n4. 鼓励用户持续练习`}\n
\n\n \n

如果你需要在 Coze 工作流中集成语音评测能力,可以通过 HTTP Request 节点调用评测 API:

\n\n

步骤 1:上传音频

\n

在工作流中添加一个 HTTP Request 节点,配置如下:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
配置项值
方法POST
URLhttps://speech-eval.site/upload
Content-Typeaudio/mp3
Body音频文件二进制数据
\n
\n

响应中获取 {'{{audioId}}'},传递给下一步。

\n\n

步骤 2:调用评测

\n

添加第二个 HTTP Request 节点,通过 MCP 接口调用评测工具:

\n {`{\n \"jsonrpc\": \"2.0\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"evaluate_english_sentence\",\n \"arguments\": {\n \"audioId\": \"{{audioId}}\",\n \"sentence\": \"{{ref_text}}\"\n }\n },\n \"id\": 1\n}`}\n\n

步骤 3:处理结果

\n

评测结果通过 JSON 格式返回,可使用 Coze 的 代码节点 或 LLM 节点 对结果进行解析和二次处理(如生成学习建议、计算进步趋势等)。

\n\n 工作流方式适合需要固定流程的场景(如批量评测、定时任务、与其他系统联动)。如果是交互式场景,推荐使用上方的 MCP 扩展方式,Agent 会自动选择合适的工具。\n\n
\n

完整工作流示意

\n
\n 用户输入音频\n →\n HTTP: 上传音频\n →\n HTTP: 调用评测\n →\n LLM: 分析结果\n →\n 输出反馈\n
\n
\n
\n\n \n

这一类是面向「上班族」的企业 / 日常 AI 助手,产品形态是个聊天框 + 插件市场 / 扩展面板。接入后,员工在 App 里打字「帮我评一下这段录音」就能自动触发驰声评测,不用写任何代码。

\n\n
\n
\n

豆包(Doubao)App / 桌面版

\n

字节跳动官方 AI 助手,2026 年起桌面版支持 MCP 扩展。

\n
    \n
  1. 桌面版设置 → 「智能体扩展」 → 添加 MCP 服务
  2. \n
  3. 类型选 streamable-http,URL 填 https://speech-eval.site/mcp
  4. \n
  5. 对话中直接说「帮我评测」即可自动调用
  6. \n
\n
\n\n
\n

飞书智能伙伴(My AI)

\n

飞书企业 AI,支持以 MCP / Function Calling 挂载外部工具给团队 Bot。

\n
    \n
  1. 飞书开发者后台 → 创建应用 → 「AI 能力 / 智能伙伴」
  2. \n
  3. 在「工具」中选 外部 MCP 服务,填入上方 URL
  4. \n
  5. 把智能伙伴拉进群聊,@ 它提交音频即可评测
  6. \n
\n
\n\n
\n

WorkBuddy / 企业智能助手

\n

字节 WorkBuddy、腾讯会议 AI、企业微信智能助手等企业 AI 工作台场景。

\n
    \n
  1. 在工作台的「技能 / 扩展」后台新增一个 MCP 连接器
  2. \n
  3. 传输协议选 Streamable HTTP,地址填 https://speech-eval.site/mcp
  4. \n
  5. 把技能发布到指定部门 / 群组,HR、培训、销售口语陪练场景即可直接用
  6. \n
\n
\n\n
\n

钉钉 AI 助理 / 通义千问 App

\n

阿里生态:钉钉 AI 助理支持自定义插件,通义 App 可通过「AI 工具箱」挂载 MCP。

\n
    \n
  1. 钉钉开发者后台 → AI 助理 → 「插件开发 / MCP 接入」
  2. \n
  3. 选 HTTP Streamable,填入驰声 MCP URL 并开启鉴权(可选)
  4. \n
  5. 在钉钉群 @AI 助理上传音频,自动返回评测卡片
  6. \n
\n
\n
\n\n 典型场景 · 小龙虾们的共同剧本:销售口语陪练 → 外语培训 → 主持 / 播音岗位考核 → K12 英语作业批改 → 客服话术复盘。这些「上班族 AI 工作台」接入驰声 MCP 后,员工 / 学员只要对着话筒说话,AI 就能自动打分并给出个性化改进建议,运营 / 培训 / 教研团队零开发即可上线。\n
\n\n \n

如果你需要把语音评测编排进多步业务流(例如:学员录音 → 评测 → 生成错题集 → 推送到 CRM),可视化工作流平台比聊天 Bot 更合适。

\n\n
\n
\n

Dify

\n

开源 LLMOps,v0.15+ 原生 MCP 工具。

\n
    \n
  • 「工具」→「自定义 MCP」→ 填 URL
  • \n
  • 在 Chatflow / Workflow 节点里直接拖用
  • \n
\n
\n
\n

n8n

\n

工作流自动化,用 MCP Client 节点。

\n
    \n
  • 添加 MCP Client 节点
  • \n
  • Transport 选 HTTP Stream,URL 贴驰声地址
  • \n
  • Tool 下拉自动列出 16 个评测能力
  • \n
\n
\n
\n

Flowise / LangFlow

\n

可视化 LangChain Agent 编排。

\n
    \n
  • 拖出 MCP Tool 节点
  • \n
  • 连到 AgentExecutor 即可
  • \n
\n
\n
\n\n 可视化平台的好处是流程可追溯、可回放,适合教育机构 / 培训部门做批量评测 + 报表导出;缺点是单步延迟略高于直接 MCP 调用,对延迟敏感的交互场景建议用 Cursor / Claude Desktop 直连。\n
\n\n \n

任何遵循 MCP 协议的客户端都可以接入,统一使用以下配置:

\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
传输类型streamable-http
URLhttps://speech-eval.site/mcp
鉴权(可选)Header:Authorization: Bearer <MCP_API_KEY>
\n
\n

还没找到你用的客户端?任何支持 Model Context Protocol 的终端都通用。找不到入口?下一小节「编程用 MCP」里用 SDK 直接接即可。

\n
\n
\n\n {/* ══════ 接入 · 编程用 MCP ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 你在写一段真正的后端服务:一个 Agent Worker、一个 API、一个自动化脚本
  • \n
  • 业务里的「语音评测」是其中一个步骤,需要由代码 决定何时调用、如何解析结果
  • \n
  • 三种主流写法:① 官方 MCP 客户端库 → ② Agent 框架自动桥接 → ③ 退化到 chat.completions + tools 参数
  • \n
\n

💡 强烈推荐①或②:驰声有 16 个评测工具,让 MCP 自动注入 tool schema,每新增一个题型不用改一行业务代码。

\n
\n\n \n

最底层、也最推荐的方式。由 Anthropic 官方维护,一次连接自动拿到全部工具的 JSON Schema,然后交给任意 LLM。

\n\n

Python:mcp

\n {`# pip install mcp openai\nimport asyncio, os\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nMCP_URL = \"https://speech-eval.site/mcp\"\nllm = OpenAI(api_key=os.getenv(\"DOUBAO_KEY\"),\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\") # 豆包 / DeepSeek / OpenAI 同构\n\nasync def main(audio_id: str, ref: str):\n async with streamablehttp_client(MCP_URL) as (reader, writer, _):\n async with ClientSession(reader, writer) as sess:\n await sess.initialize()\n\n tools = await sess.list_tools()\n openai_tools = [{\n \"type\": \"function\",\n \"function\": {\"name\": t.name, \"description\": t.description,\n \"parameters\": t.inputSchema},\n } for t in tools.tools]\n\n resp = llm.chat.completions.create(\n model=\"doubao-1-5-pro-32k\",\n messages=[{\"role\": \"user\",\n \"content\": f\"帮我评测 audioId={audio_id},参考文本:{ref}\"}],\n tools=openai_tools,\n )\n\n for call in resp.choices[0].message.tool_calls or []:\n result = await sess.call_tool(call.function.name,\n arguments=eval(call.function.arguments))\n print(call.function.name, \"→\", result.content[0].text[:200])\n\nasyncio.run(main(\"abc123\", \"I think therefore I am\"))`}\n\n

TypeScript / Node.js:@modelcontextprotocol/sdk

\n {`// npm i @modelcontextprotocol/sdk openai\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport OpenAI from \"openai\";\n\nconst mcp = new Client({ name: \"chivox-biz\", version: \"1.0.0\" });\nawait mcp.connect(new StreamableHTTPClientTransport(new URL(\"https://speech-eval.site/mcp\")));\n\nconst { tools } = await mcp.listTools();\nconst openai = new OpenAI({ apiKey: process.env.DEEPSEEK_KEY, baseURL: \"https://api.deepseek.com\" });\n\nconst resp = await openai.chat.completions.create({\n model: \"deepseek-chat\",\n messages: [{ role: \"user\", content: \"评测 audioId=abc123, 参考 I think therefore I am\" }],\n tools: tools.map(t => ({ type: \"function\", function: {\n name: t.name, description: t.description, parameters: t.inputSchema\n }})),\n});\n\nfor (const call of resp.choices[0].message.tool_calls ?? []) {\n const r = await mcp.callTool({ name: call.function.name,\n arguments: JSON.parse(call.function.arguments) });\n console.log(call.function.name, r.content);\n}`}\n 这种写法 LLM 供应商可换(豆包 / DeepSeek / GPT / Qwen / Moonshot),工具自动更新(驰声新增题型无需改业务代码),适合生产后端。\n
\n\n \n

如果项目已经在用 Agent 框架,几行 adapter 就能把驰声 MCP 塞进去,框架本身会接管 tool-calling 循环、重试、日志。

\n\n
\n
\n

LangChain / LangGraph(Python)

\n {`# pip install langchain-mcp-adapters langgraph\nfrom langchain_mcp_adapters.client import MultiServerMCPClient\nfrom langgraph.prebuilt import create_react_agent\n\nclient = MultiServerMCPClient({\n \"chivox\": {\n \"transport\": \"streamable_http\",\n \"url\": \"https://speech-eval.site/mcp\",\n }\n})\ntools = await client.get_tools()\n\nagent = create_react_agent(\"openai:gpt-4o-mini\", tools)\nresult = await agent.ainvoke({\"messages\":\n [(\"user\", \"评测 audioId=abc123 参考 think\")]})\nprint(result[\"messages\"][-1].content)`}\n
\n\n
\n

Mastra(TypeScript)

\n {`// npm i @mastra/core @mastra/mcp\nimport { MCPClient } from \"@mastra/mcp\";\nimport { Agent } from \"@mastra/core/agent\";\nimport { openai } from \"@ai-sdk/openai\";\n\nconst mcp = new MCPClient({ servers: {\n chivox: { url: new URL(\"https://speech-eval.site/mcp\") }\n}});\n\nexport const speechCoach = new Agent({\n name: \"speech-coach\",\n instructions: \"你是口语教练,用 chivox 工具评测并给改进建议。\",\n model: openai(\"gpt-4o-mini\"),\n tools: await mcp.getTools(),\n});`}\n
\n\n
\n

OpenAI Agents SDK(Python)

\n {`# pip install openai-agents\nfrom agents import Agent, Runner\nfrom agents.mcp import MCPServerStreamableHttp\n\nchivox = MCPServerStreamableHttp(\n params={\"url\": \"https://speech-eval.site/mcp\"},\n name=\"chivox-speech-eval\",\n)\n\nasync with chivox:\n agent = Agent(name=\"coach\",\n instructions=\"专业口语教练\",\n mcp_servers=[chivox])\n r = await Runner.run(agent, \"评测 audioId=abc123\")\n print(r.final_output)`}\n
\n\n
\n

LlamaIndex / AutoGen / CrewAI

\n

这些框架都有官方或社区 MCP adapter,用法与上述类似:

\n
    \n
  • LlamaIndex:llama-index-tools-mcp
  • \n
  • AutoGen:autogen-ext[mcp]
  • \n
  • CrewAI:crewai-tools 的 MCPServerAdapter
  • \n
  • Spring AI(Java):spring-ai-mcp-client
  • \n
\n
\n
\n
\n\n \n

当你用的 LLM SDK 还没有原生 MCP 支持(比如老版本的火山方舟 / 百度千帆 / 通义 DashScope),退化方案是:用 MCP 客户端一次性拉到 tool schema,然后按 OpenAI Function Calling 格式喂给 LLM。

\n {`# 适用:豆包(火山方舟)/ DeepSeek / Qwen / Moonshot / GLM 等 OpenAI 兼容 API\n# 核心思路:MCP 列工具 → 转 OpenAI tools → LLM 决策 → MCP 执行 → 回填\n\nasync with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n\n # ① 用 MCP 拉到的 schema 自动转 OpenAI 格式\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 喂给豆包\n messages = [{\"role\": \"user\", \"content\": \"评测一下 audioId=abc123\"}]\n resp = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages, tools=oa_tools,\n )\n\n # ③ LLM 回 tool_calls → 折返跑到 MCP 执行\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for c in msg.tool_calls:\n result = await mcp.call_tool(\n c.function.name, arguments=json.loads(c.function.arguments))\n messages.append({\"role\": \"tool\", \"tool_call_id\": c.id,\n \"content\": result.content[0].text})\n # ④ 再喂一轮,让豆包根据评测结果产出自然语言诊断\n final = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages)\n print(final.choices[0].message.content)`}\n 千万别手写 tool schema!驰声 16 个评测工具每个都有几十个字段,手写既容易错也难维护。一定用 MCP list_tools() 动态拿。\n
\n\n \n

大部分落地场景其实是:你已有一个业务后端(教育 SaaS / 培训系统 / 客服平台),只需要新增一个「语音评测」能力。推荐架构:

\n\n
\n
\n 前端录音 / 上传\n →\n 业务后端\n →\n MCP Client(常驻连接)\n →\n 驰声 MCP\n ↘\n LLM(诊断 / 出题)\n
\n
\n\n

FastAPI 示例(生产最小骨架)

\n {`from fastapi import FastAPI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\nfrom contextlib import asynccontextmanager\n\nmcp_session: ClientSession | None = None\n\n@asynccontextmanager\nasync def lifespan(app):\n global mcp_session\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as s:\n await s.initialize()\n mcp_session = s\n yield\n mcp_session = None\n\napp = FastAPI(lifespan=lifespan)\n\n@app.post(\"/api/evaluate\")\nasync def evaluate(audio_id: str, ref_text: str):\n # 直接选一个最合适的工具执行(不经 LLM,延迟最低)\n r = await mcp_session.call_tool(\"evaluate_english_sentence\",\n {\"audioId\": audio_id, \"sentence\": ref_text})\n return {\"result\": r.content[0].text}`}\n\n 关键优化:① MCP 连接在 lifespan 里做成长连接,不要每次请求都重连;② 对延迟敏感的场景可以「跳过 LLM 直接调 tool」,把 LLM 放到「生成诊断报告」那一步。\n
\n\n
\n

方案选型速查

\n
\n \n \n \n \n \n \n \n \n \n \n \n
场景推荐方案
AI 对话 / Copilot 类产品,LLM 供应商可能会换① 官方 MCP 客户端库
已有 LangChain / Mastra / Agents SDK 技术栈② Agent 框架 + adapter
火山方舟 / 千帆控制台直连,最小侵入③ chat.completions + tools
教育 SaaS / 培训 / 客服等业务后端集成④ 自研后端 Agent
\n
\n
\n
\n\n {/* ══════ 评测模式 ══════ */}\n \n\n \n

通过本地麦克风实时录音,音频以 WebSocket 流式推送到评测服务,无需生成中间文件。这是最灵活、延迟最低的评测方式,特别适合交互式口语练习场景。

\n 实时录音评测需要安装 SoX 并使用本地代理模式(Claude Desktop / Claude Code)。Cursor 等远程直连模式暂不支持实时录音。\n\n

需要按顺序调用三个工具:

\n\n
\n
\n

create_stream_session — 创建流式评测会话

\n \n

返回 session_id,后续步骤需使用。

\n
\n\n
\n

start_recording — 开始麦克风录音

\n \n

调用后自动启动麦克风,音频通过 WebSocket 实时推送到评测服务。

\n
\n\n
\n

stop_recording — 停止录音并获取结果

\n \n
\n
\n
\n\n \n
\n \n

用户:"请评测我的英文发音,文本是 Hello"

\n

AI 调用 create_stream_session(core_type="en.word.score", ref_text="Hello")

\n

→ 获得 session_id

\n
\n \n

AI 调用 start_recording(session_id=xxx)

\n

麦克风开始录音,音频通过 WebSocket 实时推送到评测服务

\n
\n \n

用户说完后告知 AI "结束"

\n

AI 调用 stop_recording(session_id=xxx)

\n

→ 返回评测结果(总分、准确度、流利度、音素得分等)

\n
\n
\n
\n\n \n

适用于已有音频文件的评测场景,支持三种输入方式:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
参数说明适用场景
audio_file_path本地文件路径代理自动读取并转为 Base64,最便捷
audio_base64Base64 编码数据已有编码数据时使用
audio_url音频文件 URL音频托管在云存储时使用
\n
\n 推荐使用 audio_file_path,只需传入本地文件路径,代理会自动处理编码和上传。\n

支持的音频格式:mp3, wav, ogg, m4a, aac, pcm

\n

限制:单文件最大 50MB,大于 500KB 的文件自动压缩为 16kHz / 单声道 / 32kbps。

\n
\n
\n\n {/* ══════ API 参考 ══════ */}\n \n\n \n \n\n

通用参数:所有英文评测工具均支持以下参数。

\n \n
\n\n \n \n\n

通用参数:

\n \n
\n\n \n

所有评测工具返回统一的结构化结果:

\n {`{\n \"overall\": 85,\n \"accuracy\": 82,\n \"pron\": 88,\n \"fluency\": {\n \"overall\": 78,\n \"speed\": 65,\n \"pause\": 2\n },\n \"integrity\": 95,\n \"details\": [\n {\n \"char\": \"hello\",\n \"score\": 85,\n \"phone\": [\n { \"phoneme\": \"h\", \"score\": 90 },\n { \"phoneme\": \"ɛ\", \"score\": 82 },\n { \"phoneme\": \"l\", \"score\": 88 },\n { \"phoneme\": \"oʊ\", \"score\": 80 }\n ]\n }\n ]\n}`}\n
\n \n \n \n \n \n \n \n {[\n ['overall', '0–100', '综合总分,反映整体语音质量'],\n ['accuracy', '0–100', '准确度,音素级别的发音准确率'],\n ['pron', '0–100', '发音得分,整体发音质量评价'],\n ['fluency.overall', '0–100', '流利度,语流的自然度与平滑度'],\n ['fluency.speed', '0–100', '语速得分,每分钟词/音节计量'],\n ['fluency.pause', 'number', '不自然停顿次数'],\n ['integrity', '0–100', '完整度,是否完整朗读了参考文本'],\n ['details[].phone[]', 'array', '每个音素的独立评分,可定位具体弱项'],\n ['details[].stress[]', 'array', '重音得分,检测重弱读是否正确'],\n ].map(([field, range, desc]) => (\n \n \n \n \n \n ))}\n \n
字段范围说明
{field}{range}{desc}
\n
\n
\n\n \n
\n \n \n \n \n \n \n \n {[\n ['音频 ID 无效或已过期', '音频上传后 5 分钟内有效,评测完成后自动删除', '重新上传音频'],\n ['服务器繁忙', '当前请求过多,排队已满', '稍后重试,使用指数退避策略'],\n ['存储空间已满', '服务器临时音频存储已满', '稍后重试,系统会自动清理'],\n ['音频格式不支持', '上传了不支持的文件类型', '使用 mp3/wav/ogg/m4a/aac/pcm'],\n ['音频时长超限', '超过该题型最大时长限制', '裁剪音频后重试'],\n ['WebSocket 连接断开', '网络不稳定导致流式连接中断', '代理会自动重连,如持续失败请检查网络'],\n ].map(([scene, reason, fix]) => (\n \n \n \n \n \n ))}\n \n
场景原因解决方式
{scene}{reason}{fix}
\n
\n
\n
\n\n {/* ══════ 架构说明 ══════ */}\n \n\n \n
\n
\n

AI 客户端

\n

Claude Desktop
Claude Code
Cursor

\n
\n
\n

⇄

\n

stdio

\n
\n
\n

chivox-local-mcp

\n

本地代理
SoX 录音

\n
\n
\n

⇄

\n

HTTP / WS

\n
\n
\n

Remote Chivox

\n

MCP Server
评测引擎

\n
\n
\n
\n\n \n
    \n
  • \n \n stdio — AI 客户端通过标准输入输出与本地代理通信,这是 MCP 的标准传输方式\n
  • \n
  • \n \n HTTP — 音频文件评测工具通过 HTTP 代理到远程服务,适用于非流式场景\n
  • \n
  • \n \n WebSocket — 实时录音音频通过 WebSocket 流式推送,支持断线自动重连\n
  • \n
\n
\n
\n\n {/* ══════ 示例代码 ══════ */}\n \n\n \n {`import requests\n\nwith open('audio.mp3', 'rb') as f:\n r = requests.post(\n 'https://speech-eval.site/upload',\n data=f,\n headers={'Content-Type': 'audio/mp3'}\n )\n\nresult = r.json()\nprint(f\"audioId: {result['audioId']}\")\nprint(f\"size: {result['size']} bytes\")\nprint(f\"expires: {result['expiresIn']}\")`}\n \n\n \n {`const fs = require('fs');\n\nconst audioData = fs.readFileSync('audio.mp3');\n\nconst res = await fetch('https://speech-eval.site/upload', {\n method: 'POST',\n headers: { 'Content-Type': 'audio/mp3' },\n body: audioData,\n});\n\nconst result = await res.json();\nconsole.log('audioId:', result.audioId);`}\n \n \n\n {/* ══════ 最佳实践 ══════ */}\n \n\n \n

以下模板帮助你引导 LLM 对评测结果进行深度分析:

\n
\n
\n

发音诊断

\n {`你是一位专业的英语口语教练。请根据以下 MCP 评测结果分析学生的发音表现:\n\n评测结果:{evaluation_result}\n\n请按以下格式输出:\n1. 总体评价(一句话)\n2. 优势项(>80 分的指标)\n3. 弱项分析(<70 分的指标,定位到具体音素)\n4. 针对性练习建议(2-3 条可操作的建议)`}\n
\n
\n

练习生成

\n {`根据以下弱项列表,为学生生成针对性的口语练习材料:\n\n弱项:{weak_points}\n\n请生成:\n1. 3 个绕口令(专门针对弱项音素)\n2. 5 个包含目标音素的常用短句(标注重音和连读)\n3. 1 段跟读练习段落(50-80 词)`}\n
\n
\n

学习报告

\n {`请根据学生近 7 天的评测历史生成学习报告:\n\n评测历史:{history}\n\n报告要求:\n1. 整体趋势(进步/持平/退步)\n2. 各维度变化(准确度、流利度、语速)\n3. 本周最大进步项\n4. 下周重点练习建议\n5. 鼓励性总结`}\n
\n
\n
\n\n \n
    \n
  • 音频过期:上传后 5 分钟内有效。建议在上传后 3 分钟内完成评测。
  • \n
  • 服务繁忙:使用指数退避策略重试(1s → 2s → 4s),最多 3 次。
  • \n
  • 录音中断:WebSocket 断线后代理会自动重连。如持续失败,检查网络连接和 SoX 安装。
  • \n
\n
\n\n \n
    \n
  • 优先使用流式评测:实时录音模式跳过了文件上传环节,端到端延迟比文件评测低 30-50%。
  • \n
  • 音频压缩:文件评测时,上传前将音频转为 16kHz 单声道 mp3,可减少 60-80% 的上传体积。
  • \n
  • 选择合适的工具:单词评测比段落评测快 3-5 倍。如只需单词级分数,不要用句子评测。
  • \n
  • 本地文件路径最便捷:使用 audio_file_path 参数传入本地路径,代理自动处理编码,无需手动转 Base64。
  • \n
\n
\n
\n\n {/* ══════ 服务信息 ══════ */}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n
端点方法说明
/uploadPOST音频文件上传
/mcpPOSTMCP JSON-RPC 接口(Streamable HTTP)
/healthGET健康检查
\n
\n
\n \n
\n \n \n \n \n \n \n \n {[\n ['存储限制', '500MB', '最大音频存储空间'],\n ['最大排队', '10', '等待处理的请求数'],\n ['最大并发', '3', '同时处理的评测数'],\n ['音频有效期', '5 分钟', '上传后未评测自动过期'],\n ['文件大小限制', '50MB', '单个音频文件最大'],\n ].map(([k, v, d]) => (\n \n ))}\n \n
配置项默认值说明
{k}{v}{d}
\n
\n
\n \n
\n {[\n { ver: 'v3.0.0', date: '2026-04-16', desc: '新增本地代理模式,支持实时录音流式评测,工具扩展至 16 种' },\n { ver: 'v2.3.0', date: '2026-03-25', desc: '支持 HTTPS,域名 speech-eval.site' },\n { ver: 'v2.2.0', date: '2026-03-24', desc: '添加 MCP 配置指南(Cursor / Claude Desktop)' },\n { ver: 'v2.1.0', date: '2026-03-24', desc: '简化上传流程,统一使用 HTTP API' },\n { ver: 'v2.0.0', date: '2026-03-24', desc: '初始版本,支持多种评测类型' },\n ].map(l => (\n
\n {l.ver}\n {l.date}\n {l.desc}\n
\n ))}\n
\n
\n
\n\n
\n
\n \n
\n );\n}\n"}, "89fc7eafa404d2f31537035c15917423600cc7a7": {"t": 1785765808.283272, "n": 92106, "h": "044e44207c1f88e1", "c": "'use client';\n\nimport { useState, useEffect, useMemo } from 'react';\nimport { Link } from '@/i18n/routing';\nimport { ArrowLeft, BookOpen, Code2, Zap, FileText, Copy, Check, Terminal, Globe, Mic, MessageSquare, BarChart3, AlertTriangle, Lightbulb, Radio, FolderOpen, Settings, Workflow, Sparkles, Plug, Bot, Building2 } from 'lucide-react';\n\n/* ─── Reusable Components ─── */\n\nfunction CopyButton({ text }: { text: string }) {\n const [copied, setCopied] = useState(false);\n return (\n { navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000); }}\n className=\"absolute top-3 right-3 p-1.5 rounded-md bg-white/5 hover:bg-white/10 transition-colors text-zinc-400 hover:text-zinc-200\"\n >\n {copied ? : }\n \n );\n}\n\nfunction CodeBlock({ filename, lang, children }: { filename?: string; lang?: string; children: string }) {\n return (\n
\n {filename && (\n
\n \n \n \n {filename}\n {lang && {lang}}\n
\n )}\n \n
{children.trim()}
\n
\n );\n}\n\nfunction DocSection({ id, icon: Icon, title, children }: { id: string; icon: React.ElementType; title: string; children: React.ReactNode }) {\n return (\n
\n
\n \n

{title}

\n
\n
{children}
\n
\n );\n}\n\nfunction SubDoc({ id, title, children }: { id: string; title: string; children: React.ReactNode }) {\n return (\n
\n

{title}

\n
{children}
\n
\n );\n}\n\nfunction ParamTable({ params }: { params: { name: string; type: string; required: boolean; desc: string }[] }) {\n return (\n
\n \n \n \n \n \n \n \n \n {params.map(p => (\n \n \n \n \n \n \n ))}\n \n
参数类型必填说明
{p.name}{p.type}{p.required ? ✓ : —}{p.desc}
\n
\n );\n}\n\nfunction Callout({ type = 'info', children }: { type?: 'info' | 'warning' | 'tip'; children: React.ReactNode }) {\n const styles = {\n info: 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900 dark:bg-blue-950/30 dark:text-blue-200',\n warning: 'border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-900 dark:bg-amber-950/30 dark:text-amber-200',\n tip: 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950/30 dark:text-emerald-200',\n };\n const icons = { info: Globe, warning: AlertTriangle, tip: Lightbulb };\n const Ic = icons[type];\n return (\n
\n \n
{children}
\n
\n );\n}\n\nfunction FlowStep({ title, children }: { title: string; children: React.ReactNode }) {\n return (\n
\n
{title}
\n
{children}
\n
\n );\n}\n\nfunction ToolTable({ tools }: { tools: [string, string, string][] }) {\n return (\n
\n \n \n \n \n \n \n \n {tools.map(([name, desc, scene]) => (\n \n \n \n \n \n ))}\n \n
工具名功能典型场景
{name}{desc}{scene}
\n
\n );\n}\n\n/* ─── Navigation Structure ─── */\n\nconst NAV = [\n { id: 'concept', icon: Workflow, label: 'MCP 工作原理', children: [\n { id: 'why-mcp', label: '为什么需要 MCP' },\n { id: 'scenario-walkthrough', label: '场景走查 · 6 步' },\n { id: 'dev-responsibility', label: '开发者只做两件事' },\n { id: 'integration-paths', label: '三种接入姿势' },\n ]},\n { id: 'quick-start', icon: Zap, label: '快速开始', children: [\n { id: 'overview', label: '概述' },\n { id: 'requirements', label: '系统要求' },\n { id: 'install', label: '安装方式' },\n { id: 'env-vars', label: '环境变量' },\n ]},\n { id: 'config', icon: Plug, label: '接入 · 直接用(零代码)', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-ai-ide', label: 'Windsurf / Zed / Continue' },\n { id: 'config-coze', label: '扣子(Coze)' },\n { id: 'config-coze-workflow', label: 'Coze 工作流' },\n { id: 'config-ai-workspace', label: 'AI 工作台 · 豆包 / 飞书 / WorkBuddy / 钉钉' },\n { id: 'config-workflow-platforms', label: 'Dify / n8n / Flowise' },\n { id: 'config-other', label: '其他 MCP 客户端' },\n ]},\n { id: 'config-code', icon: Code2, label: '接入 · 编程用(SDK / 代码)', children: [\n { id: 'code-mcp-sdk', label: '官方 MCP 客户端库' },\n { id: 'code-agent-frameworks', label: 'LangChain / Mastra / Agents SDK' },\n { id: 'code-function-calling', label: '直调 chat.completions · tools' },\n { id: 'code-selfhosted-agent', label: '自研后端 Agent' },\n ]},\n { id: 'eval-modes', icon: Radio, label: '评测模式', children: [\n { id: 'stream-eval', label: '实时录音评测' },\n { id: 'stream-flow', label: '流式评测流程' },\n { id: 'file-eval', label: '音频文件评测' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API 参考', children: [\n { id: 'tools-en', label: '英文评测工具' },\n { id: 'tools-cn', label: '中文评测工具' },\n { id: 'result-fields', label: '评测结果字段' },\n { id: 'error-codes', label: '错误码' },\n ]},\n { id: 'architecture', icon: Terminal, label: '架构说明', children: [\n { id: 'arch-diagram', label: '架构图' },\n { id: 'transport', label: '传输协议' },\n ]},\n { id: 'integration', icon: Code2, label: '示例代码', children: [\n { id: 'code-python', label: 'Python' },\n { id: 'code-javascript', label: 'JavaScript' },\n ]},\n { id: 'best-practices', icon: FileText, label: '最佳实践', children: [\n { id: 'prompt-templates', label: 'Prompt 模板' },\n { id: 'error-handling', label: '错误处理' },\n { id: 'performance', label: '性能优化' },\n ]},\n { id: 'service-info', icon: Globe, label: '服务信息', children: [\n { id: 'endpoints', label: '服务端点' },\n { id: 'limits', label: '服务限制' },\n { id: 'changelog', label: '更新日志' },\n ]},\n];\n\n/* ─── Page ─── */\n\nexport default function DocsPage() {\n const [activeId, setActiveId] = useState('quick-start');\n\n // 收集所有可滚动的锚点 id(包含分组和子章节),用于 scroll-spy\n const allIds = useMemo(() => {\n const ids: string[] = [];\n NAV.forEach(g => {\n ids.push(g.id);\n g.children.forEach(c => ids.push(c.id));\n });\n return ids;\n }, []);\n\n useEffect(() => {\n const elements = allIds\n .map(id => document.getElementById(id))\n .filter((el): el is HTMLElement => el !== null);\n\n if (elements.length === 0) return;\n\n // 以顶部偏移 120px 作为\"激活线\",选取距离激活线最近的上方/同位章节\n const computeActive = () => {\n const line = 120;\n let currentId = elements[0]?.id ?? '';\n for (const el of elements) {\n const top = el.getBoundingClientRect().top;\n if (top - line <= 0) {\n currentId = el.id;\n } else {\n break;\n }\n }\n // 滚到底部时,强制高亮最后一项\n if (window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - 4) {\n currentId = elements[elements.length - 1].id;\n }\n setActiveId(prev => (prev === currentId ? prev : currentId));\n };\n\n computeActive();\n window.addEventListener('scroll', computeActive, { passive: true });\n window.addEventListener('resize', computeActive);\n return () => {\n window.removeEventListener('scroll', computeActive);\n window.removeEventListener('resize', computeActive);\n };\n }, [allIds]);\n\n // 根据当前激活的子节点,找出其所属分组 id,用于同步高亮父级\n const activeGroupId = useMemo(() => {\n for (const g of NAV) {\n if (g.id === activeId) return g.id;\n if (g.children.some(c => c.id === activeId)) return g.id;\n }\n return activeId;\n }, [activeId]);\n\n return (\n
\n
\n \n 返回首页\n \n\n

开发者文档

\n

驰声语音评测 MCP · chivox-local-mcp

\n\n
\n {/* Sidebar */}\n \n\n {/* Content */}\n
\n\n {/* ══════ MCP 工作原理 ══════ */}\n \n\n \n

\n 大模型(GPT / Claude / Gemini / 通义千问 等)本质上是文字大脑:它擅长读和写,但天生听不到音频、打不开你的数据库、调不通第三方 API。\n

\n

\n MCP(Model Context Protocol)是一套由 Anthropic 主导、业界共同推进的开放协议,它像一根\"对讲机\":让大模型可以在需要时主动去调用外部能力(工具、数据源、服务),然后把结果接回来继续对话。\n

\n
\n
\n
\n \n 没有 MCP 的做法\n
\n
    \n
  • · 研究评测服务的 REST 文档
  • \n
  • · 自己写鉴权 / 上传 / 轮询代码
  • \n
  • · 把结果序列化后塞进 prompt
  • \n
  • · 每换一个大模型都得重写一遍
  • \n
\n
\n
\n
\n \n 用驰声 MCP 之后\n
\n
    \n
  • · 填一行 MCP Server 地址
  • \n
  • · 大模型自动发现&调用评测工具
  • \n
  • · 换任何支持 MCP 的大模型都能用
  • \n
  • · 不写一行调用代码
  • \n
\n
\n
\n \n MCP 让\"接入语音评测\"从一个\"后端工程\"变成了一个\"配置项\"。这也是为什么 Cursor、Claude Desktop、Dify、Coze、字节豆包、飞书智能助手都已经原生支持 MCP。\n \n
\n\n \n

\n 想象一个具体场景:一位开发者用 Claude 做了一款 「AI 雅思口语陪练」小程序,接入驰声语音评测 MCP。当用户发来一段录音,整个链路是这样的:\n

\n
\n \n

配置阶段(开发者 · 一次性)

\n

在 AI 后端的配置文件里填一行驰声 MCP Server 地址。大模型启动时自动发现:「我多了一个叫语音评测的工具」。

\n
\n \n

接收用户指令(终端用户)

\n

小程序用户发来一段自我介绍录音:「帮我听听,发音哪里有问题?」后端把「文字 + 录音链接」打包给大模型。

\n
\n \n

大模型自主思考(LLM · 最核心的魔法)

\n
\n 「用户让我听发音。」
\n 「但我只是文字大脑,我听不到。」
\n 「等等 —— 开发者给了我一个叫 chivox_voice_eval 的 MCP 工具!」\n
\n
\n \n

MCP 协议 · 自动调用(LLM → 驰声)

\n

大模型自动按 MCP 标准构造 tools/call 请求,把录音链接和参考文本发到驰声服务。开发者不需要写任何调用代码。

\n
\n \n

驰声服务处理(评测引擎)

\n

驰声对音频进行考试级打分,把结构化结果通过 MCP 原路返回:overall 85、/θ/ 音发音错误、流利度 88。

\n
\n \n

大模型整合并输出反馈(LLM)

\n

大模型把冷冰冰的分数翻译成温柔反馈:

\n
\n 「你的自我介绍很棒!综合 85 分 🎉 不过 think 这个词的 /θ/ 咬舌音不太标准,我们一起来练一下……」\n
\n
\n
\n \n 整条链路里,MCP 只出现在 ① 和 ④:① 让开发者一次性告诉大模型「你多了一个工具」,④ 让大模型可以自动调用它。这两步的标准化,就是 MCP 的全部价值。\n \n
\n\n \n

听起来复杂,但对开发者来说只需要两件事:

\n
\n
\n
\n 1\n 填一次 MCP 配置\n
\n

\n 在 AI 后端的配置里填入驰声 MCP Server 地址和 API Key,就这一次,以后新加评测能力完全免开发。\n

\n {`{\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"apiKey\": \"sk-••••••••••\"\n }\n}`}\n
\n
\n
\n 2\n 写一段 System Prompt\n
\n

\n 告诉大模型这个工具是做什么的、什么时候调用、结果怎么转成用户友好的反馈。\n

\n {`你是一位英语口语教练。\n当用户发来录音时:\n1. 调用 chivox_voice_eval 评分\n2. 聚焦 <70 分的音素家族\n3. 用高情商话术给出练习建议`}\n
\n
\n

\n 其余所有事情 —— 音频上传、鉴权、工具发现、调用时机、返回格式、结果整合 —— 都由 MCP 协议和大模型自己搞定。\n

\n
\n\n \n

根据你的技术栈,有三种等价的接入方式,底层都走完全相同的 MCP 协议:

\n\n {/* ── 姿势一:可视化 ── */}\n
\n
\n \n

姿势一 · 可视化拖拽(扣子 / Coze / 飞书智能助手)

\n
\n

\n 适合产品经理、运营、不写后端代码的开发者。整个过程像在手机上装 App。\n

\n
    \n
  1. 找到入口:在扣子平台的 「插件 / 工具」 配置区,点击「添加 MCP 服务」。
  2. \n
  3. 填两个字段(这也是你未来会从驰声这边拿到的):\n
    \n \n \n \n \n \n
    服务器地址https://speech-eval.site/mcp
    鉴权密钥sk-•••••••••• (由驰声分配,用于计费与识别)
    \n
    \n
  4. \n
  5. 平台自动发现能力:扣子会访问你填的地址,读取 MCP Server 自描述的\"说明书\"。瞬间明白:「这是个语音评测工具,需要传音频,会返发音分」。
  6. \n
  7. 右侧测试:在平台的聊天框里发一段语音,大模型就会自动调用工具。整个过程不需要写一行代码。
  8. \n
\n
\n\n {/* ── 姿势二:代码框架 ── */}\n
\n
\n \n

姿势二 · 代码框架配置(Dify / LangChain / 自研后端)

\n
\n

\n 适合做独立 APP / 小程序、用 Dify 或 LangChain 写 Agent 的极客开发者。核心就是往配置文件里加一段 JSON。\n

\n
    \n
  1. 打开配置文件(项目根目录下的 mcp.json 或框架指定的配置路径)。
  2. \n
  3. 在 mcpServers 下增加一个节点:\n {`{\n \"mcpServers\": {\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"env\": {\n \"API_KEY\": \"你的专属密钥\"\n }\n }\n }\n}`}\n
  4. \n
  5. 重启后端服务。大模型的底层调度器会在启动时自动连上驰声 MCP Server,把 16 种评测工具注册成随时待命的 tools。
  6. \n
  7. 触发调用:用户发来录音后,大模型看到 system prompt 的引导,自动选择合适的工具(单词/句子/段落/半开放)调用。
  8. \n
\n
\n\n {/* ── 姿势三:Function Calling 直连(分 A / B 两种做法) ── */}\n
\n
\n \n

姿势三 · 原生 Function Calling(豆包 / DeepSeek / OpenAI 兼容 API)

\n
\n

\n 适合不用任何 Agent 框架、直接调用 LLM API 的后端开发者。豆包 1.5+ / DeepSeek / GPT / Qwen 等模型都走标准 chat.completions 的 tools 参数。这里又分 A / B 两种做法,B 才是生产推荐。\n

\n\n \n 常见疑问:\"要不要手写一个 tool 定义?\"
\n — 姿势一 / 二不用(Coze、Dify、火山方舟控制台、Claude Desktop 会自动从 MCP Server 拉工具列表)。
\n — 姿势三看你选 A 还是 B:A 要手写,B 用 MCP 客户端库自动拉。\n
\n\n {/* ── 3-A:手写 tool schema ── */}\n
\n
\n

3-A · 手写 tool schema(最快验证,不推荐生产)

\n 快速 Demo\n
\n

\n 自己写一段 JSON Schema 告诉豆包\"有个工具叫 xxx,参数长这样\",豆包返回 tool_call 后你再手动去调驰声 MCP。缺点:驰声有 16 个评测工具,你每加一个题型都要改代码。\n

\n {`import os, json\nfrom openai import OpenAI\n\nclient = OpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv('ARK_API_KEY'),\n)\n\n# ─── 手写一段 tool schema(不推荐:16 个工具就要写 16 段)───\ntools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": \"en_word_eval\",\n \"description\": \"英语单词发音评测。当用户让你评价英语发音并提供录音链接时调用。\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"audio_url\": {\"type\": \"string\", \"description\": \"录音 URL\"},\n \"reference_text\": {\"type\": \"string\", \"description\": \"参考文本,如 Apple\"},\n },\n \"required\": [\"audio_url\", \"reference_text\"]\n }\n }\n}]\n\nresp = client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,拿到评测结果后温柔地反馈,不要直接报分数。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n)\n\nmsg = resp.choices[0].message\nif msg.tool_calls:\n args = json.loads(msg.tool_calls[0].function.arguments)\n # ↓↓↓ 这里手动调驰声 MCP,再把结果回填给豆包做第二趟 ↓↓↓\n # result = requests.post(\"https://speech-eval.site/mcp\", json={...})`}\n
\n\n {/* ── 3-B:MCP 自动发现 ── */}\n
\n
\n

\n 3-B · 用 MCP 客户端库自动发现 \n

\n 生产推荐\n
\n

\n 启动时连上驰声 MCP Server,调一次 tools/list,把 16 个评测工具自动转成 Function Calling 的 tools 格式。驰声加新工具,你代码不用改。这才是 MCP 协议的真正价值。\n

\n {`import asyncio, os\nfrom openai import AsyncOpenAI\nfrom mcp import ClientSession\nfrom mcp.client.streamable_http import streamablehttp_client\n\nclient = AsyncOpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv(\"ARK_API_KEY\"),\n)\n\nasync def main():\n # ─── 1. 连驰声 MCP Server,自动拉取全部 16 个工具 ───\n async with streamablehttp_client(\n \"https://speech-eval.site/mcp\",\n headers={\"Authorization\": f\"Bearer {os.getenv('CHIVOX_KEY')}\"},\n ) as (read, write, _):\n async with ClientSession(read, write) as session:\n await session.initialize()\n mcp_tools = (await session.list_tools()).tools # ← 一行拿到全部工具\n\n # ─── 2. MCP schema → OpenAI Function Calling schema ───\n tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema, # MCP 直接给 JSON Schema\n }\n } for t in mcp_tools]\n\n # ─── 3. 正常调豆包,tools 由 MCP 动态注入 ───\n resp = await client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,收到评测结果后温柔反馈。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n )\n\n # ─── 4. 折返跑:豆包选好工具后,直接走 MCP 调驰声 ───\n msg = resp.choices[0].message\n if msg.tool_calls:\n call = msg.tool_calls[0]\n result = await session.call_tool(\n call.function.name,\n arguments=__import__(\"json\").loads(call.function.arguments),\n )\n # 把 result 回填给豆包做第二趟 chat.completions 即可\n\nasyncio.run(main())`}\n

\n 想要更省心?直接用 官方 mcp python sdk、mcp-use、openai-agents,或火山官方 Arkitect 高代码 SDK,它们都把上面这段\"MCP → Function Calling\"的桥接封装好了。\n

\n
\n
\n\n \n 三种姿势走的是完全相同的 MCP 协议,能力完全等价。选型建议:产品经理 / 原型验证用姿势一(Coze 填表单);AI 客户端用户用姿势二(Cursor / Claude Desktop 填 mcp.json);后端生产服务用姿势三-B(MCP 客户端库自动发现工具,不要手写 tool schema)。\n \n
\n\n
\n\n {/* ══════ 快速开始 ══════ */}\n \n\n \n

chivox-local-mcp 是驰声语音评测的 MCP 本地代理,通过 Model Context Protocol 将远程驰声评测服务桥接到本地,让 AI 助手(Claude Desktop、Claude Code、Cursor 等)直接调用语音评测能力。

\n

它支持两种评测模式,覆盖从即时交互到批量处理的全部场景:

\n
\n
\n
\n \n 实时录音评测\n
\n

通过麦克风边录边评,音频以 WebSocket 流式推送,无需生成中间文件,延迟更低、体验更佳。

\n
\n
\n
\n \n 音频文件评测\n
\n

支持本地文件路径、Base64 编码、URL 三种输入,适合已有音频的批量评测场景。

\n
\n
\n 当前支持 16 种评测工具:英文 10 种(单词、句子、段落、纠音、自然拼读、口语选择、半开放题等)+ 中文 6 种(汉字、拼音、词句、段落、有限分支、AI Talk)。\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n
依赖版本说明
Node.js{'>'}= 18运行时必须
SoXany仅实时录音功能需要(处理麦克风音频流)
\n
\n

安装 SoX(仅在使用实时录音时需要):

\n {`# macOS\nbrew install sox\n\n# Ubuntu / Debian\nsudo apt-get install sox`}\n
\n\n \n

方式一:npm 全局安装(推荐)

\n {`npm install -g chivox-local-mcp`}\n\n

方式二:npx 免安装运行

\n {`MCP_REMOTE_URL=http://your-server:8080 npx chivox-local-mcp`}\n\n

方式三:从源码构建

\n {`git clone https://git.chivox.com/CLOUD_DEV/cvx_local_mcp.git\ncd cvx_local_mcp\nbash scripts/build.sh`}\n
\n\n \n \n \n
\n\n {/* ══════ 接入 · 直接用(零代码) ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 不用写代码、不用装 SDK,只在客户端的「MCP 配置」或「扩展」里填一段 JSON / URL
  • \n
  • 保存后 LLM 自动发现 16 个评测工具,并在对话 / Agent 中自主调用
  • \n
  • 覆盖 IDE 编程助手、桌面 AI 客户端、企业 AI 工作台、可视化 Bot / 工作流平台四大生态
  • \n
\n
\n\n\n \n
    \n
  1. 打开 Cursor 设置(Cmd + ,)
  2. \n
  3. 左侧选择 MCP(或搜索 "MCP")
  4. \n
  5. 点击 Add new MCP server
  6. \n
  7. 填写配置并保存:
  8. \n
\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n}`}\n Cursor 使用远程 Streamable HTTP 模式直连,无需安装本地代理。如需实时录音功能,请使用下方 Claude Desktop 的本地代理配置。\n
\n\n \n

编辑配置文件(macOS:~/Library/Application Support/Claude/claude_desktop_config.json):

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"chivox-local-mcp\",\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\",\n \"MCP_API_KEY\": \"your-api-key\"\n }\n }\n }\n}`}\n

如果是从源码构建:

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/cvx_local_mcp/dist/index.js\"],\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\"\n }\n }\n }\n}`}\n Claude Desktop 使用本地代理模式(stdio),支持实时录音评测。本地代理会自动桥接远程服务。\n
\n\n \n {`# npm 全局安装后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 chivox-local-mcp\n\n# 源码构建后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 node /path/to/cvx_local_mcp/dist/index.js`}\n \n\n \n

除了 Cursor 和 Claude Code,主流的 AI 编程 IDE 都原生支持 MCP。以下客户端使用完全一致的 Streamable HTTP 配置,区别只在配置入口:

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
客户端配置入口备注
Windsurf (Codeium)Settings → Cascade → MCP Servers直接贴下方 JSON
Zed~/.config/zed/settings.json 的 context_serversAssistant Panel 自动发现
Continue (VS Code / JetBrains)config.yaml 的 mcpServersv0.9+ 支持
通义灵码 / CodeGeeX / 文心快码插件设置 → MCP 服务2026 Q1 起陆续支持
Cline (原 Claude Dev)MCP Servers 面板 → 编辑配置VS Code 扩展
\n
\n {`{\n \"mcpServers\": {\n \"chivox-speech-eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n }\n }\n}`}\n 所有 IDE 类客户端都走远程 Streamable HTTP,零本地依赖。需要实时录音才需切到 Claude Desktop 的本地代理模式。\n
\n\n \n

扣子(Coze)是字节跳动推出的 AI 应用开发平台,支持通过 MCP 扩展为 Agent 赋予外部工具能力。接入驰声语音评测后,你可以构建口语练习 Bot、发音诊断助手等应用。

\n

方式一:扣子空间 MCP 扩展(推荐)

\n
    \n
  1. 打开 扣子空间(space.coze.cn)
  2. \n
  3. 在对话框下方点击 「添加扩展」
  4. \n
  5. 选择 「自定义」 标签,点击添加新的 MCP 服务
  6. \n
  7. 填入以下配置信息:
  8. \n
\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
名称chivox-speech-eval
传输类型streamable-http
URLhttps://speech-eval.site/mcp
\n
\n
    \n
  1. 保存后,在对话中输入 「帮我评测这段英文发音」 即可触发 Agent 调用
  2. \n
\n 添加 MCP 扩展后,扣子空间的 Agent 会自动识别并调用评测工具。你可以在 Agent 的思考过程中看到具体的工具调用细节。\n\n

方式二:在 Coze 开发平台的 Bot 中使用

\n
    \n
  1. 进入 Coze 开发平台,创建或编辑 Bot
  2. \n
  3. 在 Bot 的 「插件」 或 「工具」 面板中,添加 MCP 工具
  4. \n
  5. 选择 Streamable HTTP 类型,填入 URL:https://speech-eval.site/mcp
  6. \n
  7. Bot 将自动发现所有可用的评测工具(如 evaluate_english_word 等)
  8. \n
  9. 在 Bot 的人设提示词中,添加语音评测相关的引导语
  10. \n
\n {`你是一位专业的英语口语教练。当用户上传音频并请求评测时:\n1. 使用 evaluate_english_word / evaluate_english_sentence 等工具进行评测\n2. 根据评测结果(overall、accuracy、fluency 等分数)给出专业分析\n3. 针对得分较低的维度提供具体改进建议\n4. 鼓励用户持续练习`}\n
\n\n \n

如果你需要在 Coze 工作流中集成语音评测能力,可以通过 HTTP Request 节点调用评测 API:

\n\n

步骤 1:上传音频

\n

在工作流中添加一个 HTTP Request 节点,配置如下:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
配置项值
方法POST
URLhttps://speech-eval.site/upload
Content-Typeaudio/mp3
Body音频文件二进制数据
\n
\n

响应中获取 {'{{audioId}}'},传递给下一步。

\n\n

步骤 2:调用评测

\n

添加第二个 HTTP Request 节点,通过 MCP 接口调用评测工具:

\n {`{\n \"jsonrpc\": \"2.0\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"evaluate_english_sentence\",\n \"arguments\": {\n \"audioId\": \"{{audioId}}\",\n \"sentence\": \"{{ref_text}}\"\n }\n },\n \"id\": 1\n}`}\n\n

步骤 3:处理结果

\n

评测结果通过 JSON 格式返回,可使用 Coze 的 代码节点 或 LLM 节点 对结果进行解析和二次处理(如生成学习建议、计算进步趋势等)。

\n\n 工作流方式适合需要固定流程的场景(如批量评测、定时任务、与其他系统联动)。如果是交互式场景,推荐使用上方的 MCP 扩展方式,Agent 会自动选择合适的工具。\n\n
\n

完整工作流示意

\n
\n 用户输入音频\n →\n HTTP: 上传音频\n →\n HTTP: 调用评测\n →\n LLM: 分析结果\n →\n 输出反馈\n
\n
\n
\n\n \n

这一类是面向「上班族」的企业 / 日常 AI 助手,产品形态是个聊天框 + 插件市场 / 扩展面板。接入后,员工在 App 里打字「帮我评一下这段录音」就能自动触发驰声评测,不用写任何代码。

\n\n
\n
\n

豆包(Doubao)App / 桌面版

\n

字节跳动官方 AI 助手,2026 年起桌面版支持 MCP 扩展。

\n
    \n
  1. 桌面版设置 → 「智能体扩展」 → 添加 MCP 服务
  2. \n
  3. 类型选 streamable-http,URL 填 https://speech-eval.site/mcp
  4. \n
  5. 对话中直接说「帮我评测」即可自动调用
  6. \n
\n
\n\n
\n

飞书智能伙伴(My AI)

\n

飞书企业 AI,支持以 MCP / Function Calling 挂载外部工具给团队 Bot。

\n
    \n
  1. 飞书开发者后台 → 创建应用 → 「AI 能力 / 智能伙伴」
  2. \n
  3. 在「工具」中选 外部 MCP 服务,填入上方 URL
  4. \n
  5. 把智能伙伴拉进群聊,@ 它提交音频即可评测
  6. \n
\n
\n\n
\n

WorkBuddy / 企业智能助手

\n

字节 WorkBuddy、腾讯会议 AI、企业微信智能助手等企业 AI 工作台场景。

\n
    \n
  1. 在工作台的「技能 / 扩展」后台新增一个 MCP 连接器
  2. \n
  3. 传输协议选 Streamable HTTP,地址填 https://speech-eval.site/mcp
  4. \n
  5. 把技能发布到指定部门 / 群组,HR、培训、销售口语陪练场景即可直接用
  6. \n
\n
\n\n
\n

钉钉 AI 助理 / 通义千问 App

\n

阿里生态:钉钉 AI 助理支持自定义插件,通义 App 可通过「AI 工具箱」挂载 MCP。

\n
    \n
  1. 钉钉开发者后台 → AI 助理 → 「插件开发 / MCP 接入」
  2. \n
  3. 选 HTTP Streamable,填入驰声 MCP URL 并开启鉴权(可选)
  4. \n
  5. 在钉钉群 @AI 助理上传音频,自动返回评测卡片
  6. \n
\n
\n
\n\n 典型场景 · 小龙虾们的共同剧本:销售口语陪练 → 外语培训 → 主持 / 播音岗位考核 → K12 英语作业批改 → 客服话术复盘。这些「上班族 AI 工作台」接入驰声 MCP 后,员工 / 学员只要对着话筒说话,AI 就能自动打分并给出个性化改进建议,运营 / 培训 / 教研团队零开发即可上线。\n
\n\n \n

如果你需要把语音评测编排进多步业务流(例如:学员录音 → 评测 → 生成错题集 → 推送到 CRM),可视化工作流平台比聊天 Bot 更合适。

\n\n
\n
\n

Dify

\n

开源 LLMOps,v0.15+ 原生 MCP 工具。

\n
    \n
  • 「工具」→「自定义 MCP」→ 填 URL
  • \n
  • 在 Chatflow / Workflow 节点里直接拖用
  • \n
\n
\n
\n

n8n

\n

工作流自动化,用 MCP Client 节点。

\n
    \n
  • 添加 MCP Client 节点
  • \n
  • Transport 选 HTTP Stream,URL 贴驰声地址
  • \n
  • Tool 下拉自动列出 16 个评测能力
  • \n
\n
\n
\n

Flowise / LangFlow

\n

可视化 LangChain Agent 编排。

\n
    \n
  • 拖出 MCP Tool 节点
  • \n
  • 连到 AgentExecutor 即可
  • \n
\n
\n
\n\n 可视化平台的好处是流程可追溯、可回放,适合教育机构 / 培训部门做批量评测 + 报表导出;缺点是单步延迟略高于直接 MCP 调用,对延迟敏感的交互场景建议用 Cursor / Claude Desktop 直连。\n
\n\n \n

任何遵循 MCP 协议的客户端都可以接入,统一使用以下配置:

\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
传输类型streamable-http
URLhttps://speech-eval.site/mcp
鉴权(可选)Header:Authorization: Bearer <MCP_API_KEY>
\n
\n

还没找到你用的客户端?任何支持 Model Context Protocol 的终端都通用。找不到入口?下一小节「编程用 MCP」里用 SDK 直接接即可。

\n
\n
\n\n {/* ══════ 接入 · 编程用 MCP ══════ */}\n \n\n
\n

这一类接入的共同特征

\n
    \n
  • 你在写一段真正的后端服务:一个 Agent Worker、一个 API、一个自动化脚本
  • \n
  • 业务里的「语音评测」是其中一个步骤,需要由代码 决定何时调用、如何解析结果
  • \n
  • 三种主流写法:① 官方 MCP 客户端库 → ② Agent 框架自动桥接 → ③ 退化到 chat.completions + tools 参数
  • \n
\n

💡 强烈推荐①或②:驰声有 16 个评测工具,让 MCP 自动注入 tool schema,每新增一个题型不用改一行业务代码。

\n
\n\n \n

最底层、也最推荐的方式。由 Anthropic 官方维护,一次连接自动拿到全部工具的 JSON Schema,然后交给任意 LLM。

\n\n

Python:mcp

\n {`# pip install mcp openai\nimport asyncio, os\nfrom openai import OpenAI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\n\nMCP_URL = \"https://speech-eval.site/mcp\"\nllm = OpenAI(api_key=os.getenv(\"DOUBAO_KEY\"),\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\") # 豆包 / DeepSeek / OpenAI 同构\n\nasync def main(audio_id: str, ref: str):\n async with streamablehttp_client(MCP_URL) as (reader, writer, _):\n async with ClientSession(reader, writer) as sess:\n await sess.initialize()\n\n tools = await sess.list_tools()\n openai_tools = [{\n \"type\": \"function\",\n \"function\": {\"name\": t.name, \"description\": t.description,\n \"parameters\": t.inputSchema},\n } for t in tools.tools]\n\n resp = llm.chat.completions.create(\n model=\"doubao-1-5-pro-32k\",\n messages=[{\"role\": \"user\",\n \"content\": f\"帮我评测 audioId={audio_id},参考文本:{ref}\"}],\n tools=openai_tools,\n )\n\n for call in resp.choices[0].message.tool_calls or []:\n result = await sess.call_tool(call.function.name,\n arguments=eval(call.function.arguments))\n print(call.function.name, \"→\", result.content[0].text[:200])\n\nasyncio.run(main(\"abc123\", \"I think therefore I am\"))`}\n\n

TypeScript / Node.js:@modelcontextprotocol/sdk

\n {`// npm i @modelcontextprotocol/sdk openai\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport OpenAI from \"openai\";\n\nconst mcp = new Client({ name: \"chivox-biz\", version: \"1.0.0\" });\nawait mcp.connect(new StreamableHTTPClientTransport(new URL(\"https://speech-eval.site/mcp\")));\n\nconst { tools } = await mcp.listTools();\nconst openai = new OpenAI({ apiKey: process.env.DEEPSEEK_KEY, baseURL: \"https://api.deepseek.com\" });\n\nconst resp = await openai.chat.completions.create({\n model: \"deepseek-chat\",\n messages: [{ role: \"user\", content: \"评测 audioId=abc123, 参考 I think therefore I am\" }],\n tools: tools.map(t => ({ type: \"function\", function: {\n name: t.name, description: t.description, parameters: t.inputSchema\n }})),\n});\n\nfor (const call of resp.choices[0].message.tool_calls ?? []) {\n const r = await mcp.callTool({ name: call.function.name,\n arguments: JSON.parse(call.function.arguments) });\n console.log(call.function.name, r.content);\n}`}\n 这种写法 LLM 供应商可换(豆包 / DeepSeek / GPT / Qwen / Moonshot),工具自动更新(驰声新增题型无需改业务代码),适合生产后端。\n
\n\n \n

如果项目已经在用 Agent 框架,几行 adapter 就能把驰声 MCP 塞进去,框架本身会接管 tool-calling 循环、重试、日志。

\n\n
\n
\n

LangChain / LangGraph(Python)

\n {`# pip install langchain-mcp-adapters langgraph\nfrom langchain_mcp_adapters.client import MultiServerMCPClient\nfrom langgraph.prebuilt import create_react_agent\n\nclient = MultiServerMCPClient({\n \"chivox\": {\n \"transport\": \"streamable_http\",\n \"url\": \"https://speech-eval.site/mcp\",\n }\n})\ntools = await client.get_tools()\n\nagent = create_react_agent(\"openai:gpt-4o-mini\", tools)\nresult = await agent.ainvoke({\"messages\":\n [(\"user\", \"评测 audioId=abc123 参考 think\")]})\nprint(result[\"messages\"][-1].content)`}\n
\n\n
\n

Mastra(TypeScript)

\n {`// npm i @mastra/core @mastra/mcp\nimport { MCPClient } from \"@mastra/mcp\";\nimport { Agent } from \"@mastra/core/agent\";\nimport { openai } from \"@ai-sdk/openai\";\n\nconst mcp = new MCPClient({ servers: {\n chivox: { url: new URL(\"https://speech-eval.site/mcp\") }\n}});\n\nexport const speechCoach = new Agent({\n name: \"speech-coach\",\n instructions: \"你是口语教练,用 chivox 工具评测并给改进建议。\",\n model: openai(\"gpt-4o-mini\"),\n tools: await mcp.getTools(),\n});`}\n
\n\n
\n

OpenAI Agents SDK(Python)

\n {`# pip install openai-agents\nfrom agents import Agent, Runner\nfrom agents.mcp import MCPServerStreamableHttp\n\nchivox = MCPServerStreamableHttp(\n params={\"url\": \"https://speech-eval.site/mcp\"},\n name=\"chivox-speech-eval\",\n)\n\nasync with chivox:\n agent = Agent(name=\"coach\",\n instructions=\"专业口语教练\",\n mcp_servers=[chivox])\n r = await Runner.run(agent, \"评测 audioId=abc123\")\n print(r.final_output)`}\n
\n\n
\n

LlamaIndex / AutoGen / CrewAI

\n

这些框架都有官方或社区 MCP adapter,用法与上述类似:

\n
    \n
  • LlamaIndex:llama-index-tools-mcp
  • \n
  • AutoGen:autogen-ext[mcp]
  • \n
  • CrewAI:crewai-tools 的 MCPServerAdapter
  • \n
  • Spring AI(Java):spring-ai-mcp-client
  • \n
\n
\n
\n
\n\n \n

当你用的 LLM SDK 还没有原生 MCP 支持(比如老版本的火山方舟 / 百度千帆 / 通义 DashScope),退化方案是:用 MCP 客户端一次性拉到 tool schema,然后按 OpenAI Function Calling 格式喂给 LLM。

\n {`# 适用:豆包(火山方舟)/ DeepSeek / Qwen / Moonshot / GLM 等 OpenAI 兼容 API\n# 核心思路:MCP 列工具 → 转 OpenAI tools → LLM 决策 → MCP 执行 → 回填\n\nasync with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as mcp:\n await mcp.initialize()\n tools = (await mcp.list_tools()).tools\n\n # ① 用 MCP 拉到的 schema 自动转 OpenAI 格式\n oa_tools = [{\"type\": \"function\", \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema,\n }} for t in tools]\n\n # ② 喂给豆包\n messages = [{\"role\": \"user\", \"content\": \"评测一下 audioId=abc123\"}]\n resp = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages, tools=oa_tools,\n )\n\n # ③ LLM 回 tool_calls → 折返跑到 MCP 执行\n msg = resp.choices[0].message\n if msg.tool_calls:\n messages.append(msg)\n for c in msg.tool_calls:\n result = await mcp.call_tool(\n c.function.name, arguments=json.loads(c.function.arguments))\n messages.append({\"role\": \"tool\", \"tool_call_id\": c.id,\n \"content\": result.content[0].text})\n # ④ 再喂一轮,让豆包根据评测结果产出自然语言诊断\n final = doubao.chat.completions.create(\n model=\"doubao-1-5-pro-32k\", messages=messages)\n print(final.choices[0].message.content)`}\n 千万别手写 tool schema!驰声 16 个评测工具每个都有几十个字段,手写既容易错也难维护。一定用 MCP list_tools() 动态拿。\n
\n\n \n

大部分落地场景其实是:你已有一个业务后端(教育 SaaS / 培训系统 / 客服平台),只需要新增一个「语音评测」能力。推荐架构:

\n\n
\n
\n 前端录音 / 上传\n →\n 业务后端\n →\n MCP Client(常驻连接)\n →\n 驰声 MCP\n ↘\n LLM(诊断 / 出题)\n
\n
\n\n

FastAPI 示例(生产最小骨架)

\n {`from fastapi import FastAPI\nfrom mcp.client.streamable_http import streamablehttp_client\nfrom mcp import ClientSession\nfrom contextlib import asynccontextmanager\n\nmcp_session: ClientSession | None = None\n\n@asynccontextmanager\nasync def lifespan(app):\n global mcp_session\n async with streamablehttp_client(\"https://speech-eval.site/mcp\") as (r, w, _):\n async with ClientSession(r, w) as s:\n await s.initialize()\n mcp_session = s\n yield\n mcp_session = None\n\napp = FastAPI(lifespan=lifespan)\n\n@app.post(\"/api/evaluate\")\nasync def evaluate(audio_id: str, ref_text: str):\n # 直接选一个最合适的工具执行(不经 LLM,延迟最低)\n r = await mcp_session.call_tool(\"evaluate_english_sentence\",\n {\"audioId\": audio_id, \"sentence\": ref_text})\n return {\"result\": r.content[0].text}`}\n\n 关键优化:① MCP 连接在 lifespan 里做成长连接,不要每次请求都重连;② 对延迟敏感的场景可以「跳过 LLM 直接调 tool」,把 LLM 放到「生成诊断报告」那一步。\n
\n\n
\n

方案选型速查

\n
\n \n \n \n \n \n \n \n \n \n \n \n
场景推荐方案
AI 对话 / Copilot 类产品,LLM 供应商可能会换① 官方 MCP 客户端库
已有 LangChain / Mastra / Agents SDK 技术栈② Agent 框架 + adapter
火山方舟 / 千帆控制台直连,最小侵入③ chat.completions + tools
教育 SaaS / 培训 / 客服等业务后端集成④ 自研后端 Agent
\n
\n
\n
\n\n {/* ══════ 评测模式 ══════ */}\n \n\n \n

通过本地麦克风实时录音,音频以 WebSocket 流式推送到评测服务,无需生成中间文件。这是最灵活、延迟最低的评测方式,特别适合交互式口语练习场景。

\n 实时录音评测需要安装 SoX 并使用本地代理模式(Claude Desktop / Claude Code)。Cursor 等远程直连模式暂不支持实时录音。\n\n

需要按顺序调用三个工具:

\n\n
\n
\n

create_stream_session — 创建流式评测会话

\n \n

返回 session_id,后续步骤需使用。

\n
\n\n
\n

start_recording — 开始麦克风录音

\n \n

调用后自动启动麦克风,音频通过 WebSocket 实时推送到评测服务。

\n
\n\n
\n

stop_recording — 停止录音并获取结果

\n \n
\n
\n
\n\n \n
\n \n

用户:"请评测我的英文发音,文本是 Hello"

\n

AI 调用 create_stream_session(core_type="en.word.score", ref_text="Hello")

\n

→ 获得 session_id

\n
\n \n

AI 调用 start_recording(session_id=xxx)

\n

麦克风开始录音,音频通过 WebSocket 实时推送到评测服务

\n
\n \n

用户说完后告知 AI "结束"

\n

AI 调用 stop_recording(session_id=xxx)

\n

→ 返回评测结果(总分、准确度、流利度、音素得分等)

\n
\n
\n
\n\n \n

适用于已有音频文件的评测场景,支持三种输入方式:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
参数说明适用场景
audio_file_path本地文件路径代理自动读取并转为 Base64,最便捷
audio_base64Base64 编码数据已有编码数据时使用
audio_url音频文件 URL音频托管在云存储时使用
\n
\n 推荐使用 audio_file_path,只需传入本地文件路径,代理会自动处理编码和上传。\n

支持的音频格式:mp3, wav, ogg, m4a, aac, pcm

\n

限制:单文件最大 50MB,大于 500KB 的文件自动压缩为 16kHz / 单声道 / 32kbps。

\n
\n
\n\n {/* ══════ API 参考 ══════ */}\n \n\n \n \n\n

通用参数:所有英文评测工具均支持以下参数。

\n \n
\n\n \n \n\n

通用参数:

\n \n
\n\n \n

所有评测工具返回统一的结构化结果:

\n {`{\n \"overall\": 85,\n \"accuracy\": 82,\n \"pron\": 88,\n \"fluency\": {\n \"overall\": 78,\n \"speed\": 65,\n \"pause\": 2\n },\n \"integrity\": 95,\n \"details\": [\n {\n \"char\": \"hello\",\n \"score\": 85,\n \"phone\": [\n { \"phoneme\": \"h\", \"score\": 90 },\n { \"phoneme\": \"ɛ\", \"score\": 82 },\n { \"phoneme\": \"l\", \"score\": 88 },\n { \"phoneme\": \"oʊ\", \"score\": 80 }\n ]\n }\n ]\n}`}\n
\n \n \n \n \n \n \n \n {[\n ['overall', '0–100', '综合总分,反映整体语音质量'],\n ['accuracy', '0–100', '准确度,音素级别的发音准确率'],\n ['pron', '0–100', '发音得分,整体发音质量评价'],\n ['fluency.overall', '0–100', '流利度,语流的自然度与平滑度'],\n ['fluency.speed', '0–100', '语速得分,每分钟词/音节计量'],\n ['fluency.pause', 'number', '不自然停顿次数'],\n ['integrity', '0–100', '完整度,是否完整朗读了参考文本'],\n ['details[].phone[]', 'array', '每个音素的独立评分,可定位具体弱项'],\n ['details[].stress[]', 'array', '重音得分,检测重弱读是否正确'],\n ].map(([field, range, desc]) => (\n \n \n \n \n \n ))}\n \n
字段范围说明
{field}{range}{desc}
\n
\n
\n\n \n
\n \n \n \n \n \n \n \n {[\n ['音频 ID 无效或已过期', '音频上传后 5 分钟内有效,评测完成后自动删除', '重新上传音频'],\n ['服务器繁忙', '当前请求过多,排队已满', '稍后重试,使用指数退避策略'],\n ['存储空间已满', '服务器临时音频存储已满', '稍后重试,系统会自动清理'],\n ['音频格式不支持', '上传了不支持的文件类型', '使用 mp3/wav/ogg/m4a/aac/pcm'],\n ['音频时长超限', '超过该题型最大时长限制', '裁剪音频后重试'],\n ['WebSocket 连接断开', '网络不稳定导致流式连接中断', '代理会自动重连,如持续失败请检查网络'],\n ].map(([scene, reason, fix]) => (\n \n \n \n \n \n ))}\n \n
场景原因解决方式
{scene}{reason}{fix}
\n
\n
\n
\n\n {/* ══════ 架构说明 ══════ */}\n \n\n \n
\n
\n

AI 客户端

\n

Claude Desktop
Claude Code
Cursor

\n
\n
\n

⇄

\n

stdio

\n
\n
\n

chivox-local-mcp

\n

本地代理
SoX 录音

\n
\n
\n

⇄

\n

HTTP / WS

\n
\n
\n

Remote Chivox

\n

MCP Server
评测引擎

\n
\n
\n
\n\n \n
    \n
  • \n \n stdio — AI 客户端通过标准输入输出与本地代理通信,这是 MCP 的标准传输方式\n
  • \n
  • \n \n HTTP — 音频文件评测工具通过 HTTP 代理到远程服务,适用于非流式场景\n
  • \n
  • \n \n WebSocket — 实时录音音频通过 WebSocket 流式推送,支持断线自动重连\n
  • \n
\n
\n
\n\n {/* ══════ 示例代码 ══════ */}\n \n\n \n {`import requests\n\nwith open('audio.mp3', 'rb') as f:\n r = requests.post(\n 'https://speech-eval.site/upload',\n data=f,\n headers={'Content-Type': 'audio/mp3'}\n )\n\nresult = r.json()\nprint(f\"audioId: {result['audioId']}\")\nprint(f\"size: {result['size']} bytes\")\nprint(f\"expires: {result['expiresIn']}\")`}\n \n\n \n {`const fs = require('fs');\n\nconst audioData = fs.readFileSync('audio.mp3');\n\nconst res = await fetch('https://speech-eval.site/upload', {\n method: 'POST',\n headers: { 'Content-Type': 'audio/mp3' },\n body: audioData,\n});\n\nconst result = await res.json();\nconsole.log('audioId:', result.audioId);`}\n \n \n\n {/* ══════ 最佳实践 ══════ */}\n \n\n \n

以下模板帮助你引导 LLM 对评测结果进行深度分析:

\n
\n
\n

发音诊断

\n {`你是一位专业的英语口语教练。请根据以下 MCP 评测结果分析学生的发音表现:\n\n评测结果:{evaluation_result}\n\n请按以下格式输出:\n1. 总体评价(一句话)\n2. 优势项(>80 分的指标)\n3. 弱项分析(<70 分的指标,定位到具体音素)\n4. 针对性练习建议(2-3 条可操作的建议)`}\n
\n
\n

练习生成

\n {`根据以下弱项列表,为学生生成针对性的口语练习材料:\n\n弱项:{weak_points}\n\n请生成:\n1. 3 个绕口令(专门针对弱项音素)\n2. 5 个包含目标音素的常用短句(标注重音和连读)\n3. 1 段跟读练习段落(50-80 词)`}\n
\n
\n

学习报告

\n {`请根据学生近 7 天的评测历史生成学习报告:\n\n评测历史:{history}\n\n报告要求:\n1. 整体趋势(进步/持平/退步)\n2. 各维度变化(准确度、流利度、语速)\n3. 本周最大进步项\n4. 下周重点练习建议\n5. 鼓励性总结`}\n
\n
\n
\n\n \n
    \n
  • 音频过期:上传后 5 分钟内有效。建议在上传后 3 分钟内完成评测。
  • \n
  • 服务繁忙:使用指数退避策略重试(1s → 2s → 4s),最多 3 次。
  • \n
  • 录音中断:WebSocket 断线后代理会自动重连。如持续失败,检查网络连接和 SoX 安装。
  • \n
\n
\n\n \n
    \n
  • 优先使用流式评测:实时录音模式跳过了文件上传环节,端到端延迟比文件评测低 30-50%。
  • \n
  • 音频压缩:文件评测时,上传前将音频转为 16kHz 单声道 mp3,可减少 60-80% 的上传体积。
  • \n
  • 选择合适的工具:单词评测比段落评测快 3-5 倍。如只需单词级分数,不要用句子评测。
  • \n
  • 本地文件路径最便捷:使用 audio_file_path 参数传入本地路径,代理自动处理编码,无需手动转 Base64。
  • \n
\n
\n
\n\n {/* ══════ 服务信息 ══════ */}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n
端点方法说明
/uploadPOST音频文件上传
/mcpPOSTMCP JSON-RPC 接口(Streamable HTTP)
/healthGET健康检查
\n
\n
\n \n
\n \n \n \n \n \n \n \n {[\n ['存储限制', '500MB', '最大音频存储空间'],\n ['最大排队', '10', '等待处理的请求数'],\n ['最大并发', '3', '同时处理的评测数'],\n ['音频有效期', '5 分钟', '上传后未评测自动过期'],\n ['文件大小限制', '50MB', '单个音频文件最大'],\n ].map(([k, v, d]) => (\n \n ))}\n \n
配置项默认值说明
{k}{v}{d}
\n
\n
\n \n
\n {[\n { ver: 'v3.0.0', date: '2026-04-16', desc: '新增本地代理模式,支持实时录音流式评测,工具扩展至 16 种' },\n { ver: 'v2.3.0', date: '2026-03-25', desc: '支持 HTTPS,域名 speech-eval.site' },\n { ver: 'v2.2.0', date: '2026-03-24', desc: '添加 MCP 配置指南(Cursor / Claude Desktop)' },\n { ver: 'v2.1.0', date: '2026-03-24', desc: '简化上传流程,统一使用 HTTP API' },\n { ver: 'v2.0.0', date: '2026-03-24', desc: '初始版本,支持多种评测类型' },\n ].map(l => (\n
\n {l.ver}\n {l.date}\n {l.desc}\n
\n ))}\n
\n
\n
\n\n
\n
\n
\n
\n );\n}\n"}, "6b999e0c93041f270d4893d5f99ccb51cdfdbc00": {"t": 1785765809.9466977, "n": 67953, "h": "56162107c7a05525", "c": "'use client';\n\nimport { useState, useEffect, useMemo } from 'react';\nimport { Link } from '@/i18n/routing';\nimport { ArrowLeft, BookOpen, Code2, Zap, FileText, Copy, Check, Terminal, Globe, Mic, MessageSquare, BarChart3, AlertTriangle, Lightbulb, Radio, FolderOpen, Settings, Workflow, Sparkles } from 'lucide-react';\n\n/* ─── Reusable Components ─── */\n\nfunction CopyButton({ text }: { text: string }) {\n const [copied, setCopied] = useState(false);\n return (\n { navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000); }}\n className=\"absolute top-3 right-3 p-1.5 rounded-md bg-white/5 hover:bg-white/10 transition-colors text-zinc-400 hover:text-zinc-200\"\n >\n {copied ? : }\n \n );\n}\n\nfunction CodeBlock({ filename, lang, children }: { filename?: string; lang?: string; children: string }) {\n return (\n
\n {filename && (\n
\n \n \n \n {filename}\n {lang && {lang}}\n
\n )}\n \n
{children.trim()}
\n
\n );\n}\n\nfunction DocSection({ id, icon: Icon, title, children }: { id: string; icon: React.ElementType; title: string; children: React.ReactNode }) {\n return (\n
\n
\n \n

{title}

\n
\n
{children}
\n
\n );\n}\n\nfunction SubDoc({ id, title, children }: { id: string; title: string; children: React.ReactNode }) {\n return (\n
\n

{title}

\n
{children}
\n
\n );\n}\n\nfunction ParamTable({ params }: { params: { name: string; type: string; required: boolean; desc: string }[] }) {\n return (\n
\n \n \n \n \n \n \n \n \n {params.map(p => (\n \n \n \n \n \n \n ))}\n \n
参数类型必填说明
{p.name}{p.type}{p.required ? ✓ : —}{p.desc}
\n
\n );\n}\n\nfunction Callout({ type = 'info', children }: { type?: 'info' | 'warning' | 'tip'; children: React.ReactNode }) {\n const styles = {\n info: 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900 dark:bg-blue-950/30 dark:text-blue-200',\n warning: 'border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-900 dark:bg-amber-950/30 dark:text-amber-200',\n tip: 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950/30 dark:text-emerald-200',\n };\n const icons = { info: Globe, warning: AlertTriangle, tip: Lightbulb };\n const Ic = icons[type];\n return (\n
\n \n
{children}
\n
\n );\n}\n\nfunction FlowStep({ title, children }: { title: string; children: React.ReactNode }) {\n return (\n
\n
{title}
\n
{children}
\n
\n );\n}\n\nfunction ToolTable({ tools }: { tools: [string, string, string][] }) {\n return (\n
\n \n \n \n \n \n \n \n {tools.map(([name, desc, scene]) => (\n \n \n \n \n \n ))}\n \n
工具名功能典型场景
{name}{desc}{scene}
\n
\n );\n}\n\n/* ─── Navigation Structure ─── */\n\nconst NAV = [\n { id: 'concept', icon: Workflow, label: 'MCP 工作原理', children: [\n { id: 'why-mcp', label: '为什么需要 MCP' },\n { id: 'scenario-walkthrough', label: '场景走查 · 6 步' },\n { id: 'dev-responsibility', label: '开发者只做两件事' },\n { id: 'integration-paths', label: '三种接入姿势' },\n ]},\n { id: 'quick-start', icon: Zap, label: '快速开始', children: [\n { id: 'overview', label: '概述' },\n { id: 'requirements', label: '系统要求' },\n { id: 'install', label: '安装方式' },\n { id: 'env-vars', label: '环境变量' },\n ]},\n { id: 'config', icon: Settings, label: '接入配置', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-coze', label: '扣子(Coze)' },\n { id: 'config-coze-workflow', label: 'Coze 工作流接入' },\n { id: 'config-other', label: '豆包 / 钉钉 / 其他' },\n ]},\n { id: 'eval-modes', icon: Radio, label: '评测模式', children: [\n { id: 'stream-eval', label: '实时录音评测' },\n { id: 'stream-flow', label: '流式评测流程' },\n { id: 'file-eval', label: '音频文件评测' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API 参考', children: [\n { id: 'tools-en', label: '英文评测工具' },\n { id: 'tools-cn', label: '中文评测工具' },\n { id: 'result-fields', label: '评测结果字段' },\n { id: 'error-codes', label: '错误码' },\n ]},\n { id: 'architecture', icon: Terminal, label: '架构说明', children: [\n { id: 'arch-diagram', label: '架构图' },\n { id: 'transport', label: '传输协议' },\n ]},\n { id: 'integration', icon: Code2, label: '示例代码', children: [\n { id: 'code-python', label: 'Python' },\n { id: 'code-javascript', label: 'JavaScript' },\n ]},\n { id: 'best-practices', icon: FileText, label: '最佳实践', children: [\n { id: 'prompt-templates', label: 'Prompt 模板' },\n { id: 'error-handling', label: '错误处理' },\n { id: 'performance', label: '性能优化' },\n ]},\n { id: 'service-info', icon: Globe, label: '服务信息', children: [\n { id: 'endpoints', label: '服务端点' },\n { id: 'limits', label: '服务限制' },\n { id: 'changelog', label: '更新日志' },\n ]},\n];\n\n/* ─── Page ─── */\n\nexport default function DocsPage() {\n const [activeId, setActiveId] = useState('quick-start');\n\n // 收集所有可滚动的锚点 id(包含分组和子章节),用于 scroll-spy\n const allIds = useMemo(() => {\n const ids: string[] = [];\n NAV.forEach(g => {\n ids.push(g.id);\n g.children.forEach(c => ids.push(c.id));\n });\n return ids;\n }, []);\n\n useEffect(() => {\n const elements = allIds\n .map(id => document.getElementById(id))\n .filter((el): el is HTMLElement => el !== null);\n\n if (elements.length === 0) return;\n\n // 以顶部偏移 120px 作为\"激活线\",选取距离激活线最近的上方/同位章节\n const computeActive = () => {\n const line = 120;\n let currentId = elements[0]?.id ?? '';\n for (const el of elements) {\n const top = el.getBoundingClientRect().top;\n if (top - line <= 0) {\n currentId = el.id;\n } else {\n break;\n }\n }\n // 滚到底部时,强制高亮最后一项\n if (window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - 4) {\n currentId = elements[elements.length - 1].id;\n }\n setActiveId(prev => (prev === currentId ? prev : currentId));\n };\n\n computeActive();\n window.addEventListener('scroll', computeActive, { passive: true });\n window.addEventListener('resize', computeActive);\n return () => {\n window.removeEventListener('scroll', computeActive);\n window.removeEventListener('resize', computeActive);\n };\n }, [allIds]);\n\n // 根据当前激活的子节点,找出其所属分组 id,用于同步高亮父级\n const activeGroupId = useMemo(() => {\n for (const g of NAV) {\n if (g.id === activeId) return g.id;\n if (g.children.some(c => c.id === activeId)) return g.id;\n }\n return activeId;\n }, [activeId]);\n\n return (\n
\n
\n \n 返回首页\n \n\n

开发者文档

\n

驰声语音评测 MCP · chivox-local-mcp

\n\n
\n {/* Sidebar */}\n \n\n {/* Content */}\n
\n\n {/* ══════ MCP 工作原理 ══════ */}\n \n\n \n

\n 大模型(GPT / Claude / Gemini / 通义千问 等)本质上是文字大脑:它擅长读和写,但天生听不到音频、打不开你的数据库、调不通第三方 API。\n

\n

\n MCP(Model Context Protocol)是一套由 Anthropic 主导、业界共同推进的开放协议,它像一根\"对讲机\":让大模型可以在需要时主动去调用外部能力(工具、数据源、服务),然后把结果接回来继续对话。\n

\n
\n
\n
\n \n 没有 MCP 的做法\n
\n
    \n
  • · 研究评测服务的 REST 文档
  • \n
  • · 自己写鉴权 / 上传 / 轮询代码
  • \n
  • · 把结果序列化后塞进 prompt
  • \n
  • · 每换一个大模型都得重写一遍
  • \n
\n
\n
\n
\n \n 用驰声 MCP 之后\n
\n
    \n
  • · 填一行 MCP Server 地址
  • \n
  • · 大模型自动发现&调用评测工具
  • \n
  • · 换任何支持 MCP 的大模型都能用
  • \n
  • · 不写一行调用代码
  • \n
\n
\n
\n \n MCP 让\"接入语音评测\"从一个\"后端工程\"变成了一个\"配置项\"。这也是为什么 Cursor、Claude Desktop、Dify、Coze、字节豆包、飞书智能助手都已经原生支持 MCP。\n \n
\n\n \n

\n 想象一个具体场景:一位开发者用 Claude 做了一款 「AI 雅思口语陪练」小程序,接入驰声语音评测 MCP。当用户发来一段录音,整个链路是这样的:\n

\n
\n \n

配置阶段(开发者 · 一次性)

\n

在 AI 后端的配置文件里填一行驰声 MCP Server 地址。大模型启动时自动发现:「我多了一个叫语音评测的工具」。

\n
\n \n

接收用户指令(终端用户)

\n

小程序用户发来一段自我介绍录音:「帮我听听,发音哪里有问题?」后端把「文字 + 录音链接」打包给大模型。

\n
\n \n

大模型自主思考(LLM · 最核心的魔法)

\n
\n 「用户让我听发音。」
\n 「但我只是文字大脑,我听不到。」
\n 「等等 —— 开发者给了我一个叫 chivox_voice_eval 的 MCP 工具!」\n
\n
\n \n

MCP 协议 · 自动调用(LLM → 驰声)

\n

大模型自动按 MCP 标准构造 tools/call 请求,把录音链接和参考文本发到驰声服务。开发者不需要写任何调用代码。

\n
\n \n

驰声服务处理(评测引擎)

\n

驰声对音频进行考试级打分,把结构化结果通过 MCP 原路返回:overall 85、/θ/ 音发音错误、流利度 88。

\n
\n \n

大模型整合并输出反馈(LLM)

\n

大模型把冷冰冰的分数翻译成温柔反馈:

\n
\n 「你的自我介绍很棒!综合 85 分 🎉 不过 think 这个词的 /θ/ 咬舌音不太标准,我们一起来练一下……」\n
\n
\n
\n \n 整条链路里,MCP 只出现在 ① 和 ④:① 让开发者一次性告诉大模型「你多了一个工具」,④ 让大模型可以自动调用它。这两步的标准化,就是 MCP 的全部价值。\n \n
\n\n \n

听起来复杂,但对开发者来说只需要两件事:

\n
\n
\n
\n 1\n 填一次 MCP 配置\n
\n

\n 在 AI 后端的配置里填入驰声 MCP Server 地址和 API Key,就这一次,以后新加评测能力完全免开发。\n

\n {`{\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"apiKey\": \"sk-••••••••••\"\n }\n}`}\n
\n
\n
\n 2\n 写一段 System Prompt\n
\n

\n 告诉大模型这个工具是做什么的、什么时候调用、结果怎么转成用户友好的反馈。\n

\n {`你是一位英语口语教练。\n当用户发来录音时:\n1. 调用 chivox_voice_eval 评分\n2. 聚焦 <70 分的音素家族\n3. 用高情商话术给出练习建议`}\n
\n
\n

\n 其余所有事情 —— 音频上传、鉴权、工具发现、调用时机、返回格式、结果整合 —— 都由 MCP 协议和大模型自己搞定。\n

\n
\n\n \n

根据你的技术栈,有三种等价的接入方式,底层都走完全相同的 MCP 协议:

\n\n {/* ── 姿势一:可视化 ── */}\n
\n
\n \n

姿势一 · 可视化拖拽(扣子 / Coze / 飞书智能助手)

\n
\n

\n 适合产品经理、运营、不写后端代码的开发者。整个过程像在手机上装 App。\n

\n
    \n
  1. 找到入口:在扣子平台的 「插件 / 工具」 配置区,点击「添加 MCP 服务」。
  2. \n
  3. 填两个字段(这也是你未来会从驰声这边拿到的):\n
    \n \n \n \n \n \n
    服务器地址https://speech-eval.site/mcp
    鉴权密钥sk-•••••••••• (由驰声分配,用于计费与识别)
    \n
    \n
  4. \n
  5. 平台自动发现能力:扣子会访问你填的地址,读取 MCP Server 自描述的\"说明书\"。瞬间明白:「这是个语音评测工具,需要传音频,会返发音分」。
  6. \n
  7. 右侧测试:在平台的聊天框里发一段语音,大模型就会自动调用工具。整个过程不需要写一行代码。
  8. \n
\n
\n\n {/* ── 姿势二:代码框架 ── */}\n
\n
\n \n

姿势二 · 代码框架配置(Dify / LangChain / 自研后端)

\n
\n

\n 适合做独立 APP / 小程序、用 Dify 或 LangChain 写 Agent 的极客开发者。核心就是往配置文件里加一段 JSON。\n

\n
    \n
  1. 打开配置文件(项目根目录下的 mcp.json 或框架指定的配置路径)。
  2. \n
  3. 在 mcpServers 下增加一个节点:\n {`{\n \"mcpServers\": {\n \"chivox_voice_eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\",\n \"env\": {\n \"API_KEY\": \"你的专属密钥\"\n }\n }\n }\n}`}\n
  4. \n
  5. 重启后端服务。大模型的底层调度器会在启动时自动连上驰声 MCP Server,把 16 种评测工具注册成随时待命的 tools。
  6. \n
  7. 触发调用:用户发来录音后,大模型看到 system prompt 的引导,自动选择合适的工具(单词/句子/段落/半开放)调用。
  8. \n
\n
\n\n {/* ── 姿势三:Function Calling 直连(分 A / B 两种做法) ── */}\n
\n
\n \n

姿势三 · 原生 Function Calling(豆包 / DeepSeek / OpenAI 兼容 API)

\n
\n

\n 适合不用任何 Agent 框架、直接调用 LLM API 的后端开发者。豆包 1.5+ / DeepSeek / GPT / Qwen 等模型都走标准 chat.completions 的 tools 参数。这里又分 A / B 两种做法,B 才是生产推荐。\n

\n\n \n 常见疑问:\"要不要手写一个 tool 定义?\"
\n — 姿势一 / 二不用(Coze、Dify、火山方舟控制台、Claude Desktop 会自动从 MCP Server 拉工具列表)。
\n — 姿势三看你选 A 还是 B:A 要手写,B 用 MCP 客户端库自动拉。\n
\n\n {/* ── 3-A:手写 tool schema ── */}\n
\n
\n

3-A · 手写 tool schema(最快验证,不推荐生产)

\n 快速 Demo\n
\n

\n 自己写一段 JSON Schema 告诉豆包\"有个工具叫 xxx,参数长这样\",豆包返回 tool_call 后你再手动去调驰声 MCP。缺点:驰声有 16 个评测工具,你每加一个题型都要改代码。\n

\n {`import os, json\nfrom openai import OpenAI\n\nclient = OpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv('ARK_API_KEY'),\n)\n\n# ─── 手写一段 tool schema(不推荐:16 个工具就要写 16 段)───\ntools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": \"en_word_eval\",\n \"description\": \"英语单词发音评测。当用户让你评价英语发音并提供录音链接时调用。\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"audio_url\": {\"type\": \"string\", \"description\": \"录音 URL\"},\n \"reference_text\": {\"type\": \"string\", \"description\": \"参考文本,如 Apple\"},\n },\n \"required\": [\"audio_url\", \"reference_text\"]\n }\n }\n}]\n\nresp = client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,拿到评测结果后温柔地反馈,不要直接报分数。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n)\n\nmsg = resp.choices[0].message\nif msg.tool_calls:\n args = json.loads(msg.tool_calls[0].function.arguments)\n # ↓↓↓ 这里手动调驰声 MCP,再把结果回填给豆包做第二趟 ↓↓↓\n # result = requests.post(\"https://speech-eval.site/mcp\", json={...})`}\n
\n\n {/* ── 3-B:MCP 自动发现 ── */}\n
\n
\n

\n 3-B · 用 MCP 客户端库自动发现 \n

\n 生产推荐\n
\n

\n 启动时连上驰声 MCP Server,调一次 tools/list,把 16 个评测工具自动转成 Function Calling 的 tools 格式。驰声加新工具,你代码不用改。这才是 MCP 协议的真正价值。\n

\n {`import asyncio, os\nfrom openai import AsyncOpenAI\nfrom mcp import ClientSession\nfrom mcp.client.streamable_http import streamablehttp_client\n\nclient = AsyncOpenAI(\n base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key=os.getenv(\"ARK_API_KEY\"),\n)\n\nasync def main():\n # ─── 1. 连驰声 MCP Server,自动拉取全部 16 个工具 ───\n async with streamablehttp_client(\n \"https://speech-eval.site/mcp\",\n headers={\"Authorization\": f\"Bearer {os.getenv('CHIVOX_KEY')}\"},\n ) as (read, write, _):\n async with ClientSession(read, write) as session:\n await session.initialize()\n mcp_tools = (await session.list_tools()).tools # ← 一行拿到全部工具\n\n # ─── 2. MCP schema → OpenAI Function Calling schema ───\n tools = [{\n \"type\": \"function\",\n \"function\": {\n \"name\": t.name,\n \"description\": t.description,\n \"parameters\": t.inputSchema, # MCP 直接给 JSON Schema\n }\n } for t in mcp_tools]\n\n # ─── 3. 正常调豆包,tools 由 MCP 动态注入 ───\n resp = await client.chat.completions.create(\n model=\"ep-xxx-doubao-tools\",\n messages=[\n {\"role\": \"system\", \"content\": \"你是英语老师,收到评测结果后温柔反馈。\"},\n {\"role\": \"user\", \"content\": \"老师,我读了 Apple,录音 https://demo.com/u1.mp3\"},\n ],\n tools=tools,\n tool_choice=\"auto\",\n )\n\n # ─── 4. 折返跑:豆包选好工具后,直接走 MCP 调驰声 ───\n msg = resp.choices[0].message\n if msg.tool_calls:\n call = msg.tool_calls[0]\n result = await session.call_tool(\n call.function.name,\n arguments=__import__(\"json\").loads(call.function.arguments),\n )\n # 把 result 回填给豆包做第二趟 chat.completions 即可\n\nasyncio.run(main())`}\n

\n 想要更省心?直接用 官方 mcp python sdk、mcp-use、openai-agents,或火山官方 Arkitect 高代码 SDK,它们都把上面这段\"MCP → Function Calling\"的桥接封装好了。\n

\n
\n
\n\n \n 三种姿势走的是完全相同的 MCP 协议,能力完全等价。选型建议:产品经理 / 原型验证用姿势一(Coze 填表单);AI 客户端用户用姿势二(Cursor / Claude Desktop 填 mcp.json);后端生产服务用姿势三-B(MCP 客户端库自动发现工具,不要手写 tool schema)。\n \n
\n\n
\n\n {/* ══════ 快速开始 ══════ */}\n \n\n \n

chivox-local-mcp 是驰声语音评测的 MCP 本地代理,通过 Model Context Protocol 将远程驰声评测服务桥接到本地,让 AI 助手(Claude Desktop、Claude Code、Cursor 等)直接调用语音评测能力。

\n

它支持两种评测模式,覆盖从即时交互到批量处理的全部场景:

\n
\n
\n
\n \n 实时录音评测\n
\n

通过麦克风边录边评,音频以 WebSocket 流式推送,无需生成中间文件,延迟更低、体验更佳。

\n
\n
\n
\n \n 音频文件评测\n
\n

支持本地文件路径、Base64 编码、URL 三种输入,适合已有音频的批量评测场景。

\n
\n
\n 当前支持 16 种评测工具:英文 10 种(单词、句子、段落、纠音、自然拼读、口语选择、半开放题等)+ 中文 6 种(汉字、拼音、词句、段落、有限分支、AI Talk)。\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n
依赖版本说明
Node.js{'>'}= 18运行时必须
SoXany仅实时录音功能需要(处理麦克风音频流)
\n
\n

安装 SoX(仅在使用实时录音时需要):

\n {`# macOS\nbrew install sox\n\n# Ubuntu / Debian\nsudo apt-get install sox`}\n
\n\n \n

方式一:npm 全局安装(推荐)

\n {`npm install -g chivox-local-mcp`}\n\n

方式二:npx 免安装运行

\n {`MCP_REMOTE_URL=http://your-server:8080 npx chivox-local-mcp`}\n\n

方式三:从源码构建

\n {`git clone https://git.chivox.com/CLOUD_DEV/cvx_local_mcp.git\ncd cvx_local_mcp\nbash scripts/build.sh`}\n
\n\n \n \n \n
\n\n {/* ══════ 接入配置 ══════ */}\n \n\n \n
    \n
  1. 打开 Cursor 设置(Cmd + ,)
  2. \n
  3. 左侧选择 MCP(或搜索 "MCP")
  4. \n
  5. 点击 Add new MCP server
  6. \n
  7. 填写配置并保存:
  8. \n
\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n}`}\n Cursor 使用远程 Streamable HTTP 模式直连,无需安装本地代理。如需实时录音功能,请使用下方 Claude Desktop 的本地代理配置。\n
\n\n \n

编辑配置文件(macOS:~/Library/Application Support/Claude/claude_desktop_config.json):

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"chivox-local-mcp\",\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\",\n \"MCP_API_KEY\": \"your-api-key\"\n }\n }\n }\n}`}\n

如果是从源码构建:

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/cvx_local_mcp/dist/index.js\"],\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\"\n }\n }\n }\n}`}\n Claude Desktop 使用本地代理模式(stdio),支持实时录音评测。本地代理会自动桥接远程服务。\n
\n\n \n {`# npm 全局安装后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 chivox-local-mcp\n\n# 源码构建后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 node /path/to/cvx_local_mcp/dist/index.js`}\n \n\n \n

扣子(Coze)是字节跳动推出的 AI 应用开发平台,支持通过 MCP 扩展为 Agent 赋予外部工具能力。接入驰声语音评测后,你可以构建口语练习 Bot、发音诊断助手等应用。

\n

方式一:扣子空间 MCP 扩展(推荐)

\n
    \n
  1. 打开 扣子空间(space.coze.cn)
  2. \n
  3. 在对话框下方点击 「添加扩展」
  4. \n
  5. 选择 「自定义」 标签,点击添加新的 MCP 服务
  6. \n
  7. 填入以下配置信息:
  8. \n
\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
名称chivox-speech-eval
传输类型streamable-http
URLhttps://speech-eval.site/mcp
\n
\n
    \n
  1. 保存后,在对话中输入 「帮我评测这段英文发音」 即可触发 Agent 调用
  2. \n
\n 添加 MCP 扩展后,扣子空间的 Agent 会自动识别并调用评测工具。你可以在 Agent 的思考过程中看到具体的工具调用细节。\n\n

方式二:在 Coze 开发平台的 Bot 中使用

\n
    \n
  1. 进入 Coze 开发平台,创建或编辑 Bot
  2. \n
  3. 在 Bot 的 「插件」 或 「工具」 面板中,添加 MCP 工具
  4. \n
  5. 选择 Streamable HTTP 类型,填入 URL:https://speech-eval.site/mcp
  6. \n
  7. Bot 将自动发现所有可用的评测工具(如 evaluate_english_word 等)
  8. \n
  9. 在 Bot 的人设提示词中,添加语音评测相关的引导语
  10. \n
\n {`你是一位专业的英语口语教练。当用户上传音频并请求评测时:\n1. 使用 evaluate_english_word / evaluate_english_sentence 等工具进行评测\n2. 根据评测结果(overall、accuracy、fluency 等分数)给出专业分析\n3. 针对得分较低的维度提供具体改进建议\n4. 鼓励用户持续练习`}\n
\n\n \n

如果你需要在 Coze 工作流中集成语音评测能力,可以通过 HTTP Request 节点调用评测 API:

\n\n

步骤 1:上传音频

\n

在工作流中添加一个 HTTP Request 节点,配置如下:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
配置项值
方法POST
URLhttps://speech-eval.site/upload
Content-Typeaudio/mp3
Body音频文件二进制数据
\n
\n

响应中获取 {'{{audioId}}'},传递给下一步。

\n\n

步骤 2:调用评测

\n

添加第二个 HTTP Request 节点,通过 MCP 接口调用评测工具:

\n {`{\n \"jsonrpc\": \"2.0\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"evaluate_english_sentence\",\n \"arguments\": {\n \"audioId\": \"{{audioId}}\",\n \"sentence\": \"{{ref_text}}\"\n }\n },\n \"id\": 1\n}`}\n\n

步骤 3:处理结果

\n

评测结果通过 JSON 格式返回,可使用 Coze 的 代码节点 或 LLM 节点 对结果进行解析和二次处理(如生成学习建议、计算进步趋势等)。

\n\n 工作流方式适合需要固定流程的场景(如批量评测、定时任务、与其他系统联动)。如果是交互式场景,推荐使用上方的 MCP 扩展方式,Agent 会自动选择合适的工具。\n\n
\n

完整工作流示意

\n
\n 用户输入音频\n →\n HTTP: 上传音频\n →\n HTTP: 调用评测\n →\n LLM: 分析结果\n →\n 输出反馈\n
\n
\n
\n\n \n

支持 MCP 的客户端均可接入,统一使用以下配置:

\n
\n \n \n \n \n \n \n \n \n \n
配置项值
传输类型streamable-http
URLhttps://speech-eval.site/mcp
\n
\n
\n
\n\n {/* ══════ 评测模式 ══════ */}\n \n\n \n

通过本地麦克风实时录音,音频以 WebSocket 流式推送到评测服务,无需生成中间文件。这是最灵活、延迟最低的评测方式,特别适合交互式口语练习场景。

\n 实时录音评测需要安装 SoX 并使用本地代理模式(Claude Desktop / Claude Code)。Cursor 等远程直连模式暂不支持实时录音。\n\n

需要按顺序调用三个工具:

\n\n
\n
\n

create_stream_session — 创建流式评测会话

\n \n

返回 session_id,后续步骤需使用。

\n
\n\n
\n

start_recording — 开始麦克风录音

\n \n

调用后自动启动麦克风,音频通过 WebSocket 实时推送到评测服务。

\n
\n\n
\n

stop_recording — 停止录音并获取结果

\n \n
\n
\n
\n\n \n
\n \n

用户:"请评测我的英文发音,文本是 Hello"

\n

AI 调用 create_stream_session(core_type="en.word.score", ref_text="Hello")

\n

→ 获得 session_id

\n
\n \n

AI 调用 start_recording(session_id=xxx)

\n

麦克风开始录音,音频通过 WebSocket 实时推送到评测服务

\n
\n \n

用户说完后告知 AI "结束"

\n

AI 调用 stop_recording(session_id=xxx)

\n

→ 返回评测结果(总分、准确度、流利度、音素得分等)

\n
\n
\n
\n\n \n

适用于已有音频文件的评测场景,支持三种输入方式:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
参数说明适用场景
audio_file_path本地文件路径代理自动读取并转为 Base64,最便捷
audio_base64Base64 编码数据已有编码数据时使用
audio_url音频文件 URL音频托管在云存储时使用
\n
\n 推荐使用 audio_file_path,只需传入本地文件路径,代理会自动处理编码和上传。\n

支持的音频格式:mp3, wav, ogg, m4a, aac, pcm

\n

限制:单文件最大 50MB,大于 500KB 的文件自动压缩为 16kHz / 单声道 / 32kbps。

\n
\n
\n\n {/* ══════ API 参考 ══════ */}\n \n\n \n \n\n

通用参数:所有英文评测工具均支持以下参数。

\n \n
\n\n \n \n\n

通用参数:

\n \n
\n\n \n

所有评测工具返回统一的结构化结果:

\n {`{\n \"overall\": 85,\n \"accuracy\": 82,\n \"pron\": 88,\n \"fluency\": {\n \"overall\": 78,\n \"speed\": 65,\n \"pause\": 2\n },\n \"integrity\": 95,\n \"details\": [\n {\n \"char\": \"hello\",\n \"score\": 85,\n \"phone\": [\n { \"phoneme\": \"h\", \"score\": 90 },\n { \"phoneme\": \"ɛ\", \"score\": 82 },\n { \"phoneme\": \"l\", \"score\": 88 },\n { \"phoneme\": \"oʊ\", \"score\": 80 }\n ]\n }\n ]\n}`}\n
\n \n \n \n \n \n \n \n {[\n ['overall', '0–100', '综合总分,反映整体语音质量'],\n ['accuracy', '0–100', '准确度,音素级别的发音准确率'],\n ['pron', '0–100', '发音得分,整体发音质量评价'],\n ['fluency.overall', '0–100', '流利度,语流的自然度与平滑度'],\n ['fluency.speed', '0–100', '语速得分,每分钟词/音节计量'],\n ['fluency.pause', 'number', '不自然停顿次数'],\n ['integrity', '0–100', '完整度,是否完整朗读了参考文本'],\n ['details[].phone[]', 'array', '每个音素的独立评分,可定位具体弱项'],\n ['details[].stress[]', 'array', '重音得分,检测重弱读是否正确'],\n ].map(([field, range, desc]) => (\n \n \n \n \n \n ))}\n \n
字段范围说明
{field}{range}{desc}
\n
\n
\n\n \n
\n \n \n \n \n \n \n \n {[\n ['音频 ID 无效或已过期', '音频上传后 5 分钟内有效,评测完成后自动删除', '重新上传音频'],\n ['服务器繁忙', '当前请求过多,排队已满', '稍后重试,使用指数退避策略'],\n ['存储空间已满', '服务器临时音频存储已满', '稍后重试,系统会自动清理'],\n ['音频格式不支持', '上传了不支持的文件类型', '使用 mp3/wav/ogg/m4a/aac/pcm'],\n ['音频时长超限', '超过该题型最大时长限制', '裁剪音频后重试'],\n ['WebSocket 连接断开', '网络不稳定导致流式连接中断', '代理会自动重连,如持续失败请检查网络'],\n ].map(([scene, reason, fix]) => (\n \n \n \n \n \n ))}\n \n
场景原因解决方式
{scene}{reason}{fix}
\n
\n
\n
\n\n {/* ══════ 架构说明 ══════ */}\n \n\n \n
\n
\n

AI 客户端

\n

Claude Desktop
Claude Code
Cursor

\n
\n
\n

⇄

\n

stdio

\n
\n
\n

chivox-local-mcp

\n

本地代理
SoX 录音

\n
\n
\n

⇄

\n

HTTP / WS

\n
\n
\n

Remote Chivox

\n

MCP Server
评测引擎

\n
\n
\n
\n\n \n
    \n
  • \n \n stdio — AI 客户端通过标准输入输出与本地代理通信,这是 MCP 的标准传输方式\n
  • \n
  • \n \n HTTP — 音频文件评测工具通过 HTTP 代理到远程服务,适用于非流式场景\n
  • \n
  • \n \n WebSocket — 实时录音音频通过 WebSocket 流式推送,支持断线自动重连\n
  • \n
\n
\n
\n\n {/* ══════ 示例代码 ══════ */}\n \n\n \n {`import requests\n\nwith open('audio.mp3', 'rb') as f:\n r = requests.post(\n 'https://speech-eval.site/upload',\n data=f,\n headers={'Content-Type': 'audio/mp3'}\n )\n\nresult = r.json()\nprint(f\"audioId: {result['audioId']}\")\nprint(f\"size: {result['size']} bytes\")\nprint(f\"expires: {result['expiresIn']}\")`}\n \n\n \n {`const fs = require('fs');\n\nconst audioData = fs.readFileSync('audio.mp3');\n\nconst res = await fetch('https://speech-eval.site/upload', {\n method: 'POST',\n headers: { 'Content-Type': 'audio/mp3' },\n body: audioData,\n});\n\nconst result = await res.json();\nconsole.log('audioId:', result.audioId);`}\n \n \n\n {/* ══════ 最佳实践 ══════ */}\n \n\n \n

以下模板帮助你引导 LLM 对评测结果进行深度分析:

\n
\n
\n

发音诊断

\n {`你是一位专业的英语口语教练。请根据以下 MCP 评测结果分析学生的发音表现:\n\n评测结果:{evaluation_result}\n\n请按以下格式输出:\n1. 总体评价(一句话)\n2. 优势项(>80 分的指标)\n3. 弱项分析(<70 分的指标,定位到具体音素)\n4. 针对性练习建议(2-3 条可操作的建议)`}\n
\n
\n

练习生成

\n {`根据以下弱项列表,为学生生成针对性的口语练习材料:\n\n弱项:{weak_points}\n\n请生成:\n1. 3 个绕口令(专门针对弱项音素)\n2. 5 个包含目标音素的常用短句(标注重音和连读)\n3. 1 段跟读练习段落(50-80 词)`}\n
\n
\n

学习报告

\n {`请根据学生近 7 天的评测历史生成学习报告:\n\n评测历史:{history}\n\n报告要求:\n1. 整体趋势(进步/持平/退步)\n2. 各维度变化(准确度、流利度、语速)\n3. 本周最大进步项\n4. 下周重点练习建议\n5. 鼓励性总结`}\n
\n
\n
\n\n \n
    \n
  • 音频过期:上传后 5 分钟内有效。建议在上传后 3 分钟内完成评测。
  • \n
  • 服务繁忙:使用指数退避策略重试(1s → 2s → 4s),最多 3 次。
  • \n
  • 录音中断:WebSocket 断线后代理会自动重连。如持续失败,检查网络连接和 SoX 安装。
  • \n
\n
\n\n \n
    \n
  • 优先使用流式评测:实时录音模式跳过了文件上传环节,端到端延迟比文件评测低 30-50%。
  • \n
  • 音频压缩:文件评测时,上传前将音频转为 16kHz 单声道 mp3,可减少 60-80% 的上传体积。
  • \n
  • 选择合适的工具:单词评测比段落评测快 3-5 倍。如只需单词级分数,不要用句子评测。
  • \n
  • 本地文件路径最便捷:使用 audio_file_path 参数传入本地路径,代理自动处理编码,无需手动转 Base64。
  • \n
\n
\n
\n\n {/* ══════ 服务信息 ══════ */}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n
端点方法说明
/uploadPOST音频文件上传
/mcpPOSTMCP JSON-RPC 接口(Streamable HTTP)
/healthGET健康检查
\n
\n
\n \n
\n \n \n \n \n \n \n \n {[\n ['存储限制', '500MB', '最大音频存储空间'],\n ['最大排队', '10', '等待处理的请求数'],\n ['最大并发', '3', '同时处理的评测数'],\n ['音频有效期', '5 分钟', '上传后未评测自动过期'],\n ['文件大小限制', '50MB', '单个音频文件最大'],\n ].map(([k, v, d]) => (\n \n ))}\n \n
配置项默认值说明
{k}{v}{d}
\n
\n
\n \n
\n {[\n { ver: 'v3.0.0', date: '2026-04-16', desc: '新增本地代理模式,支持实时录音流式评测,工具扩展至 16 种' },\n { ver: 'v2.3.0', date: '2026-03-25', desc: '支持 HTTPS,域名 speech-eval.site' },\n { ver: 'v2.2.0', date: '2026-03-24', desc: '添加 MCP 配置指南(Cursor / Claude Desktop)' },\n { ver: 'v2.1.0', date: '2026-03-24', desc: '简化上传流程,统一使用 HTTP API' },\n { ver: 'v2.0.0', date: '2026-03-24', desc: '初始版本,支持多种评测类型' },\n ].map(l => (\n
\n {l.ver}\n {l.date}\n {l.desc}\n
\n ))}\n
\n
\n
\n\n
\n
\n
\n
\n );\n}\n"}, "df6978fcba4dfa6353b0a2b2f0f21a9fea9fd5d0": {"t": 1785765813.6600416, "n": 47075, "h": "6df90c0ede446342", "c": "'use client';\n\nimport { useState } from 'react';\nimport { Link } from '@/i18n/routing';\nimport { ArrowLeft, BookOpen, Code2, Zap, FileText, Copy, Check, Terminal, Globe, Mic, MessageSquare, BarChart3, AlertTriangle, Lightbulb, Radio, FolderOpen, Settings } from 'lucide-react';\n\n/* ─── Reusable Components ─── */\n\nfunction CopyButton({ text }: { text: string }) {\n const [copied, setCopied] = useState(false);\n return (\n { navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000); }}\n className=\"absolute top-3 right-3 p-1.5 rounded-md bg-white/5 hover:bg-white/10 transition-colors text-zinc-400 hover:text-zinc-200\"\n >\n {copied ? : }\n \n );\n}\n\nfunction CodeBlock({ filename, lang, children }: { filename?: string; lang?: string; children: string }) {\n return (\n
\n {filename && (\n
\n \n \n \n {filename}\n {lang && {lang}}\n
\n )}\n \n
{children.trim()}
\n
\n );\n}\n\nfunction DocSection({ id, icon: Icon, title, children }: { id: string; icon: React.ElementType; title: string; children: React.ReactNode }) {\n return (\n
\n
\n \n

{title}

\n
\n
{children}
\n
\n );\n}\n\nfunction SubDoc({ id, title, children }: { id: string; title: string; children: React.ReactNode }) {\n return (\n
\n

{title}

\n
{children}
\n
\n );\n}\n\nfunction ParamTable({ params }: { params: { name: string; type: string; required: boolean; desc: string }[] }) {\n return (\n
\n \n \n \n \n \n \n \n \n {params.map(p => (\n \n \n \n \n \n \n ))}\n \n
参数类型必填说明
{p.name}{p.type}{p.required ? ✓ : —}{p.desc}
\n
\n );\n}\n\nfunction Callout({ type = 'info', children }: { type?: 'info' | 'warning' | 'tip'; children: React.ReactNode }) {\n const styles = {\n info: 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900 dark:bg-blue-950/30 dark:text-blue-200',\n warning: 'border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-900 dark:bg-amber-950/30 dark:text-amber-200',\n tip: 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950/30 dark:text-emerald-200',\n };\n const icons = { info: Globe, warning: AlertTriangle, tip: Lightbulb };\n const Ic = icons[type];\n return (\n
\n \n
{children}
\n
\n );\n}\n\nfunction FlowStep({ title, children }: { title: string; children: React.ReactNode }) {\n return (\n
\n
{title}
\n
{children}
\n
\n );\n}\n\nfunction ToolTable({ tools }: { tools: [string, string, string][] }) {\n return (\n
\n \n \n \n \n \n \n \n {tools.map(([name, desc, scene]) => (\n \n \n \n \n \n ))}\n \n
工具名功能典型场景
{name}{desc}{scene}
\n
\n );\n}\n\n/* ─── Navigation Structure ─── */\n\nconst NAV = [\n { id: 'quick-start', icon: Zap, label: '快速开始', children: [\n { id: 'overview', label: '概述' },\n { id: 'requirements', label: '系统要求' },\n { id: 'install', label: '安装方式' },\n { id: 'env-vars', label: '环境变量' },\n ]},\n { id: 'config', icon: Settings, label: '接入配置', children: [\n { id: 'config-cursor', label: 'Cursor' },\n { id: 'config-claude-desktop', label: 'Claude Desktop' },\n { id: 'config-claude-code', label: 'Claude Code' },\n { id: 'config-coze', label: '扣子(Coze)' },\n { id: 'config-coze-workflow', label: 'Coze 工作流接入' },\n { id: 'config-other', label: '豆包 / 钉钉 / 其他' },\n ]},\n { id: 'eval-modes', icon: Radio, label: '评测模式', children: [\n { id: 'stream-eval', label: '实时录音评测' },\n { id: 'stream-flow', label: '流式评测流程' },\n { id: 'file-eval', label: '音频文件评测' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API 参考', children: [\n { id: 'tools-en', label: '英文评测工具' },\n { id: 'tools-cn', label: '中文评测工具' },\n { id: 'result-fields', label: '评测结果字段' },\n { id: 'error-codes', label: '错误码' },\n ]},\n { id: 'architecture', icon: Terminal, label: '架构说明', children: [\n { id: 'arch-diagram', label: '架构图' },\n { id: 'transport', label: '传输协议' },\n ]},\n { id: 'integration', icon: Code2, label: '示例代码', children: [\n { id: 'code-python', label: 'Python' },\n { id: 'code-javascript', label: 'JavaScript' },\n ]},\n { id: 'best-practices', icon: FileText, label: '最佳实践', children: [\n { id: 'prompt-templates', label: 'Prompt 模板' },\n { id: 'error-handling', label: '错误处理' },\n { id: 'performance', label: '性能优化' },\n ]},\n { id: 'service-info', icon: Globe, label: '服务信息', children: [\n { id: 'endpoints', label: '服务端点' },\n { id: 'limits', label: '服务限制' },\n { id: 'changelog', label: '更新日志' },\n ]},\n];\n\n/* ─── Page ─── */\n\nexport default function DocsPage() {\n const [, setActiveSection] = useState('quick-start');\n\n return (\n
\n
\n \n 返回首页\n \n\n

开发者文档

\n

驰声语音评测 MCP · chivox-local-mcp

\n\n
\n {/* Sidebar */}\n \n\n {/* Content */}\n
\n\n {/* ══════ 快速开始 ══════ */}\n \n\n \n

chivox-local-mcp 是驰声语音评测的 MCP 本地代理,通过 Model Context Protocol 将远程驰声评测服务桥接到本地,让 AI 助手(Claude Desktop、Claude Code、Cursor 等)直接调用语音评测能力。

\n

它支持两种评测模式,覆盖从即时交互到批量处理的全部场景:

\n
\n
\n
\n \n 实时录音评测\n
\n

通过麦克风边录边评,音频以 WebSocket 流式推送,无需生成中间文件,延迟更低、体验更佳。

\n
\n
\n
\n \n 音频文件评测\n
\n

支持本地文件路径、Base64 编码、URL 三种输入,适合已有音频的批量评测场景。

\n
\n
\n 当前支持 16 种评测工具:英文 10 种(单词、句子、段落、纠音、自然拼读、口语选择、半开放题等)+ 中文 6 种(汉字、拼音、词句、段落、有限分支、AI Talk)。\n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n
依赖版本说明
Node.js{'>'}= 18运行时必须
SoXany仅实时录音功能需要(处理麦克风音频流)
\n
\n

安装 SoX(仅在使用实时录音时需要):

\n {`# macOS\nbrew install sox\n\n# Ubuntu / Debian\nsudo apt-get install sox`}\n
\n\n \n

方式一:npm 全局安装(推荐)

\n {`npm install -g chivox-local-mcp`}\n\n

方式二:npx 免安装运行

\n {`MCP_REMOTE_URL=http://your-server:8080 npx chivox-local-mcp`}\n\n

方式三:从源码构建

\n {`git clone https://git.chivox.com/CLOUD_DEV/cvx_local_mcp.git\ncd cvx_local_mcp\nbash scripts/build.sh`}\n
\n\n \n \n \n
\n\n {/* ══════ 接入配置 ══════ */}\n \n\n \n
    \n
  1. 打开 Cursor 设置(Cmd + ,)
  2. \n
  3. 左侧选择 MCP(或搜索 "MCP")
  4. \n
  5. 点击 Add new MCP server
  6. \n
  7. 填写配置并保存:
  8. \n
\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n}`}\n Cursor 使用远程 Streamable HTTP 模式直连,无需安装本地代理。如需实时录音功能,请使用下方 Claude Desktop 的本地代理配置。\n
\n\n \n

编辑配置文件(macOS:~/Library/Application Support/Claude/claude_desktop_config.json):

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"chivox-local-mcp\",\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\",\n \"MCP_API_KEY\": \"your-api-key\"\n }\n }\n }\n}`}\n

如果是从源码构建:

\n {`{\n \"mcpServers\": {\n \"chivox\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/cvx_local_mcp/dist/index.js\"],\n \"env\": {\n \"MCP_REMOTE_URL\": \"http://your-server:8080\"\n }\n }\n }\n}`}\n Claude Desktop 使用本地代理模式(stdio),支持实时录音评测。本地代理会自动桥接远程服务。\n
\n\n \n {`# npm 全局安装后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 chivox-local-mcp\n\n# 源码构建后\nclaude mcp add chivox -- env MCP_REMOTE_URL=http://your-server:8080 node /path/to/cvx_local_mcp/dist/index.js`}\n \n\n \n

扣子(Coze)是字节跳动推出的 AI 应用开发平台,支持通过 MCP 扩展为 Agent 赋予外部工具能力。接入驰声语音评测后,你可以构建口语练习 Bot、发音诊断助手等应用。

\n

方式一:扣子空间 MCP 扩展(推荐)

\n
    \n
  1. 打开 扣子空间(space.coze.cn)
  2. \n
  3. 在对话框下方点击 「添加扩展」
  4. \n
  5. 选择 「自定义」 标签,点击添加新的 MCP 服务
  6. \n
  7. 填入以下配置信息:
  8. \n
\n
\n \n \n \n \n \n \n \n \n \n \n
配置项值
名称chivox-speech-eval
传输类型streamable-http
URLhttps://speech-eval.site/mcp
\n
\n
    \n
  1. 保存后,在对话中输入 「帮我评测这段英文发音」 即可触发 Agent 调用
  2. \n
\n 添加 MCP 扩展后,扣子空间的 Agent 会自动识别并调用评测工具。你可以在 Agent 的思考过程中看到具体的工具调用细节。\n\n

方式二:在 Coze 开发平台的 Bot 中使用

\n
    \n
  1. 进入 Coze 开发平台,创建或编辑 Bot
  2. \n
  3. 在 Bot 的 「插件」 或 「工具」 面板中,添加 MCP 工具
  4. \n
  5. 选择 Streamable HTTP 类型,填入 URL:https://speech-eval.site/mcp
  6. \n
  7. Bot 将自动发现所有可用的评测工具(如 evaluate_english_word 等)
  8. \n
  9. 在 Bot 的人设提示词中,添加语音评测相关的引导语
  10. \n
\n {`你是一位专业的英语口语教练。当用户上传音频并请求评测时:\n1. 使用 evaluate_english_word / evaluate_english_sentence 等工具进行评测\n2. 根据评测结果(overall、accuracy、fluency 等分数)给出专业分析\n3. 针对得分较低的维度提供具体改进建议\n4. 鼓励用户持续练习`}\n
\n\n \n

如果你需要在 Coze 工作流中集成语音评测能力,可以通过 HTTP Request 节点调用评测 API:

\n\n

步骤 1:上传音频

\n

在工作流中添加一个 HTTP Request 节点,配置如下:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
配置项值
方法POST
URLhttps://speech-eval.site/upload
Content-Typeaudio/mp3
Body音频文件二进制数据
\n
\n

响应中获取 {'{{audioId}}'},传递给下一步。

\n\n

步骤 2:调用评测

\n

添加第二个 HTTP Request 节点,通过 MCP 接口调用评测工具:

\n {`{\n \"jsonrpc\": \"2.0\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"evaluate_english_sentence\",\n \"arguments\": {\n \"audioId\": \"{{audioId}}\",\n \"sentence\": \"{{ref_text}}\"\n }\n },\n \"id\": 1\n}`}\n\n

步骤 3:处理结果

\n

评测结果通过 JSON 格式返回,可使用 Coze 的 代码节点 或 LLM 节点 对结果进行解析和二次处理(如生成学习建议、计算进步趋势等)。

\n\n 工作流方式适合需要固定流程的场景(如批量评测、定时任务、与其他系统联动)。如果是交互式场景,推荐使用上方的 MCP 扩展方式,Agent 会自动选择合适的工具。\n\n
\n

完整工作流示意

\n
\n 用户输入音频\n →\n HTTP: 上传音频\n →\n HTTP: 调用评测\n →\n LLM: 分析结果\n →\n 输出反馈\n
\n
\n
\n\n \n

支持 MCP 的客户端均可接入,统一使用以下配置:

\n
\n \n \n \n \n \n \n \n \n \n
配置项值
传输类型streamable-http
URLhttps://speech-eval.site/mcp
\n
\n
\n
\n\n {/* ══════ 评测模式 ══════ */}\n \n\n \n

通过本地麦克风实时录音,音频以 WebSocket 流式推送到评测服务,无需生成中间文件。这是最灵活、延迟最低的评测方式,特别适合交互式口语练习场景。

\n 实时录音评测需要安装 SoX 并使用本地代理模式(Claude Desktop / Claude Code)。Cursor 等远程直连模式暂不支持实时录音。\n\n

需要按顺序调用三个工具:

\n\n
\n
\n

create_stream_session — 创建流式评测会话

\n \n

返回 session_id,后续步骤需使用。

\n
\n\n
\n

start_recording — 开始麦克风录音

\n \n

调用后自动启动麦克风,音频通过 WebSocket 实时推送到评测服务。

\n
\n\n
\n

stop_recording — 停止录音并获取结果

\n \n
\n
\n
\n\n \n
\n \n

用户:"请评测我的英文发音,文本是 Hello"

\n

AI 调用 create_stream_session(core_type="en.word.score", ref_text="Hello")

\n

→ 获得 session_id

\n
\n \n

AI 调用 start_recording(session_id=xxx)

\n

麦克风开始录音,音频通过 WebSocket 实时推送到评测服务

\n
\n \n

用户说完后告知 AI "结束"

\n

AI 调用 stop_recording(session_id=xxx)

\n

→ 返回评测结果(总分、准确度、流利度、音素得分等)

\n
\n
\n
\n\n \n

适用于已有音频文件的评测场景,支持三种输入方式:

\n
\n \n \n \n \n \n \n \n \n \n \n \n
参数说明适用场景
audio_file_path本地文件路径代理自动读取并转为 Base64,最便捷
audio_base64Base64 编码数据已有编码数据时使用
audio_url音频文件 URL音频托管在云存储时使用
\n
\n 推荐使用 audio_file_path,只需传入本地文件路径,代理会自动处理编码和上传。\n

支持的音频格式:mp3, wav, ogg, m4a, aac, pcm

\n

限制:单文件最大 50MB,大于 500KB 的文件自动压缩为 16kHz / 单声道 / 32kbps。

\n
\n
\n\n {/* ══════ API 参考 ══════ */}\n \n\n \n \n\n

通用参数:所有英文评测工具均支持以下参数。

\n \n
\n\n \n \n\n

通用参数:

\n \n
\n\n \n

所有评测工具返回统一的结构化结果:

\n {`{\n \"overall\": 85,\n \"accuracy\": 82,\n \"pron\": 88,\n \"fluency\": {\n \"overall\": 78,\n \"speed\": 65,\n \"pause\": 2\n },\n \"integrity\": 95,\n \"details\": [\n {\n \"char\": \"hello\",\n \"score\": 85,\n \"phone\": [\n { \"phoneme\": \"h\", \"score\": 90 },\n { \"phoneme\": \"ɛ\", \"score\": 82 },\n { \"phoneme\": \"l\", \"score\": 88 },\n { \"phoneme\": \"oʊ\", \"score\": 80 }\n ]\n }\n ]\n}`}\n
\n \n \n \n \n \n \n \n {[\n ['overall', '0–100', '综合总分,反映整体语音质量'],\n ['accuracy', '0–100', '准确度,音素级别的发音准确率'],\n ['pron', '0–100', '发音得分,整体发音质量评价'],\n ['fluency.overall', '0–100', '流利度,语流的自然度与平滑度'],\n ['fluency.speed', '0–100', '语速得分,每分钟词/音节计量'],\n ['fluency.pause', 'number', '不自然停顿次数'],\n ['integrity', '0–100', '完整度,是否完整朗读了参考文本'],\n ['details[].phone[]', 'array', '每个音素的独立评分,可定位具体弱项'],\n ['details[].stress[]', 'array', '重音得分,检测重弱读是否正确'],\n ].map(([field, range, desc]) => (\n \n \n \n \n \n ))}\n \n
字段范围说明
{field}{range}{desc}
\n
\n
\n\n \n
\n \n \n \n \n \n \n \n {[\n ['音频 ID 无效或已过期', '音频上传后 5 分钟内有效,评测完成后自动删除', '重新上传音频'],\n ['服务器繁忙', '当前请求过多,排队已满', '稍后重试,使用指数退避策略'],\n ['存储空间已满', '服务器临时音频存储已满', '稍后重试,系统会自动清理'],\n ['音频格式不支持', '上传了不支持的文件类型', '使用 mp3/wav/ogg/m4a/aac/pcm'],\n ['音频时长超限', '超过该题型最大时长限制', '裁剪音频后重试'],\n ['WebSocket 连接断开', '网络不稳定导致流式连接中断', '代理会自动重连,如持续失败请检查网络'],\n ].map(([scene, reason, fix]) => (\n \n \n \n \n \n ))}\n \n
场景原因解决方式
{scene}{reason}{fix}
\n
\n
\n
\n\n {/* ══════ 架构说明 ══════ */}\n \n\n \n
\n
\n

AI 客户端

\n

Claude Desktop
Claude Code
Cursor

\n
\n
\n

⇄

\n

stdio

\n
\n
\n

chivox-local-mcp

\n

本地代理
SoX 录音

\n
\n
\n

⇄

\n

HTTP / WS

\n
\n
\n

Remote Chivox

\n

MCP Server
评测引擎

\n
\n
\n
\n\n \n
    \n
  • \n \n stdio — AI 客户端通过标准输入输出与本地代理通信,这是 MCP 的标准传输方式\n
  • \n
  • \n \n HTTP — 音频文件评测工具通过 HTTP 代理到远程服务,适用于非流式场景\n
  • \n
  • \n \n WebSocket — 实时录音音频通过 WebSocket 流式推送,支持断线自动重连\n
  • \n
\n
\n
\n\n {/* ══════ 示例代码 ══════ */}\n \n\n \n {`import requests\n\nwith open('audio.mp3', 'rb') as f:\n r = requests.post(\n 'https://speech-eval.site/upload',\n data=f,\n headers={'Content-Type': 'audio/mp3'}\n )\n\nresult = r.json()\nprint(f\"audioId: {result['audioId']}\")\nprint(f\"size: {result['size']} bytes\")\nprint(f\"expires: {result['expiresIn']}\")`}\n \n\n \n {`const fs = require('fs');\n\nconst audioData = fs.readFileSync('audio.mp3');\n\nconst res = await fetch('https://speech-eval.site/upload', {\n method: 'POST',\n headers: { 'Content-Type': 'audio/mp3' },\n body: audioData,\n});\n\nconst result = await res.json();\nconsole.log('audioId:', result.audioId);`}\n \n \n\n {/* ══════ 最佳实践 ══════ */}\n \n\n \n

以下模板帮助你引导 LLM 对评测结果进行深度分析:

\n
\n
\n

发音诊断

\n {`你是一位专业的英语口语教练。请根据以下 MCP 评测结果分析学生的发音表现:\n\n评测结果:{evaluation_result}\n\n请按以下格式输出:\n1. 总体评价(一句话)\n2. 优势项(>80 分的指标)\n3. 弱项分析(<70 分的指标,定位到具体音素)\n4. 针对性练习建议(2-3 条可操作的建议)`}\n
\n
\n

练习生成

\n {`根据以下弱项列表,为学生生成针对性的口语练习材料:\n\n弱项:{weak_points}\n\n请生成:\n1. 3 个绕口令(专门针对弱项音素)\n2. 5 个包含目标音素的常用短句(标注重音和连读)\n3. 1 段跟读练习段落(50-80 词)`}\n
\n
\n

学习报告

\n {`请根据学生近 7 天的评测历史生成学习报告:\n\n评测历史:{history}\n\n报告要求:\n1. 整体趋势(进步/持平/退步)\n2. 各维度变化(准确度、流利度、语速)\n3. 本周最大进步项\n4. 下周重点练习建议\n5. 鼓励性总结`}\n
\n
\n
\n\n \n
    \n
  • 音频过期:上传后 5 分钟内有效。建议在上传后 3 分钟内完成评测。
  • \n
  • 服务繁忙:使用指数退避策略重试(1s → 2s → 4s),最多 3 次。
  • \n
  • 录音中断:WebSocket 断线后代理会自动重连。如持续失败,检查网络连接和 SoX 安装。
  • \n
\n
\n\n \n
    \n
  • 优先使用流式评测:实时录音模式跳过了文件上传环节,端到端延迟比文件评测低 30-50%。
  • \n
  • 音频压缩:文件评测时,上传前将音频转为 16kHz 单声道 mp3,可减少 60-80% 的上传体积。
  • \n
  • 选择合适的工具:单词评测比段落评测快 3-5 倍。如只需单词级分数,不要用句子评测。
  • \n
  • 本地文件路径最便捷:使用 audio_file_path 参数传入本地路径,代理自动处理编码,无需手动转 Base64。
  • \n
\n
\n
\n\n {/* ══════ 服务信息 ══════ */}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n
端点方法说明
/uploadPOST音频文件上传
/mcpPOSTMCP JSON-RPC 接口(Streamable HTTP)
/healthGET健康检查
\n
\n
\n \n
\n \n \n \n \n \n \n \n {[\n ['存储限制', '500MB', '最大音频存储空间'],\n ['最大排队', '10', '等待处理的请求数'],\n ['最大并发', '3', '同时处理的评测数'],\n ['音频有效期', '5 分钟', '上传后未评测自动过期'],\n ['文件大小限制', '50MB', '单个音频文件最大'],\n ].map(([k, v, d]) => (\n \n ))}\n \n
配置项默认值说明
{k}{v}{d}
\n
\n
\n \n
\n {[\n { ver: 'v3.0.0', date: '2026-04-16', desc: '新增本地代理模式,支持实时录音流式评测,工具扩展至 16 种' },\n { ver: 'v2.3.0', date: '2026-03-25', desc: '支持 HTTPS,域名 speech-eval.site' },\n { ver: 'v2.2.0', date: '2026-03-24', desc: '添加 MCP 配置指南(Cursor / Claude Desktop)' },\n { ver: 'v2.1.0', date: '2026-03-24', desc: '简化上传流程,统一使用 HTTP API' },\n { ver: 'v2.0.0', date: '2026-03-24', desc: '初始版本,支持多种评测类型' },\n ].map(l => (\n
\n {l.ver}\n {l.date}\n {l.desc}\n
\n ))}\n
\n
\n
\n\n
\n
\n
\n
\n );\n}\n"}, "ea92804d243613a262247fb779bb9c06c68ca15b": {"t": 1785765815.1899729, "n": 33768, "h": "33a6b55cdb1e185b", "c": "'use client';\n\nimport { useState } from 'react';\nimport { Link } from '@/i18n/routing';\nimport { ArrowLeft, BookOpen, Code2, Zap, FileText, Copy, Check, Terminal, Globe, Mic, MessageSquare, BarChart3, AlertTriangle, Lightbulb } from 'lucide-react';\n\nfunction CopyButton({ text }: { text: string }) {\n const [copied, setCopied] = useState(false);\n return (\n { navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000); }}\n className=\"absolute top-3 right-3 p-1.5 rounded-md bg-white/5 hover:bg-white/10 transition-colors text-zinc-400 hover:text-zinc-200\"\n >\n {copied ? : }\n \n );\n}\n\nfunction CodeBlock({ filename, lang, children }: { filename?: string; lang?: string; children: string }) {\n return (\n
\n {filename && (\n
\n \n \n \n {filename}\n {lang && {lang}}\n
\n )}\n \n
{children.trim()}
\n
\n );\n}\n\nfunction DocSection({ id, icon: Icon, title, children }: { id: string; icon: React.ElementType; title: string; children: React.ReactNode }) {\n return (\n
\n
\n \n

{title}

\n
\n
\n {children}\n
\n
\n );\n}\n\nfunction SubDoc({ id, title, children }: { id: string; title: string; children: React.ReactNode }) {\n return (\n
\n

{title}

\n
{children}
\n
\n );\n}\n\nfunction ParamTable({ params }: { params: { name: string; type: string; required: boolean; desc: string }[] }) {\n return (\n
\n \n \n \n \n \n \n \n \n {params.map(p => (\n \n \n \n \n \n \n ))}\n \n
参数类型必填说明
{p.name}{p.type}{p.required ? ✓ : —}{p.desc}
\n
\n );\n}\n\nfunction Callout({ type = 'info', children }: { type?: 'info' | 'warning' | 'tip'; children: React.ReactNode }) {\n const styles = {\n info: 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900 dark:bg-blue-950/30 dark:text-blue-200',\n warning: 'border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-900 dark:bg-amber-950/30 dark:text-amber-200',\n tip: 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950/30 dark:text-emerald-200',\n };\n const icons = { info: Globe, warning: AlertTriangle, tip: Lightbulb };\n const Ic = icons[type];\n return (\n
\n \n
{children}
\n
\n );\n}\n\nconst NAV = [\n { id: 'quick-start', icon: Zap, label: '快速开始', children: [\n { id: 'overview', label: '概述' },\n { id: 'mcp-config', label: 'MCP 配置' },\n { id: 'upload-audio', label: '上传音频' },\n { id: 'first-eval', label: '第一次评测' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API 参考', children: [\n { id: 'audio-upload-api', label: '音频上传 API' },\n { id: 'eval-tools', label: '评测工具总览' },\n { id: 'tool-english-word', label: 'evaluate_english_word' },\n { id: 'tool-english-sentence', label: 'evaluate_english_sentence' },\n { id: 'tool-english-paragraph', label: 'evaluate_english_paragraph' },\n { id: 'tool-english-word-pron', label: 'evaluate_english_word_pron' },\n { id: 'tool-english-sentence-pron', label: 'evaluate_english_sentence_pron' },\n { id: 'tool-english-phonics', label: 'evaluate_english_phonics' },\n { id: 'tool-chinese', label: 'evaluate_chinese' },\n { id: 'result-fields', label: '评测结果字段' },\n { id: 'error-codes', label: '错误码' },\n ]},\n { id: 'integration', icon: Code2, label: '集成指南', children: [\n { id: 'config-cursor', label: 'Cursor 配置' },\n { id: 'config-claude', label: 'Claude Desktop 配置' },\n { id: 'config-other', label: '豆包 / 钉钉 / 其他' },\n { id: 'code-python', label: 'Python 示例' },\n { id: 'code-javascript', label: 'JavaScript 示例' },\n ]},\n { id: 'best-practices', icon: FileText, label: '最佳实践', children: [\n { id: 'prompt-templates', label: 'Prompt 模板' },\n { id: 'error-handling', label: '错误处理' },\n { id: 'performance', label: '性能优化' },\n ]},\n];\n\nexport default function DocsPage() {\n const [, setActiveSection] = useState('quick-start');\n\n return (\n
\n
\n \n 返回首页\n \n\n

开发者文档

\n

驰声语音评测 MCP · v2.3.0

\n\n
\n {/* Sidebar */}\n \n\n {/* Content */}\n
\n\n {/* ══════ 快速开始 ══════ */}\n \n\n \n

chivox-speech-eval 是一个基于 MCP(Model Context Protocol)的语音评测服务器,为 AI 助手提供驰声中英文语音评测能力。

\n

MCP 是 AI 助手与外部工具/服务通信的标准化协议。通过 MCP,AI 可以直接调用专业工具,无需用户手动复制粘贴数据。

\n 当前版本 v2.3.0,服务端点:https://speech-eval.site\n

工作流程:

\n
    \n
  1. 用户上传音频 → POST /upload → 获得 audioId
  2. \n
  3. AI 调用评测 → evaluate_xxx(audioId, text) → 获得评测结果
  4. \n
  5. 音频自动删除(评测完成或 5 分钟后过期)
  6. \n
\n
\n\n \n

在你的 AI 客户端中添加以下 MCP 服务器配置:

\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n}`}\n 所有支持 MCP 的客户端(Cursor、Claude Desktop、豆包、钉钉等)均使用以上配置,仅 UI 入口不同。详见下方集成指南。\n
\n\n \n

评测前需先上传音频文件,获取 audioId。

\n {`curl -X POST https://speech-eval.site/upload \\\\\n -H \"Content-Type: audio/mp3\" \\\\\n --data-binary @audio.mp3`}\n

返回示例:

\n {`{\n \"audioId\": \"audio_1234567890_abc123\",\n \"size\": 38528,\n \"compressed\": false,\n \"expiresIn\": \"5 分钟\"\n}`}\n 音频上传后 5 分钟内有效,评测完成后会自动删除。请在上传后尽快进行评测。\n

支持的音频格式:mp3, wav, ogg, m4a, aac, pcm

\n

限制:单文件最大 50MB,大于 500KB 的文件自动压缩为 16kHz / 单声道 / 32kbps。

\n
\n\n \n

上传音频获得 audioId 后,告诉 AI 你要评测的内容,AI 会自动调用相应工具。

\n
\n
\n
你
\n

请帮我评测这个音频的英文句子发音,参考文本是 "The quick brown fox jumps over the lazy dog."

\n
\n
\n
AI
\n
\n

正在调用 evaluate_english_sentence ...

\n

评测完成!总分 82,准确度 78,流利度 85。

\n
\n
\n
\n
\n
\n\n {/* ══════ API 参考 ══════ */}\n \n\n \n
\n POST\n https://speech-eval.site/upload\n
\n \n

响应字段:

\n \n
\n\n \n
\n \n \n \n \n \n \n \n \n {[\n ['evaluate_english_word','英文单词评测','en.word.score','< 20秒'],\n ['evaluate_english_sentence','英文句子评测','en.sent.score','≤ 40秒'],\n ['evaluate_english_paragraph','英文段落评测','en.pred.score','≤ 300秒'],\n ['evaluate_english_word_pron','英文单词纠音','en.word.pron','< 20秒'],\n ['evaluate_english_sentence_pron','英文句子纠音','en.sent.pron','≤ 40秒'],\n ['evaluate_english_phonics','自然拼读评测','en.nsp.score','< 20秒'],\n ['evaluate_chinese','中文评测','cn.word/sent.score','< 60秒'],\n ].map(([tool,fn,id,dur]) => (\n \n \n \n \n \n \n ))}\n \n
工具名功能题型 ID最大时长
{tool}{fn}{id}{dur}
\n
\n
\n\n {/* 每个评测工具 */}\n \n

评测英文单词的发音质量。

\n \n

示例对话:

\n {`evaluate_english_word(\n audioId = \"audio_xxx\",\n word = \"magnificent\",\n accent = \"american\"\n)`}\n
\n\n \n

评测英文句子的发音质量,包括流利度、准确度等。

\n \n {`evaluate_english_sentence(\n audioId = \"audio_xxx\",\n sentence = \"The quick brown fox jumps over the lazy dog.\"\n)`}\n
\n\n \n

评测英文段落的整体发音质量。

\n \n
\n\n \n

英文单词纠音,可检测多读、漏读、错读。

\n \n 纠音工具会返回详细的音素级错误信息,包括多读(insertion)、漏读(deletion)、错读(substitution)的具体位置。\n
\n\n \n

英文句子纠音,检测句子中每个单词的发音问题。

\n \n
\n\n \n

自然拼读评测,适用于拼读规则练习场景。

\n \n
\n\n \n

评测中文发音,自动识别词语/句子模式。

\n \n 自动识别模式:≤ 10 个字符使用词语模式,{'>'}10 个字符使用句子模式。\n {`evaluate_chinese(\n audioId = \"audio_xxx\",\n text = \"你好,世界\"\n)`}\n
\n\n \n

所有评测工具返回统一的结果结构:

\n {`{\n \"overall\": 85,\n \"accuracy\": 82,\n \"pron\": 88,\n \"fluency\": {\n \"overall\": 78,\n \"speed\": 65,\n \"pause\": 2\n },\n \"details\": [\n { \"char\": \"hello\", \"score\": 85 },\n { \"char\": \"world\", \"score\": 82 }\n ]\n}`}\n
\n \n \n \n \n \n \n \n {[\n ['overall','0-100','总分,综合语音质量评分'],\n ['accuracy','0-100','准确度,音素级别的发音准确率'],\n ['pron','0-100','发音分,整体发音质量'],\n ['fluency.overall','0-100','流利度,语流的自然度与平滑度'],\n ['fluency.speed','0-100','语速,每分钟词/音节计量'],\n ['fluency.pause','number','停顿次数,不自然停顿检测'],\n ['details','array','逐词/逐字评分详情'],\n ].map(([field,range,desc])=>(\n \n \n \n \n \n ))}\n \n
字段范围说明
{field}{range}{desc}
\n
\n
\n\n \n
\n \n \n \n \n \n \n \n {[\n ['音频 ID 无效或已过期','音频上传后 5 分钟内有效,评测完成后自动删除','重新上传音频'],\n ['服务器繁忙,排队已满','当前请求过多','稍后重试'],\n ['存储空间已满','服务器临时音频存储已满','稍后重试,系统会自动清理'],\n ['音频格式不支持','上传了不支持的文件类型','使用 mp3/wav/ogg/m4a/aac/pcm'],\n ['音频时长超限','音频时长超过该题型最大限制','裁剪音频后重试'],\n ].map(([scene,reason,fix])=>(\n \n \n \n \n \n ))}\n \n
场景原因解决方式
{scene}{reason}{fix}
\n
\n
\n
\n\n {/* ══════ 集成指南 ══════ */}\n \n\n \n
    \n
  1. 打开 Cursor 设置(Cmd + ,)
  2. \n
  3. 左侧选择 MCP(或搜索 "MCP")
  4. \n
  5. 点击 Add new MCP server
  6. \n
  7. 填写配置:
  8. \n
\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n}`}\n
    \n
  1. 点击 Save 保存
  2. \n
  3. 在对话中输入「帮我评测这段英文发音」即可触发
  4. \n
\n
\n\n \n

编辑配置文件:

\n
    \n
  • macOS:~/Library/Application Support/Claude/claude_desktop_config.json
  • \n
  • Windows:%APPDATA%\\Claude\\claude_desktop_config.json
  • \n
\n {`{\n \"mcpServers\": {\n \"chivox-speech-eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n }\n }\n}`}\n
\n\n \n

参照各自的 MCP 配置界面,添加以下配置:

\n
\n \n \n \n \n \n \n \n \n \n
配置项值
类型streamable-http
URLhttps://speech-eval.site/mcp
\n
\n 现已支持 HTTPS,可安全用于各类 AI 平台。\n
\n\n \n

使用 Python requests 库上传音频并获取 audioId:

\n {`import requests\n\nwith open('audio.mp3', 'rb') as f:\n r = requests.post(\n 'https://speech-eval.site/upload',\n data=f,\n headers={'Content-Type': 'audio/mp3'}\n )\n\nresult = r.json()\nprint(f\"audioId: {result['audioId']}\")\nprint(f\"size: {result['size']} bytes\")\nprint(f\"expires: {result['expiresIn']}\")`}\n
\n\n \n

使用 Node.js 上传音频:

\n {`const fs = require('fs');\nconst https = require('https');\n\nconst audioData = fs.readFileSync('audio.mp3');\n\nconst req = https.request({\n hostname: 'speech-eval.site',\n port: 443,\n path: '/upload',\n method: 'POST',\n headers: {\n 'Content-Type': 'audio/mp3',\n 'Content-Length': audioData.length\n }\n}, (res) => {\n let data = '';\n res.on('data', chunk => data += chunk);\n res.on('end', () => {\n const result = JSON.parse(data);\n console.log('audioId:', result.audioId);\n });\n});\n\nreq.write(audioData);\nreq.end();`}\n
\n
\n\n {/* ══════ 最佳实践 ══════ */}\n \n\n \n

以下是推荐的 Prompt 模板,帮助你引导 LLM 对评测结果进行深度分析:

\n\n
\n
\n

模板 1:发音诊断

\n {`你是一位专业的英语口语教练。请根据以下 MCP 评测结果分析学生的发音表现:\n\n评测结果:{evaluation_result}\n\n请按以下格式输出:\n1. 总体评价(一句话)\n2. 优势项(准确度/流利度等 >80 分的指标)\n3. 弱项分析(<70 分的指标,定位到具体音素)\n4. 针对性练习建议(2-3 条具体可操作的建议)`}\n
\n\n
\n

模板 2:练习生成

\n {`根据以下弱项列表,为学生生成针对性的口语练习材料:\n\n弱项:{weak_points}\n\n请生成:\n1. 3 个绕口令(专门针对弱项音素)\n2. 5 个包含目标音素的常用短句(标注重音和连读)\n3. 1 段跟读练习段落(50-80 词,高频使用目标音素)`}\n
\n\n
\n

模板 3:学习报告

\n {`你是一位数据分析师,请根据学生近 7 天的评测历史生成学习报告:\n\n评测历史:{history}\n\n报告要求:\n1. 整体趋势(进步/持平/退步)\n2. 各维度变化(准确度、流利度、语速)\n3. 本周最大进步项\n4. 下周重点练习建议\n5. 鼓励性总结(保持学习动力)`}\n
\n
\n
\n\n \n

推荐的错误处理策略:

\n
    \n
  • \n \n 音频过期:评测前检查 audioId 是否仍有效。如果返回「已过期」,提示用户重新上传。建议在上传后 3 分钟内完成评测。\n
  • \n
  • \n \n 服务繁忙:遇到排队满时,使用指数退避策略重试(1s → 2s → 4s),最多 3 次。\n
  • \n
  • \n \n 音频质量差:建议在上传前在客户端进行基本的音频质量检查(静音检测、时长检测),减少无效调用。\n
  • \n
\n
\n\n \n
    \n
  • \n \n 音频压缩:上传前在客户端将音频转为 16kHz 单声道 mp3 格式,可减少 60-80% 的上传体积和评测延迟。\n
  • \n
  • \n \n 避免重复评测:对相同音频 + 参考文本的组合做客户端缓存,避免重复调用消耗配额。\n
  • \n
  • \n \n 选择合适的工具:单词评测比句子评测快 3-5 倍。如果只需要单词级别的分数,不要用句子评测工具。\n
  • \n
  • \n \n 批量场景:如果需要同时评测多段音频(如班级考试),建议使用批量评测接口(即将上线),避免并发限制。\n
  • \n
\n
\n
\n\n {/* ══════ 服务信息 ══════ */}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n
端点方法说明
/uploadPOST音频文件上传
/mcpPOSTMCP JSON-RPC 接口
/healthGET健康检查
\n
\n
\n \n
\n \n \n \n \n \n \n \n {[\n ['存储限制','500MB','最大音频存储空间'],\n ['最大排队','10','等待处理的请求数'],\n ['最大并发','3','同时处理的评测数'],\n ['音频有效期','5 分钟','上传后未评测自动过期'],\n ['文件大小限制','50MB','单个音频文件最大'],\n ].map(([k,v,d])=>(\n \n ))}\n \n
配置项默认值说明
{k}{v}{d}
\n
\n
\n \n
\n {[\n { ver: 'v2.3.0', date: '2026-03-25', desc: '支持 HTTPS,域名 speech-eval.site' },\n { ver: 'v2.2.0', date: '2026-03-24', desc: '添加 MCP 配置指南(Cursor / Claude Desktop)' },\n { ver: 'v2.1.0', date: '2026-03-24', desc: '简化上传流程,统一使用 HTTP API' },\n { ver: 'v2.0.0', date: '2026-03-24', desc: '初始版本,支持多种评测类型' },\n ].map(l => (\n
\n {l.ver}\n {l.date}\n {l.desc}\n
\n ))}\n
\n
\n
\n\n
\n
\n
\n
\n );\n}\n"}, "bfe46122c8fad240ab22d7975addecc9deae3416": {"t": 1785765818.3646426, "n": 33795, "h": "6a5f3755d0e35235", "c": "'use client';\n\nimport { useState } from 'react';\nimport { Link } from '@/i18n/routing';\nimport { ArrowLeft, BookOpen, Code2, Zap, FileText, ChevronRight, Copy, Check, Terminal, Globe, Mic, MessageSquare, BarChart3, AlertTriangle, Lightbulb } from 'lucide-react';\n\nfunction CopyButton({ text }: { text: string }) {\n const [copied, setCopied] = useState(false);\n return (\n { navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000); }}\n className=\"absolute top-3 right-3 p-1.5 rounded-md bg-white/5 hover:bg-white/10 transition-colors text-zinc-400 hover:text-zinc-200\"\n >\n {copied ? : }\n \n );\n}\n\nfunction CodeBlock({ filename, lang, children }: { filename?: string; lang?: string; children: string }) {\n return (\n
\n {filename && (\n
\n \n \n \n {filename}\n {lang && {lang}}\n
\n )}\n \n
{children.trim()}
\n
\n );\n}\n\nfunction DocSection({ id, icon: Icon, title, children }: { id: string; icon: React.ElementType; title: string; children: React.ReactNode }) {\n return (\n
\n
\n \n

{title}

\n
\n
\n {children}\n
\n
\n );\n}\n\nfunction SubDoc({ id, title, children }: { id: string; title: string; children: React.ReactNode }) {\n return (\n
\n

{title}

\n
{children}
\n
\n );\n}\n\nfunction ParamTable({ params }: { params: { name: string; type: string; required: boolean; desc: string }[] }) {\n return (\n
\n \n \n \n \n \n \n \n \n {params.map(p => (\n \n \n \n \n \n \n ))}\n \n
参数类型必填说明
{p.name}{p.type}{p.required ? ✓ : —}{p.desc}
\n
\n );\n}\n\nfunction Callout({ type = 'info', children }: { type?: 'info' | 'warning' | 'tip'; children: React.ReactNode }) {\n const styles = {\n info: 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900 dark:bg-blue-950/30 dark:text-blue-200',\n warning: 'border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-900 dark:bg-amber-950/30 dark:text-amber-200',\n tip: 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950/30 dark:text-emerald-200',\n };\n const icons = { info: Globe, warning: AlertTriangle, tip: Lightbulb };\n const Ic = icons[type];\n return (\n
\n \n
{children}
\n
\n );\n}\n\nconst NAV = [\n { id: 'quick-start', icon: Zap, label: '快速开始', children: [\n { id: 'overview', label: '概述' },\n { id: 'mcp-config', label: 'MCP 配置' },\n { id: 'upload-audio', label: '上传音频' },\n { id: 'first-eval', label: '第一次评测' },\n ]},\n { id: 'api-reference', icon: BookOpen, label: 'API 参考', children: [\n { id: 'audio-upload-api', label: '音频上传 API' },\n { id: 'eval-tools', label: '评测工具总览' },\n { id: 'tool-english-word', label: 'evaluate_english_word' },\n { id: 'tool-english-sentence', label: 'evaluate_english_sentence' },\n { id: 'tool-english-paragraph', label: 'evaluate_english_paragraph' },\n { id: 'tool-english-word-pron', label: 'evaluate_english_word_pron' },\n { id: 'tool-english-sentence-pron', label: 'evaluate_english_sentence_pron' },\n { id: 'tool-english-phonics', label: 'evaluate_english_phonics' },\n { id: 'tool-chinese', label: 'evaluate_chinese' },\n { id: 'result-fields', label: '评测结果字段' },\n { id: 'error-codes', label: '错误码' },\n ]},\n { id: 'integration', icon: Code2, label: '集成指南', children: [\n { id: 'config-cursor', label: 'Cursor 配置' },\n { id: 'config-claude', label: 'Claude Desktop 配置' },\n { id: 'config-other', label: '豆包 / 钉钉 / 其他' },\n { id: 'code-python', label: 'Python 示例' },\n { id: 'code-javascript', label: 'JavaScript 示例' },\n ]},\n { id: 'best-practices', icon: FileText, label: '最佳实践', children: [\n { id: 'prompt-templates', label: 'Prompt 模板' },\n { id: 'error-handling', label: '错误处理' },\n { id: 'performance', label: '性能优化' },\n ]},\n];\n\nexport default function DocsPage() {\n const [activeSection, setActiveSection] = useState('quick-start');\n\n return (\n
\n
\n \n 返回首页\n \n\n

开发者文档

\n

驰声语音评测 MCP · v2.3.0

\n\n
\n {/* Sidebar */}\n \n\n {/* Content */}\n
\n\n {/* ══════ 快速开始 ══════ */}\n \n\n \n

chivox-speech-eval 是一个基于 MCP(Model Context Protocol)的语音评测服务器,为 AI 助手提供驰声中英文语音评测能力。

\n

MCP 是 AI 助手与外部工具/服务通信的标准化协议。通过 MCP,AI 可以直接调用专业工具,无需用户手动复制粘贴数据。

\n 当前版本 v2.3.0,服务端点:https://speech-eval.site\n

工作流程:

\n
    \n
  1. 用户上传音频 → POST /upload → 获得 audioId
  2. \n
  3. AI 调用评测 → evaluate_xxx(audioId, text) → 获得评测结果
  4. \n
  5. 音频自动删除(评测完成或 5 分钟后过期)
  6. \n
\n
\n\n \n

在你的 AI 客户端中添加以下 MCP 服务器配置:

\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n}`}\n 所有支持 MCP 的客户端(Cursor、Claude Desktop、豆包、钉钉等)均使用以上配置,仅 UI 入口不同。详见下方集成指南。\n
\n\n \n

评测前需先上传音频文件,获取 audioId。

\n {`curl -X POST https://speech-eval.site/upload \\\\\n -H \"Content-Type: audio/mp3\" \\\\\n --data-binary @audio.mp3`}\n

返回示例:

\n {`{\n \"audioId\": \"audio_1234567890_abc123\",\n \"size\": 38528,\n \"compressed\": false,\n \"expiresIn\": \"5 分钟\"\n}`}\n 音频上传后 5 分钟内有效,评测完成后会自动删除。请在上传后尽快进行评测。\n

支持的音频格式:mp3, wav, ogg, m4a, aac, pcm

\n

限制:单文件最大 50MB,大于 500KB 的文件自动压缩为 16kHz / 单声道 / 32kbps。

\n
\n\n \n

上传音频获得 audioId 后,告诉 AI 你要评测的内容,AI 会自动调用相应工具。

\n
\n
\n
你
\n

请帮我评测这个音频的英文句子发音,参考文本是 "The quick brown fox jumps over the lazy dog."

\n
\n
\n
AI
\n
\n

正在调用 evaluate_english_sentence ...

\n

评测完成!总分 82,准确度 78,流利度 85。

\n
\n
\n
\n
\n
\n\n {/* ══════ API 参考 ══════ */}\n \n\n \n
\n POST\n https://speech-eval.site/upload\n
\n \n

响应字段:

\n \n
\n\n \n
\n \n \n \n \n \n \n \n \n {[\n ['evaluate_english_word','英文单词评测','en.word.score','< 20秒'],\n ['evaluate_english_sentence','英文句子评测','en.sent.score','≤ 40秒'],\n ['evaluate_english_paragraph','英文段落评测','en.pred.score','≤ 300秒'],\n ['evaluate_english_word_pron','英文单词纠音','en.word.pron','< 20秒'],\n ['evaluate_english_sentence_pron','英文句子纠音','en.sent.pron','≤ 40秒'],\n ['evaluate_english_phonics','自然拼读评测','en.nsp.score','< 20秒'],\n ['evaluate_chinese','中文评测','cn.word/sent.score','< 60秒'],\n ].map(([tool,fn,id,dur]) => (\n \n \n \n \n \n \n ))}\n \n
工具名功能题型 ID最大时长
{tool}{fn}{id}{dur}
\n
\n
\n\n {/* 每个评测工具 */}\n \n

评测英文单词的发音质量。

\n \n

示例对话:

\n {`evaluate_english_word(\n audioId = \"audio_xxx\",\n word = \"magnificent\",\n accent = \"american\"\n)`}\n
\n\n \n

评测英文句子的发音质量,包括流利度、准确度等。

\n \n {`evaluate_english_sentence(\n audioId = \"audio_xxx\",\n sentence = \"The quick brown fox jumps over the lazy dog.\"\n)`}\n
\n\n \n

评测英文段落的整体发音质量。

\n \n
\n\n \n

英文单词纠音,可检测多读、漏读、错读。

\n \n 纠音工具会返回详细的音素级错误信息,包括多读(insertion)、漏读(deletion)、错读(substitution)的具体位置。\n
\n\n \n

英文句子纠音,检测句子中每个单词的发音问题。

\n \n
\n\n \n

自然拼读评测,适用于拼读规则练习场景。

\n \n
\n\n \n

评测中文发音,自动识别词语/句子模式。

\n \n 自动识别模式:≤ 10 个字符使用词语模式,{'>'}10 个字符使用句子模式。\n {`evaluate_chinese(\n audioId = \"audio_xxx\",\n text = \"你好,世界\"\n)`}\n
\n\n \n

所有评测工具返回统一的结果结构:

\n {`{\n \"overall\": 85,\n \"accuracy\": 82,\n \"pron\": 88,\n \"fluency\": {\n \"overall\": 78,\n \"speed\": 65,\n \"pause\": 2\n },\n \"details\": [\n { \"char\": \"hello\", \"score\": 85 },\n { \"char\": \"world\", \"score\": 82 }\n ]\n}`}\n
\n \n \n \n \n \n \n \n {[\n ['overall','0-100','总分,综合语音质量评分'],\n ['accuracy','0-100','准确度,音素级别的发音准确率'],\n ['pron','0-100','发音分,整体发音质量'],\n ['fluency.overall','0-100','流利度,语流的自然度与平滑度'],\n ['fluency.speed','0-100','语速,每分钟词/音节计量'],\n ['fluency.pause','number','停顿次数,不自然停顿检测'],\n ['details','array','逐词/逐字评分详情'],\n ].map(([field,range,desc])=>(\n \n \n \n \n \n ))}\n \n
字段范围说明
{field}{range}{desc}
\n
\n
\n\n \n
\n \n \n \n \n \n \n \n {[\n ['音频 ID 无效或已过期','音频上传后 5 分钟内有效,评测完成后自动删除','重新上传音频'],\n ['服务器繁忙,排队已满','当前请求过多','稍后重试'],\n ['存储空间已满','服务器临时音频存储已满','稍后重试,系统会自动清理'],\n ['音频格式不支持','上传了不支持的文件类型','使用 mp3/wav/ogg/m4a/aac/pcm'],\n ['音频时长超限','音频时长超过该题型最大限制','裁剪音频后重试'],\n ].map(([scene,reason,fix])=>(\n \n \n \n \n \n ))}\n \n
场景原因解决方式
{scene}{reason}{fix}
\n
\n
\n
\n\n {/* ══════ 集成指南 ══════ */}\n \n\n \n
    \n
  1. 打开 Cursor 设置(Cmd + ,)
  2. \n
  3. 左侧选择 MCP(或搜索 "MCP")
  4. \n
  5. 点击 Add new MCP server
  6. \n
  7. 填写配置:
  8. \n
\n {`{\n \"name\": \"chivox-speech-eval\",\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n}`}\n
    \n
  1. 点击 Save 保存
  2. \n
  3. 在对话中输入「帮我评测这段英文发音」即可触发
  4. \n
\n
\n\n \n

编辑配置文件:

\n
    \n
  • macOS:~/Library/Application Support/Claude/claude_desktop_config.json
  • \n
  • Windows:%APPDATA%\\Claude\\claude_desktop_config.json
  • \n
\n {`{\n \"mcpServers\": {\n \"chivox-speech-eval\": {\n \"type\": \"streamable-http\",\n \"url\": \"https://speech-eval.site/mcp\"\n }\n }\n}`}\n
\n\n \n

参照各自的 MCP 配置界面,添加以下配置:

\n
\n \n \n \n \n \n \n \n \n \n
配置项值
类型streamable-http
URLhttps://speech-eval.site/mcp
\n
\n 现已支持 HTTPS,可安全用于各类 AI 平台。\n
\n\n \n

使用 Python requests 库上传音频并获取 audioId:

\n {`import requests\n\nwith open('audio.mp3', 'rb') as f:\n r = requests.post(\n 'https://speech-eval.site/upload',\n data=f,\n headers={'Content-Type': 'audio/mp3'}\n )\n\nresult = r.json()\nprint(f\"audioId: {result['audioId']}\")\nprint(f\"size: {result['size']} bytes\")\nprint(f\"expires: {result['expiresIn']}\")`}\n
\n\n \n

使用 Node.js 上传音频:

\n {`const fs = require('fs');\nconst https = require('https');\n\nconst audioData = fs.readFileSync('audio.mp3');\n\nconst req = https.request({\n hostname: 'speech-eval.site',\n port: 443,\n path: '/upload',\n method: 'POST',\n headers: {\n 'Content-Type': 'audio/mp3',\n 'Content-Length': audioData.length\n }\n}, (res) => {\n let data = '';\n res.on('data', chunk => data += chunk);\n res.on('end', () => {\n const result = JSON.parse(data);\n console.log('audioId:', result.audioId);\n });\n});\n\nreq.write(audioData);\nreq.end();`}\n
\n
\n\n {/* ══════ 最佳实践 ══════ */}\n \n\n \n

以下是推荐的 Prompt 模板,帮助你引导 LLM 对评测结果进行深度分析:

\n\n
\n
\n

模板 1:发音诊断

\n {`你是一位专业的英语口语教练。请根据以下 MCP 评测结果分析学生的发音表现:\n\n评测结果:{evaluation_result}\n\n请按以下格式输出:\n1. 总体评价(一句话)\n2. 优势项(准确度/流利度等 >80 分的指标)\n3. 弱项分析(<70 分的指标,定位到具体音素)\n4. 针对性练习建议(2-3 条具体可操作的建议)`}\n
\n\n
\n

模板 2:练习生成

\n {`根据以下弱项列表,为学生生成针对性的口语练习材料:\n\n弱项:{weak_points}\n\n请生成:\n1. 3 个绕口令(专门针对弱项音素)\n2. 5 个包含目标音素的常用短句(标注重音和连读)\n3. 1 段跟读练习段落(50-80 词,高频使用目标音素)`}\n
\n\n
\n

模板 3:学习报告

\n {`你是一位数据分析师,请根据学生近 7 天的评测历史生成学习报告:\n\n评测历史:{history}\n\n报告要求:\n1. 整体趋势(进步/持平/退步)\n2. 各维度变化(准确度、流利度、语速)\n3. 本周最大进步项\n4. 下周重点练习建议\n5. 鼓励性总结(保持学习动力)`}\n
\n
\n
\n\n \n

推荐的错误处理策略:

\n
    \n
  • \n \n 音频过期:评测前检查 audioId 是否仍有效。如果返回「已过期」,提示用户重新上传。建议在上传后 3 分钟内完成评测。\n
  • \n
  • \n \n 服务繁忙:遇到排队满时,使用指数退避策略重试(1s → 2s → 4s),最多 3 次。\n
  • \n
  • \n \n 音频质量差:建议在上传前在客户端进行基本的音频质量检查(静音检测、时长检测),减少无效调用。\n
  • \n
\n
\n\n \n
    \n
  • \n \n 音频压缩:上传前在客户端将音频转为 16kHz 单声道 mp3 格式,可减少 60-80% 的上传体积和评测延迟。\n
  • \n
  • \n \n 避免重复评测:对相同音频 + 参考文本的组合做客户端缓存,避免重复调用消耗配额。\n
  • \n
  • \n \n 选择合适的工具:单词评测比句子评测快 3-5 倍。如果只需要单词级别的分数,不要用句子评测工具。\n
  • \n
  • \n \n 批量场景:如果需要同时评测多段音频(如班级考试),建议使用批量评测接口(即将上线),避免并发限制。\n
  • \n
\n
\n
\n\n {/* ══════ 服务信息 ══════ */}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n
端点方法说明
/uploadPOST音频文件上传
/mcpPOSTMCP JSON-RPC 接口
/healthGET健康检查
\n
\n
\n \n
\n \n \n \n \n \n \n \n {[\n ['存储限制','500MB','最大音频存储空间'],\n ['最大排队','10','等待处理的请求数'],\n ['最大并发','3','同时处理的评测数'],\n ['音频有效期','5 分钟','上传后未评测自动过期'],\n ['文件大小限制','50MB','单个音频文件最大'],\n ].map(([k,v,d])=>(\n \n ))}\n \n
配置项默认值说明
{k}{v}{d}
\n
\n
\n \n
\n {[\n { ver: 'v2.3.0', date: '2026-03-25', desc: '支持 HTTPS,域名 speech-eval.site' },\n { ver: 'v2.2.0', date: '2026-03-24', desc: '添加 MCP 配置指南(Cursor / Claude Desktop)' },\n { ver: 'v2.1.0', date: '2026-03-24', desc: '简化上传流程,统一使用 HTTP API' },\n { ver: 'v2.0.0', date: '2026-03-24', desc: '初始版本,支持多种评测类型' },\n ].map(l => (\n
\n {l.ver}\n {l.date}\n {l.desc}\n
\n ))}\n
\n
\n
\n\n
\n
\n
\n
\n );\n}\n"}}}}