ai应用一篇通【react环境】
首先进行技术选型。1 Deepseek文本大模型其官方具备面向nodejs环境的openai调用模型的sdk。2 环境直接起一个react项目直接在前端项目中调用Deepseek仅学习用生产还是要起nodejs轻服务。一 流式多轮对话1.1 基础请求先发出一个简单的文本请求。下面的apiKey需要替换为自己的key在deepseek开发平台中获取。下面的代码包含了OpenAI的简单用法importOpenAIfromopenai;import{useState,useEffect}fromreact;constopenainewOpenAI({baseURL:https://api.deepseek.com,apiKey:xxxxxxxxxxxxxxxxxxxxx,dangerouslyAllowBrowser:true,});exportdefaultfunctionDeepseekPage(){const[chatList,setChatList]useState([])useEffect((){openai.chat.completions.create({messages:[{role:system,content:You are a helpful assistant.},{role:user,content:hello.},],model:deepseek-v4-flash,thinking:{type:disabled},stream:false,}).then(res{console.log(res.choices[0].message.content);});},[])return(div{chatList.map((msg,index)(div key{index}strong{msg.role}:/strong{msg.content}/div))}/div)}注意下面代码中打印了一个res.choices[0].message.content内容如下{role:assistant,content:Hi! How can I help you today?}其中content是内容role是角色。现在页面上已经展示了一行返回内容了。1.2 多轮对话多轮对话的核心是将第一轮中模型的输出添加到 messages 末尾。上面代码中第一次请求的参数是这样的[{role:system,content:You are a helpful assistant.},{role:user,content:hello.},]我们将返回体和用户的写入内容追加到后面使参数变为[{role:system,content:You are a helpful assistant.},{role:user,content:hello.},{role:assistant,content:Hi! How can I help you today?}{role:user,content:xxxxxx},]同时在用户点击发送后触发接口请求。现在我们要做两件事1 上面代码中的useEffect要重复触发触发条件是有新的用户信息产生时所以书写一个变量记录该信息列表chatList并将其加入到useEffect依赖项中。2 状态的触发需要入口所以添加input和submit入口。exportdefaultfunctionDeepseekPage(){const[chatList,setChatList]useState([{role:system,content:You are a helpful assistant.},{role:user,content:hello.},])const[input,setInput]useState()useEffect((){if(chatList[chatList.length-1].role!user)returnopenai.chat.completions.create({messages:chatList,model:deepseek-v4-flash,thinking:{type:disabled},stream:false,}).then(res{console.log(res.choices[0].message.content);setChatList([...chatList,res.choices[0].message])});},[chatList])return(div{chatList.map((msg,index)(div key{index}strong{msg.role}:/strong{msg.content}/div))}Space vertical sizemediumSpace.Compact style{{width:100%}}Input defaultValueCombine input and buttonvalue{input}onChange{(e)setInput(e.target.value)}/Button typeprimaryonClick{(){setChatList([...chatList,{role:user,content:input}])}}Submit/Button/Space.Compact/Space/div)}现在输入文字点击按钮就可以实现多轮对话了。1.3 流式传输现在ai返回的语句是一次性全部返回的等待时候较长。我们使用ai对话的时候可以让它陆续返回实现打字机效果就是流式传输了。首先将stream设置为true让其开启流式传输。其次要在js中补充承接逻辑。1.3.1 fetch如果使用fetch来处理返回值会返回两个重要的数据value和doneReading。doneReading是流式数据是否已全部返回。value是返回的内容使用new TextDecoder().decode(value)进行解析读取。返回的内容解析后可能出现的情况示例如下第一轮返回data:{choices:[{delta:{content:你第二轮返回}}]}\n\n可以看到解析的时候一个有效json会分成多次返回一个有效json由data开启由\n结束。整个代码逻辑如下1 判断是否已经全部返回否则循环获取数据。2 将本次数据与上次数据相结合形成本次校验是否形成有效json?数据chunkValue。3 将有效数据以’data: ‘为开头’\n’为结尾取出4 解析json串后赋值1.3.2 openai我们这里使用openai来处理。首先将openai.chat.completions.create中的stream设置为true让其开启流式传输。先把useEffect中的代码提取出来成为方法使用。因为这个方法是独立性比较强的所以不需要封装为hook。const getCharDateasync(dataList, callback, streamfalse){letresawait openai.chat.completions.create({messages: dataList, model:deepseek-v4-flash, thinking:{type:disabled}, stream: stream,})callback([...dataList, res.choices[0].message])}现在添加流式处理逻辑。openai已对其做了封装实现流式就比较容易。其会返回异步迭代器Async Iterator直接使用 for await…of 循环来逐块获取数据即可。forawait(const chunk of res){console.log(chunk)}上面打印出的chunk示例如下{id:5a3ce01f-1353-47ed-b355-0337dc890ff6, // 对话id 多组流式对话时靠它拼接object:chat.completion.chunk,created:1784792183,model:deepseek-v4-flash,system_fingerprint:fp_8b330d02d0_prod0820_fp8_kvcache_20260402,choices:[{index:0,delta:{role:assistant,content:// 数据放在这里},logprobs:null,finish_reason:null}]}现在根据chunk内容list有值则拼接无值则添加对话项将id记录在项中用来寻找对应项。forawait(constchunkofres){callback(prevList{constchartIndexItemprevList.findIndex(item{returnitem.charIdchunk.id})if(chartIndexItem-1){return[...prevList,{...chunk.choices[0].delta,charId:chunk.id}]}else{returnprevList.map(item{if(item.charIdchunk.id){return{...item,content:item.contentchunk.choices[0].delta.content}}else{returnitem}})}})}如此就实现了流式效果。1.3.3 设置node中间层上面是在前端项目中直接请求的openai接口实际项目中需要使用node中间层做中转以保护key。中转层在操作时需要注意一下几点:1 发出请求时注意请求头的正确性{Content-Type:text/event-stream,Cache-Control:no-cache,Connection:keep-alive,}返回数据时使用res.write陆续返回。数据返回结束后使用res.end();结束接口。其他逻辑和前端项目中的内容等同都是通过openai获取chund后对数据进行处理。前端可以使用fetch读取流式数据axios不支持。fetch读取流式数据的方式上面有介绍。使用response.body.getReader().read()读取内容new TextDecoder().decode(value)进行解码。response.body.getReader().read()反复读取直到返回的done为true时break。这里也可以使用EventSource但是EventSource仅支持get接口不支持太长的上下文传递。const eventSourcenew EventSource(url);eventSource.addEventListener(message, function(e: any){content.valuee.data;});eventSource.addEventListener(end,(){eventSource.close();});个人更推荐仍然使用openai来在前端读取只是不写秘钥把url改成node中间层的地址。二 图像生成我们仍然选用国内场景大模型可灵ai来做示范。可灵ai需要比文本请求多做一件事通过jsonwebtoken包换取token。当然这一步在生产上肯定是后端做的这里我们就放在前端了。npm i jsonwebtoken安装依赖。2.1 发布任务可灵ai首页左侧有开发者平台按钮开发者平台右上角能进入控制台买个试用资源包然后创建key。和文本一样在header中写Authorization “Bearer XXX”其中 XXX 填写第一步获取的 API Key。现在页面中准备好相关的内容。divstyle{{margin:10px}}Imagewidth{200}srchttps://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png//divSpace verticalsizemediumSpace.Compactstyle{{width:100%}}InputdefaultValueCombine input and buttonvalue{pInput}onChange{(e)setPInput(e.target.value)}/ButtontypeprimaryonClick{()getImage(pInput)}图片生成/Button/Space.Compact/Space然后在getImage事件中根据pInput的值获取图片把图片url给image组件即可。api调用文档https://klingai.com/document-api/api/image/2-1/image-generationconst getImageasync(imageInput){const endPointhttps://api-beijing.klingai.com/v1/images/generationsletresfetch(endPoint,{headers:{Content-Type:application/json,Authorization:Bearer xxxx,}, method:POST, body: JSON.stringify({prompt: imageInput, aspect_ratio:1:1,})})if(res.status400){throw new Error(Non-200 response: ${await res.text()});}const resJsonawait res.json();constidresJson.data.task_id;const resultUrl${endpoint}/${id};console.log(id, resultUrl)// while(true){// 循环获取图片内容直到生成成功 // 返回task_status标志位为succeed即成功 // 成功后task_result中有生成图片的url //}}可灵ai是不支持跨域的所以咋package.json中配置proxy来进行跨域。在文本框中输入文字后点击图片生成id。909536646579253261/v1/images/generations/909536646579253261根据这个id就可以来获取图片内容了。2.2 获取图片现在将while中的内容补全。while(true){// console.log(resJson,id)// 循环获取图片内容直到生成成功// 返回task_status标志位为succeed即成功// 成功后task_result中有生成图片的urlawaitnewPromise((resolve)setTimeout(resolve,100));// 预防堵塞 让出主线程constresultawaitfetch(resultUrl,{headers:{Content-Type:application/json,Authorization:Bearer xxxx,}});constresultJsonawaitresult.json();console.log(resultJson)consttaskStatusresultJson.data.task_status;if(taskStatussucceed){console.log(resultJson.data?.task_result.images[0].url)setImageUrl(resultJson.data?.task_result.images[0].url)returnresultJson.data?.task_result.images[0].url}else{continue}}setImageUrl是这个方法的第二个参数用来赋值图片地址。现在点击生成图片页面上就出现了图片。三 AI应用智能体-------------------------------------------------------------------------------------------------------------未完待续 持续更新

相关新闻

政务云系统上了国产芯片之后,运维团队的真实体验

政务云系统上了国产芯片之后,运维团队的真实体验

政务云系统上了国产芯片之后,运维团队的真实体验 **摘要:**信创替代正在从“系统能跑起来”进入“系统要管得好”的新阶段。本文结合多地政务云信创迁移的公开实践,梳理国产化替代后运维团队面临的三个真实变化与应对思路。 某市政务云完成了…

2026/7/24 18:02:11阅读更多 →
2026年AI配音技术选型:从开源TTS到商业API,7款方案横向评测

2026年AI配音技术选型:从开源TTS到商业API,7款方案横向评测

给开源项目做演示视频、录制技术教程,或者为个人应用接入语音能力——配音往往是“最后一公里”的效率瓶颈。自录受环境、口音、返工成本制约;直接上开源TTS又面临推理耗时、参数盲调、部署成本等问题。过去半年,我陆续测试了十余款TTS方案&a…

2026/7/24 18:00:11阅读更多 →
从 0 到 1 速通 Gemini CLI:我整理的安装配置终极保姆教程来了

从 0 到 1 速通 Gemini CLI:我整理的安装配置终极保姆教程来了

Gemini CLI 安装并不难,真正容易卡住的是 API Key、中转地址和模型 ID。 这篇教程只走一条主线: 安装 Gemini CLI→ 获取 API Key→ 配置中转 API→ 启动验证→ 提交第一个任务 Windows、macOS 和 Linux 都可以参考。 PS:本文默认使用:gemin…

2026/7/24 18:00:11阅读更多 →
YuukiPS Launcher-PC:3个实用技巧快速掌握多游戏启动工具

YuukiPS Launcher-PC:3个实用技巧快速掌握多游戏启动工具

YuukiPS Launcher-PC:3个实用技巧快速掌握多游戏启动工具 【免费下载链接】Launcher-PC 项目地址: https://gitcode.com/gh_mirrors/la/Launcher-PC YuukiPS Launcher-PC是一款免费高效的多动漫游戏启动工具,采用C#开发,帮助玩家轻松…

2026/7/24 19:34:25阅读更多 →
什么是PR(Pull Request)专业指导手册 —— 新人开发者必读

什么是PR(Pull Request)专业指导手册 —— 新人开发者必读

一、什么是 Pull Request(PR)? Pull Request(拉取请求) 是 Git 协作开发流程中的核心机制,用于在将代码变更合并到目标分支(通常是 main 或 develop)之前,发起一次正式的…

2026/7/24 19:34:25阅读更多 →
Hermes Agent 自我进化:Curator 怎样清理、修复和迭代过期 Skills

Hermes Agent 自我进化:Curator 怎样清理、修复和迭代过期 Skills

Hermes Agent 自我进化:Curator 怎样清理、修复和迭代过期 Skills [!NOTE] 很多初学者把智能体当成“更会聊天的模型”,结果一上手就把文件、网络和高权限命令交出去。本篇围绕 Curator维护 建立一套可复现的实践路径:先明确任务边界,再确认工具与权限,最后用日志和结果验…

2026/7/24 19:34:25阅读更多 →
腾讯:自适应剪枝优化高并发推理

腾讯:自适应剪枝优化高并发推理

📖标题:D-cut: Adaptive Verification Depth Pruning for Batched Speculative Decoding 🌐来源:arXiv, 2607.14647v1 🛎️文章简介 🔸研究问题:在高并发场景下,长草稿的投机解码因验…

2026/7/24 19:34:25阅读更多 →
Agent技术现状与研究生发展指南

Agent技术现状与研究生发展指南

1. 研究生搞agent还有搞头吗?最近在实验室带本科生做项目时,有个研一的学弟跑来问我:"师兄,现在搞agent方向还有前途吗?我看网上有人说这个方向已经饱和了。"这个问题让我想起三年前自己刚读研时的迷茫。作为…

2026/7/24 19:34:25阅读更多 →
WarcraftHelper:让魔兽争霸3在现代电脑上突破165fps性能极限

WarcraftHelper:让魔兽争霸3在现代电脑上突破165fps性能极限

WarcraftHelper:让魔兽争霸3在现代电脑上突破165fps性能极限 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 你是否还在为魔兽争霸3那陈旧…

2026/7/24 19:32:25阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/24 0:58:53阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 0:58:53阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 0:58:53阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好,我是一名编程初学者,同时这也是我编程学习之路上的第一篇博客。在这里,我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手,目前在学习c语言,我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:06阅读更多 →
【LeetCode 54】螺旋矩阵

【LeetCode 54】螺旋矩阵

问题描述: 解法: 1、模拟(参考自【LeetCode 54】螺旋矩阵-CSDN博客) int *spiralOrder(int **matrix, int matrixSize, int *matrixColSize, int *returnSize) {static const int dirs[4][2] {{0, 1}, {1, 0}, {0, -1}, {-1, …

2026/7/24 0:00:06阅读更多 →
2026 WAIC:模型隐身、智能体疯野,厂商竞赛聚焦办公场景与商业闭环

2026 WAIC:模型隐身、智能体疯野,厂商竞赛聚焦办公场景与商业闭环

知春路不相信模型领先今年WAIC大会,昔日AI六小龙来了五家,分别是Kimi、阶跃星辰、Minimax、百川智能、零一万物。连放弃基模的百川和零一万物都来了,唯一缺席的竟是近几个月来风光无限的智谱。(DeepSeek一直不参加)WAI…

2026/7/24 0:00:06阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/23 22:58:43阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/24 19:00:40阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/24 19:00:40阅读更多 →