导读:本期聚焦于小宵创作的《如何使用讯飞星火API实现WebSocket实时流式对话与功能调用?》,敬请观看详情。构建一个智能客服系统时,如果用户每次提问都需要等待大模型完整生成才能看到回复,体验会非常糟糕。为了解决这个延迟痛点,我们可以引入流式输出机制。本文将以智能语音助手场景为例,详细讲解如何通过WebSocket协议接入讯飞星火API。不仅会剖析实时流式对话的底层通信逻辑,还会深入探讨如何利用Function Call功能让大模型与外部业务系统进行交互。通过具体的代码实例,带你掌握鉴权认证、参数配置以及结果解析的全流程,帮助你快速搭建具备动态响应能力的AI应用。

在构建自然语言处理应用时,大模型的响应速度往往直接决定了用户体验。传统的HTTP请求采用一问一答的模式,必须等待模型生成完整结果后才能返回给客户端,这在处理长文本时会导致明显的等待时间。讯飞星火API提供了基于WebSocket的实时流式对话能力,允许服务端在模型生成过程中逐字推送结果,从而实现类似打字机的效果。不仅如此,通过功能调用机制,大模型还能与外部业务系统进行交互,极大地拓展了应用边界。

如何使用讯飞星火API实现WebSocket实时流式对话与功能调用?

WebSocket协议与星火API的鉴权机制

WebSocket是一种在单个TCP连接上进行全双工通信的协议。与HTTP每次请求都需要建立新连接不同,WebSocket建立连接后,客户端和服务端可以随时互相发送数据。这种特性非常适合流式对话场景,因为大模型在推理时是逐个Token生成的,通过WebSocket可以立即将生成的Token推送给客户端,而不必等待整段文本生成完毕。

要建立WebSocket连接,首先需要解决鉴权问题。讯飞星火API的鉴权机制基于HMAC-SHA256算法生成签名。开发者需要使用APIKey和APISecret对请求参数进行加密,生成一个带有时间戳和签名的URL。服务端接收到连接请求后,会验证签名是否有效以及时间戳是否在有效期内。这种机制确保了请求的合法性和不可篡改性,防止API密钥被恶意盗用。

import base64
import hashlib
import hmac
from datetime import datetime
from urllib.parse import urlencode

def generate_auth_url(api_key, api_secret, host, path, method="GET"):
    # 生成RFC1123格式的日期时间戳
    utc_now = datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
    
    # 拼接签名原文
    signature_origin = f"host: {host}\ndate: {utc_now}\n{method} {path} HTTP/1.1"
    
    # 使用HMAC-SHA256进行加密
    signature_sha = hmac.new(api_secret.encode('utf-8'), signature_origin.encode('utf-8'), hashlib.sha256).digest()
    signature = base64.b64encode(signature_sha).decode('utf-8')
    
    # 构建请求参数
    authorization_origin = f'api_key="{api_key}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature}"'
    authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode('utf-8')
    
    # 生成最终鉴权URL
    params = {
        'authorization': authorization,
        'date': utc_now,
        'host': host
    }
    url = f"wss://{host}{path}?{urlencode(params)}"
    return url

在上述代码中,生成签名原文时必须严格按照指定的格式拼接,包括host、date和request-line。日期参数必须使用UTC时间并符合RFC1123格式,如果时区或格式不正确,服务端会直接拒绝连接。此外,生成的鉴权URL通常具有较短的有效期,一般为5分钟左右,因此客户端在发起连接前应实时生成,避免使用过期的URL导致连接失败。

构建实时流式对话请求与解析

建立WebSocket连接后,客户端需要发送特定结构的JSON数据来触发对话。星火API的请求体主要包含header、parameter和payload三个部分。header中通常包含应用ID和对话场景标识,parameter用于设置模型参数如最大Token数、温度值等,payload则包含了实际的对话历史记录和用户当前提问。通过维护对话历史,可以让模型理解上下文,实现多轮对话。

当服务端接收到请求后,会开始进行推理,并通过WebSocket连接持续推送JSON格式的响应数据。每个响应数据包包含当前生成的文本片段、本次对话的唯一标识以及结束标志。客户端需要不断接收这些数据包,提取其中的文本片段并追加到界面上,从而实现流式输出的视觉效果。当响应数据中的状态码指示会话结束时,客户端可以关闭连接或等待下一次提问。

import json
import websocket

def on_message(ws, message):
    data = json.loads(message)
    # 解析返回的文本片段
    if data['header']['code'] != 0:
        print(f"请求出错: {data['header']['message']}")
        ws.close()
        return
    
    # 提取AI生成的文本
    choices = data.get('payload', {}).get('choices', {})
    if choices:
        content = choices.get('text', {}).get('content', '')
        print(content, end='', flush=True)
        
    # 判断是否结束
    if data['header']['status'] == 2:
        print("\n对话结束")
        ws.close()

def on_error(ws, error):
    print(f"WebSocket错误: {error}")

def on_open(ws):
    # 构造请求参数
    payload = {
        "header": {
            "app_id": "your_app_id",
            "uid": "user_123"
        },
        "parameter": {
            "chat": {
                "domain": "generalv3",
                "max_tokens": 1024,
                "temperature": 0.5
            }
        },
        "payload": {
            "message": {
                "text": [
                    {"role": "user", "content": "请用一句话介绍WebSocket协议"}
                ]
            }
        }
    }
    ws.send(json.dumps(payload))

# 启动WebSocket客户端
# ws = websocket.WebSocketApp(auth_url, on_message=on_message, on_error=on_error, on_open=on_open)
# ws.run_forever()

在解析流式数据时,最关键的是判断header中的status字段。通常status为1表示正在生成中,为2表示当前这轮对话已经全部生成完毕。如果在网络不稳定的情况下,可能会出现数据包乱序或丢失的情况,因此建议在每轮对话结束后,根据完整的对话历史重新发起请求进行重试,而不是依赖断点续传。同时,为了防止长时间占用连接,应当设置合理的超时时间。

深度解析Function Call功能调用

大模型虽然具备丰富的知识储备,但其训练数据是静态的,无法直接获取实时天气、数据库中的订单状态等动态信息。Function Call功能就是为了解决这一痛点而设计的。开发者可以预先定义一组外部函数的名称、描述和参数结构,并将其随同用户提问一起发送给星火API。模型在理解用户意图后,如果发现需要调用外部工具,就会返回一个包含函数名和参数的指令,而不是直接生成自然语言回复。

在接收到模型返回的函数调用指令后,客户端应用需要解析出函数名和参数,在本地执行对应的业务逻辑,例如查询数据库或调用第三方API。获取到执行结果后,再将结果以特定的格式返回给大模型。大模型会结合这个结果和之前的对话上下文,为用户生成最终的自然语言总结。这种机制将大模型的推理能力与外部系统的数据获取能力完美结合。

# 定义外部函数结构
functions = [
    {
        "name": "get_weather",
        "description": "获取指定城市的实时天气信息",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "城市名称,例如:北京"
                }
            },
            "required": ["location"]
        }
    }
]

# 构造带有Function Call的请求Payload
payload_with_fc = {
    "header": {
        "app_id": "your_app_id"
    },
    "parameter": {
        "chat": {
            "domain": "generalv3",
            "functions": functions
        }
    },
    "payload": {
        "message": {
            "text": [
                {"role": "user", "content": "今天北京天气怎么样?"}
            ]
        }
    }
}

# 模拟接收到的模型响应
mock_response = {
    "header": {"code": 0, "status": 2},
    "payload": {
        "choices": {
            "text": [
                {
                    "role": "assistant",
                    "content": "",
                    "function_call": {
                        "name": "get_weather",
                        "arguments": "{\"location\":\"北京\"}"
                    }
                }
            ]
        }
    }
}

# 客户端处理函数调用
def handle_function_call(response_data):
    choices = response_data.get('payload', {}).get('choices', {})
    text_list = choices.get('text', [])
    if text_list:
        func_call = text_list[0].get('function_call')
        if func_call:
            func_name = func_call['name']
            args = json.loads(func_call['arguments'])
            # 执行本地函数
            if func_name == "get_weather":
                weather_info = query_local_weather(args['location'])
                # 将结果返回给大模型进行下一轮对话
                return weather_info
    return None

def query_local_weather(location):
    # 模拟查询外部天气API
    return f"{location}今天晴,气温25度"

使用Function Call时,函数描述的清晰度直接决定了模型调用的准确率。在定义description时,应当尽可能详细地说明函数的作用、适用场景以及参数的具体含义。如果参数是一个枚举值,最好在描述中列出所有可能的选项。此外,当本地函数执行失败或超时时,也应当将错误信息以结构化的方式返回给大模型,让模型能够自行判断是否需要向用户道歉或尝试调用其他备用函数。通过合理设计函数调用链路,可以构建出高度智能化的Agent系统。

讯飞星火APIWebSocket流式对话修改时间:2026-08-22 05:01:04

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。