当前位置: 首页 > news >正文

调用通义千问大模型实现流式对话

前言

我使用的是硅基流动中通义千问免费的大模型:

在这里插入图片描述

我的技术栈使用的 Next14.2 全栈框架。

代码结构

需要使用的库:

npm i ai openai

目录结构:

基础测试页面 test-openai/page.tsx:

'use client';import { useChat } from 'ai/react';export default function TestDeepseek() {const { messages, input, handleInputChange, handleSubmit } = useChat({api: '/api/chat/openai',});return (<div className="flex flex-col w-full max-w-md py-24 mx-auto stretch"><h1 className="text-2xl font-bold mb-4">Deepseek 聊天测试</h1>{messages.map(message => (<div key={message.id} className="whitespace-pre-wrap mb-4 p-3 border rounded-lg"><div className="font-bold">{message.role === 'user' ? '用户: ' : 'AI: '}</div><div className="mt-1">{message.content}</div></div>))}<form onSubmit={handleSubmit} className="mt-4"><inputclassName="w-full p-2 border border-gray-300 rounded shadow-sm dark:bg-gray-800 dark:border-gray-700"value={input}placeholder="输入消息..."onChange={handleInputChange}/><button type="submit" className="mt-2 w-full p-2 bg-blue-500 text-white rounded hover:bg-blue-600">发送</button></form></div>);
}

后端接口 app/api/chat/openai/route.ts:

import { handleChatRequest } from '@/lib/openai';
import { NextRequest, NextResponse } from 'next/server';
import { MessageRequestBody } from '@/types/chat';// 设置最大响应时间为30秒
export const maxDuration = 30;/*** 处理POST请求,使用QwQ-32B模型进行聊天* * @param request NextRequest请求对象* @returns 返回流式响应*/
export async function POST(request: NextRequest) {try {// 从请求中获取消息数据const { messages } = (await request.json()) as MessageRequestBody;if (!messages || !Array.isArray(messages)) {return NextResponse.json({ error: '无效的消息格式' },{ status: 400 });}// 调用QwQ-32B处理函数并返回流式响应return handleChatRequest(messages);} catch (error) {console.error('处理QwQ-32B请求时出错:', error);return NextResponse.json({ error: '处理请求时发生错误: ' + (error instanceof Error ? error.message : String(error)) },{ status: 500 });}
}

lib/openai.ts

openai 规范调用大模型可以参考 deepseek文档:https://api-docs.deepseek.com/zh-cn/

也可以参考硅基流动的文档:https://docs.siliconflow.cn/cn/userguide/quickstart

import { Message } from '@/types/chat';
import { NextResponse } from 'next/server';
import OpenAI from 'openai';// 创建自定义OpenAI实例,使用SiliconFlow API
const openai = new OpenAI({apiKey: process.env.SILICONFLOW_API_KEY!,baseURL: process.env.SILICONFLOW_API_BASE!,  
});/*** 处理聊天请求的函数* 使用SiliconFlow API处理消息并返回流式响应* * @param messages 聊天消息数组* @returns 流式响应*/
export async function handleChatRequest(messages: Message[]) {try {// 检查API密钥是否配置if (!process.env.SILICONFLOW_API_KEY) {console.error('SiliconFlow API密钥未配置');return NextResponse.json({ error: '未配置SiliconFlow API密钥,请在.env文件中设置SILICONFLOW_API_KEY' },{ status: 500 });}// 检查API基础URL是否配置if (!process.env.SILICONFLOW_API_BASE) {console.error('SiliconFlow API基础URL未配置');return NextResponse.json({ error: '未配置SiliconFlow API基础URL,请在.env文件中设置SILICONFLOW_API_BASE' },{ status: 500 });}// 将消息格式转换为OpenAI格式const formattedMessages = messages.map(msg => ({role: msg.role,content: msg.content}));// 使用SiliconFlow API创建流式响应const response = await openai.chat.completions.create({model: 'Qwen/QwQ-32B', // 使用SiliconFlow提供的QwQ-32B模型messages: formattedMessages,stream: true,});// 创建并返回流式响应const encoder = new TextEncoder();const stream = new ReadableStream({async start(controller) {// 处理流式响应for await (const chunk of response) {const text = chunk.choices[0]?.delta?.content || '';if (text) {controller.enqueue(encoder.encode(text));}}controller.close();},});return new Response(stream, {headers: {'Content-Type': 'text/plain; charset=utf-8','Cache-Control': 'no-cache',},});} catch (error) {console.error('SiliconFlow API调用错误:', error);return NextResponse.json({ error: '调用SiliconFlow API时发生错误: ' + (error instanceof Error ? error.message : String(error)) },{ status: 500 });}
}

.env

# SILICONFLOW API密钥
SILICONFLOW_API_KEY=YOUR_API_KEY
SILICONFLOW_API_BASE=https://api.siliconflow.cn/v1# 其他环境变量

演示

在这里插入图片描述

http://www.lryc.cn/news/601483.html

相关文章:

  • 用 Python 轻松实现时间序列预测:Darts N-BEATS
  • 安卓怎么做一个像QQ一样的开关切换控件
  • 墨者:通过手工解决SQL手工注入漏洞测试(MongoDB数据库)
  • 机器学习特征选择 explanation and illustration of ANOVA
  • net8.0一键创建支持(Redis)
  • 【机器学习】第七章 特征工程
  • 基于大模型的预训练、量化、微调等完整流程解析
  • CLAP文本-音频基础模型: LEARNING AUDIO CONCEPTS FROM NATURAL LANGUAGE SUPERVISION
  • PDF文件被加密限制怎么办?专业级解除方案分享
  • 51核和ARM核单片机OTA实战解析(一)
  • 一分钟部署一个导航网站
  • MCU 通用AT指令处理框架
  • PDF转图片实用指南:如何批量高效转换?
  • 创建的springboot工程java文件夹下还是文件夹而不是包
  • 内网服务器实现从公网穿透
  • 单片机ADC采集机理层面详细分析(二)
  • 零基础学习性能测试第五章:JVM性能分析与调优-多线程检测与瓶颈分析
  • 【C语言网络编程基础】TCP 服务器详解
  • Rust与Java DynamoDB、MySQL CRM、tokio-pg、SVM、Custors实战指南
  • 墨者:通过手动解决SQL手工注入漏洞测试(MySQL数据库)
  • Wireshark TS | 发送数据超出接收窗口
  • 双面15.6寸智能访客机硬件规格书及对接第三方接口说明
  • 力扣 hot100 Day57
  • 数据江湖的“三国演义”:数据仓库、数据湖与湖仓一体的全景对比
  • 区块链:工作量证明与联邦学习
  • 神经网络知识讨论
  • 【旧文】Adobe Express使用教程
  • 7月27日星期日今日早报简报微语报早读
  • 数据赋能(340)——技术平台——共享平台
  • Spring之【Bean的生命周期】