从零打通大模型:阿里云百炼 + FastAPI + Vue3 实现单轮与流式 AI 对话

发布时间:2026/8/4 5:48:12

从零打通大模型:阿里云百炼 + FastAPI + Vue3 实现单轮与流式 AI 对话
本文以一个「AI 求职助手」为例完整演示如何调用通义千问大模型从阿里云百炼开通与配置到 Python 直连验证再到 FastAPI 封装接口、接口测试、最后用 Vue3 Element Plus 前端对接实现「单轮对话」与「流式输出」两种模式。所有代码均来自真实可运行项目。目录一、整体架构与最终效果二、阿里云百炼配置DASHSCOPE_API_KEY三、Python 直接调用大模型3.1 单轮对话case1.py3.2 流式输出case2.py四、FastAPI 封装 HTTP 接口4.1 请求体 Schema4.2 路由单轮 SSE 流式4.3 在 main.py 注册路由五、接口测试curl / Postman / Swagger六、前端对接Vue3 Element Plus6.1 接口封装 llm.js6.2 Vite 代理配置6.3 豆包风格聊天面板组件6.4 页面与路由七、常见问题与踩坑八、总结一、整体架构与最终效果我们要做的是一个模仿「豆包」的 AI 对话页面包含两种模式模式传输方式后端接口体验单轮对话普通POST等待完整响应后一次性渲染POST /llm-day01/case1发问 → 等几秒 → 整段出现流式输出POST SSEtext/event-stream逐段推送POST /llm-day01/case2发问 → 文字逐字「打字机」式出现整体链路如下浏览器(Vue3) │ /api/llm-day01/case1 (axios, 单轮) │ /api/llm-day01/case2 (fetchSSE, 流式) ▼ Vite 代理 (/api → http://127.0.0.1:8000) ▼ FastAPI 后端 (case1_api.py) ▼ 阿里云百炼 DashScope (通义千问 qwen-plus, OpenAI 兼容)二、阿里云百炼配置DASHSCOPE_API_KEY本项目通过阿里云百炼原 DashScope提供的OpenAI 兼容接口调用通义千问底层库使用官方openaiSDK。2.1 开通与获取 API Key登录 阿里云百炼控制台。开通「模型服务」并进入API-KEY 管理点击「创建 API-KEY」。复制生成的 Key格式形如sk-xxxxxxxxxxxxxxxx。2.2 配置环境变量推荐强烈建议用环境变量不要硬编码 Key 到代码里。# Linux / macOS export DASHSCOPE_API_KEYsk-你的key ​ # Windows (PowerShell) $env:DASHSCOPE_API_KEYsk-你的key ​ # 或写入 .env 文件不要提交到 git echo DASHSCOPE_API_KEYsk-你的key .env代码中直接读取import os api_key os.getenv(DASHSCOPE_API_KEY)2.3 base_url 与模型OpenAI 兼容模式下百炼的base_url为https://dashscope.aliyuncs.com/compatible-mode/v1注本文项目代码中使用的是专属 MaaS endpointhttps://ws-xxxxx.cn-beijing.maas.aliyuncs.com/compatible-mode/v1功能等价可按你自己的专属地址替换。常用模型通过model参数指定qwen-plus通义千问 plus性价比高本项目使用qwen-max效果更强qwen-turbo速度最快、最便宜三、Python 直接调用大模型先不碰 Web 框架用纯 Python 验证大模型调用是否跑通。项目把这两段放在llm/目录下。3.1 单轮对话case1.py# llm/case1.py import os from openai import OpenAI ​ client OpenAI( api_keyos.getenv(DASHSCOPE_API_KEY), base_urlhttps://dashscope.aliyuncs.com/compatible-mode/v1, ) ​ completion client.chat.completions.create( modelqwen-plus, messages[ {role: system, content: You are a helpful assistant.}, {role: user, content: 人为什么要睡觉?}, ], temperature0.75, max_completion_tokens100, ) ​ print(completion.choices[0].message.content)运行pip install openai python llm/case1.py3.2 流式输出case2.py关键参数是streamTrue此时返回的是一个可迭代的生成器每收到一个 chunk 就 yield 一次。# llm/case2.py import os from openai import OpenAI ​ client OpenAI( api_keyos.getenv(DASHSCOPE_API_KEY), base_urlhttps://dashscope.aliyuncs.com/compatible-mode/v1, ) ​ completion client.chat.completions.create( modelqwen-plus, messages[ {role: system, content: You are a helpful assistant.}, {role: user, content: 请介绍一下自己}, ], streamTrue, stream_options{include_usage: True}, # 返回 token 用量 ) ​ content_parts [] print(AI: , end, flushTrue) ​ for chunk in completion: if chunk.choices: content chunk.choices[0].delta.content or print(content, end, flushTrue) content_parts.append(content) elif chunk.usage: print(\n--- 请求用量 ---) print(f输入 Tokens: {chunk.usage.prompt_tokens}) print(f输出 Tokens: {chunk.usage.completion_tokens}) print(f总计 Tokens: {chunk.usage.total_tokens}) ​ print(f\n--- 完整回复 ---\n{.join(content_parts)})流式模式下内容通过chunk.choices[0].delta.content逐段获取用它来实现「打字机」效果是标准做法。四、FastAPI 封装 HTTP 接口验证通了之后把调用逻辑封装成 Web 接口供前端调用。4.1 请求体 Schema使用 Pydantic 定义请求体只接收一个question字段# app/schemas/llm_case1.py from pydantic import BaseModel, Field ​ ​ class LLMCase1(BaseModel): question: str Field(..., title问题, description用户问题)4.2 路由单轮 SSE 流式# app/llm/case1_api.py import os from fastapi import APIRouter from openai import OpenAI from starlette.responses import StreamingResponse from app.schemas.llm_case1 import LLMCase1 BASE_URL https://dashscope.aliyuncs.com/compatible-mode/v1 router APIRouter(prefix/llm-day01, tags[LLM-DAY01]) # 单轮对话等待完整回复后返回 JSON router.post(/case1, summary单轮对话) async def case1_api(body: LLMCase1): client OpenAI( api_keyos.getenv(DASHSCOPE_API_KEY), base_urlBASE_URL, ) completion client.chat.completions.create( modelqwen-plus, messages[ {role: system, content: 你是一个智能助手}, {role: user, content: body.question}, ], temperature0.75, ) ai_reply completion.choices[0].message.content return { code: 1, message: 请求成功, data: {ai_reply: ai_reply}, } # 流式对话SSE 逐段推送 def stream_chunk(user_question: str): client OpenAI( api_keyos.environ[DASHSCOPE_API_KEY], base_urlBASE_URL, ) completion client.chat.completions.create( modelqwen-plus, messages[ {role: system, content: You are a helpful assistant.}, {role: user, content: user_question}, ], streamTrue, stream_options{include_usage: True}, ) for chunk in completion: if chunk.choices: delta chunk.choices[0].delta if delta.content: yield fdata: {delta.content}\n\n # SSE 格式data: 内容 两个换行 yield data: [done]\n\n # 自定义结束标志 router.post(/case2, summary流式对话(SSE)) async def case2_api(body: LLMCase1): return StreamingResponse( contentstream_chunk(body.question), media_typetext/event-stream, )SSE 格式要点每个事件以data: 内容\n\ndata: 内容 两个换行分隔结束用data: [done]\n\n。前端据此切分。4.3 在 main.py 注册路由# main.py节选 from app.llm.case1_api import llm_day01_router app.include_router(llm_day01_router) # 别忘了跨域方便前端本地联调 from starlette.middleware.cors import CORSMiddleware app.add_middleware( CORSMiddleware, allow_origins[*], allow_methods[*], allow_headers[*], allow_credentialsTrue, )启动后端pip install fastapi uvicorn uvicorn main:app --host 127.0.0.1 --port 8000 --reload五、接口测试curl / Postman / Swagger5.1 curl 测试单轮curl -X POST http://127.0.0.1:8000/llm-day01/case1 \ -H Content-Type: application/json \ -d {question:你好}返回{ code: 1, message: 请求成功, data: { ai_reply: 你好很高兴见到你 有什么可以帮你的吗 } }5.2 curl 测试流式curl -N -X POST http://127.0.0.1:8000/llm-day01/case2 \ -H Content-Type: application/json \ -d {question:介绍一下你自己}你会看到内容被逐行推出来最后一行是data: [done]。5.3 Swagger 在线文档FastAPI 自带交互式文档浏览器打开即可填参数直接测试http://127.0.0.1:8000/docs如果接口文档里测试通过、但前端报错问题几乎一定在前端超时 / 代理 / SSE 解析见第七节。六、前端对接Vue3 Element Plus前端是标准的 Vue3 Vite Element Plus 项目。核心难点是流式接口是 POST不能用浏览器的原生EventSource它只支持 GET因此要手写fetch ReadableStream解析 SSE。6.1 接口封装 llm.js// src/api/llm.js import request from /utils/request // 单轮对话 export function askOnce(question) { return request({ url: /llm-day01/case1, method: post, data: { question }, timeout: 120000, // 大模型单轮完整生成可能较慢务必放宽超时 }) } // 流式对话POST SSE不能用 EventSource export async function askStream(question, { onChunk, onDone, onError } {}) { try { const token localStorage.getItem(candidateToken) const resp await fetch(/api/llm-day01/case2, { method: POST, headers: { Content-Type: application/json, ...(token ? { Authorization: Bearer ${token} } : {}), }, body: JSON.stringify({ question }), }) if (!resp.ok || !resp.body) { const text await resp.text().catch(() ) throw new Error(text || 请求失败状态码 ${resp.status}) } const reader resp.body.getReader() const decoder new TextDecoder(utf-8) let buffer while (true) { const { done, value } await reader.read() if (done) break buffer decoder.decode(value, { stream: true }) // SSE 以空行(\n\n)分隔事件 let sep while ((sep buffer.indexOf(\n\n)) ! -1) { const event buffer.slice(0, sep) buffer buffer.slice(sep 2) const dataLine event .split(\n) .find((line) line.startsWith(data:)) if (!dataLine) continue const data dataLine.slice(5).trim() if (data [DONE] || data [done]) { onDone onDone() return } onChunk onChunk(data) } } onDone onDone() } catch (err) { console.error([askStream] 流式请求异常:, err) onError onError(err) } }6.2 Vite 代理配置把/api代理到后端 8000并去掉/api前缀// vite.config.js export default defineConfig({ server: { port: 3003, proxy: { /api: { target: http://127.0.0.1:8000, changeOrigin: true, rewrite: (path) path.replace(/^\/api/, ), }, }, }, })这样前端访问/api/llm-day01/case1实际打到http://127.0.0.1:8000/llm-day01/case1跨域问题交给代理解决。6.3 豆包风格聊天面板组件核心是一个可复用组件AiChatPanel.vue通过mode区分单轮 / 流式!-- src/components/ai/AiChatPanel.vue核心逻辑节选 -- script setup import { ref, reactive } from vue import { askOnce, askStream } from /api/llm const props defineProps({ mode: { type: String, default: single } }) const messages ref([]) const inputText ref() const loading ref(false) const sendSingle async (question) { loading.value true const aiMsg reactive({ role: ai, content: , streaming: true }) messages.value.push(aiMsg) try { const res await askOnce(question) aiMsg.content res?.data?.ai_reply || 暂无回复 } catch (e) { console.error([sendSingle] 单轮请求失败:, e) aiMsg.content 请求失败请稍后重试。 } finally { aiMsg.streaming false loading.value false } } const sendStream (question) { loading.value true const aiMsg reactive({ role: ai, content: , streaming: true }) messages.value.push(aiMsg) askStream(question, { onChunk: (chunk) { aiMsg.content chunk }, // 逐字追加 onDone: () { aiMsg.streaming false; loading.value false }, onError: (err) { aiMsg.streaming false aiMsg.content aiMsg.content || 请求失败请稍后重试。 loading.value false }, }) } /script6.4 页面与路由两个页面分别复用面板再注册路由// router/index.js import AiSingleChat from /pages/ai/AiSingleChat.vue import AiStreamChat from /pages/ai/AiStreamChat.vue // 在 /candidate 子路由 children 中增加 { path: ai-single, name: AiSingleChat, component: AiSingleChat }, { path: ai-stream, name: AiStreamChat, component: AiStreamChat },!-- src/pages/ai/AiSingleChat.vue -- template AiChatPanel modesingle / /template script setup import AiChatPanel from /components/ai/AiChatPanel.vue /script !-- src/pages/ai/AiStreamChat.vue -- template AiChatPanel modestream / /template script setup import AiChatPanel from /components/ai/AiChatPanel.vue /script启动前端npm install npm run dev # 默认 http://127.0.0.1:3003七、常见问题与踩坑❌ 坑 1单轮对话「请求超时」axios 默认timeout: 1500015 秒。大模型在并发高或首字延迟大时单轮完整响应很容易超过 15 秒触发超时。解决在askOnce中单独设置timeout: 1200002 分钟见 6.1。流式模式不会超时因为首字节很快返回连接一直「活跃」。这也解释了为什么「流式正常、单轮超时」。❌ 坑 2流式接口是 POSTEventSource 用不了new EventSource(url)只能发 GET。我们的流式接口是POST /llm-day01/case2必须带 body。解决用fetchresponse.body.getReader()手动读取流按\n\n切分 SSE 事件见 6.1 的askStream。❌ 坑 3SSE 结束标志要自己约定标准 SSE 用data: [DONE]结束。本项目后端约定data: [done]小写。前端解析时两者都兼容即可。❌ 坑 4跨域 / 代理本地开发若前端直接请求http://127.0.0.1:8000会触发 CORS。统一走 Vite 的/api代理见 6.2即可无需在前端写完整域名。❌ 坑 5本地联调 405用浏览器或 curl 以GET方式访问/llm-day01/case1会返回405 Method Not Allowed——这是正常的因为接口只接受 POST。测试请用curl -X POST或 Swagger。八、总结本文从配置到落地打通了「阿里云百炼 → FastAPI → Vue3」的完整链路配置在百炼控制台拿到DASHSCOPE_API_KEY用环境变量注入base_url 走 OpenAI 兼容模式。Python 直连streamTrue实现流式delta.content取片段。FastAPI 封装单轮返回 JSON流式用StreamingResponse SSEdata: 片段/data: [done]。测试curl、Postman、Swagger/docs三件套验证接口。前端 axios 单轮注意超时fetch ReadableStream解析 POST 流式Vite 代理解决跨域。踩坑超时、EventSource 不支持 POST、SSE 结束标志、代理与 405。照着这套你也能快速给自己的系统加上一个「会打字」的 AI 助手。环境依赖# 后端 pip install fastapi uvicorn openai ​ # 前端 npm install axios element-plus完整项目结构节选fastApiProject4/ ├── llm/ │ ├── case1.py # Python 单轮直连示例 │ └── case2.py # Python 流式直连示例 ├── app/ │ ├── llm/case1_api.py # FastAPI 单轮 SSE 流式接口 │ ├── schemas/llm_case1.py │ └── main.py # 注册路由 CORS └── main.py ​ new_boss_vue-main/boss-candidate-ui/ ├── src/api/llm.js # 接口封装单轮 流式 ├── src/components/ai/AiChatPanel.vue ├── src/pages/ai/AiSingleChat.vue ├── src/pages/ai/AiStreamChat.vue ├── src/router/index.js └── vite.config.js # /api 代理到 8000

相关新闻

【需求分析】基于 GPT-5.6 + Codex 开发个人工具箱 Personal Toolbox 项目

【需求分析】基于 GPT-5.6 + Codex 开发个人工具箱 Personal Toolbox 项目

2026/8/4 5:38:12

其实是第二个 AI 项目。但前一个项目因没有经验,搞得太乱,现在被卡在一半不想继续。 新的项目从需求分析开始,每一次功能更新/完成都会复盘一下。 本次想法是给自己开发一个多功能工具箱,GitHub仓库。 1 前言 在日常使用 AI、浏览…

PCB全检质量控制:猎板工程师的出货标准

PCB全检质量控制:猎板工程师的出货标准

2026/8/4 5:38:12

不知你是否有过这样的经历, 就是收到了一块线路整齐, 焊点光亮, 堪称完美的PCB? 殊不知在你视线外难以留意的情形下, 有一套全检质量控制体系, 正悄无声息地对每一块板的品质起着守护作用。 身为猎板那儿的一名工程师, 我每日打交道的皆是这个问题, 即怎样保证每一块PCB都能够…

AI智能拦截告警风暴:EFK+K8s+OpenAI实战

AI智能拦截告警风暴:EFK+K8s+OpenAI实战

2026/8/4 5:38:12

1. 项目概述:当AI遇上告警风暴去年我们团队接手了一个日均告警量超过5000条的EFK(ElasticsearchFluentdKibana)监控系统,运维人员每天要花3小时处理告警邮件。直到某天凌晨2点,一条"K8s节点内存使用率95%"的…

基于BiLSTM-Attention的轴承剩余寿命预测:MATLAB实践指南

基于BiLSTM-Attention的轴承剩余寿命预测:MATLAB实践指南

2026/8/4 9:38:33

在实际工业预测性维护场景中,轴承作为旋转机械的核心部件,其剩余使用寿命(RUL)的准确预测是避免非计划停机、降低维护成本的关键。传统的基于物理模型或简单统计的方法往往难以捕捉复杂工况下轴承性能退化的非线性动态特征。近年来…

决策树与决策森林新手实战指南

决策树与决策森林新手实战指南

2026/8/4 9:38:33

在处理分类或回归问题时,我们常常面临一个两难选择:是追求模型的简单可解释性,还是牺牲一部分透明度来换取更高的预测精度?传统的线性模型虽然直观,但在面对非线性关系复杂的数据时往往力不从心;而深度神经…

3个为什么选择Seraphine的理由:告别手动查询的智能游戏助手

3个为什么选择Seraphine的理由:告别手动查询的智能游戏助手

2026/8/4 9:38:33

3个为什么选择Seraphine的理由:告别手动查询的智能游戏助手 【免费下载链接】Seraphine 英雄联盟战绩查询工具 项目地址: https://gitcode.com/gh_mirrors/se/Seraphine 你是否曾经在英雄联盟游戏中,因为无法快速了解队友和对手的实力而错失BP优势…

基于SpringBoot的高校班费管理系统设计与实现

基于SpringBoot的高校班费管理系统设计与实现

2026/8/4 9:38:33

1. 项目概述 高校班级财务管理一直是学生自治工作中的痛点。传统纸质记账本容易丢失、Excel表格难以共享、微信群接龙统计混乱...这些问题在班费管理场景中屡见不鲜。我开发的这套基于SpringBoot的班费管理系统,正是为了解决这些实际问题而生。 这个系统本质上是一…

SpringBoot与微信小程序构建智慧校园选课系统

SpringBoot与微信小程序构建智慧校园选课系统

2026/8/4 9:38:33

1. 项目概述:基于SpringBoot与微信小程序的智慧校园选课系统 这个项目本质上是一个打通校园教务系统与学生移动端的桥梁。我们团队用SpringBoot构建后端服务,配合微信小程序前端,实现了学生随时随地进行课程查询、选课、退课等操作。相比传统…

Docker部署OpenClaw:AI智能体框架环境配置与容器化实践

Docker部署OpenClaw:AI智能体框架环境配置与容器化实践

2026/8/4 9:28:33

1. 项目概述:为什么选择 Docker 部署 OpenClaw?最近在折腾一些 AI 工具链的本地化部署,OpenClaw 这个名字出现的频率越来越高。它不是一个单一的模型,而是一个集成了多种 AI 能力的开源智能体框架,你可以把它理解为一个…

ncmdumpGUI:一键解锁网易云音乐ncm文件的终极解决方案

ncmdumpGUI:一键解锁网易云音乐ncm文件的终极解决方案

2026/8/3 4:49:52

ncmdumpGUI:一键解锁网易云音乐ncm文件的终极解决方案 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾经从网易云音乐下载了心爱的歌曲&am…

分布式配置中心选型实战:Nacos与Consul在创业场景下的对比

分布式配置中心选型实战:Nacos与Consul在创业场景下的对比

2026/8/3 19:24:18

分布式配置中心选型实战:Nacos与Consul在创业场景下的对比工程导读:本文深入讨论 分布式配置中心选型实战:Nacos与Consul在创业场景下的对比 在生产工程实践中的核心落地方案。基于 分布式架构与微服务设计 视角,剖析实际痛点、架…

MoneyPrinterPlus实战指南:AI视频批量生成与自动化发布完整解决方案

MoneyPrinterPlus实战指南:AI视频批量生成与自动化发布完整解决方案

2026/8/3 20:38:37

MoneyPrinterPlus实战指南:AI视频批量生成与自动化发布完整解决方案 【免费下载链接】MoneyPrinterPlus AI一键批量生成各类短视频,自动批量混剪短视频,自动把视频发布到抖音,快手,小红书,视频号上,赚钱从来没有这么容易过! 支持本地语音模型chatTTS,fasterwhisper,…

3步解决Windows DLL缺失问题:VisualCppRedist AIO终极运行库修复方案

3步解决Windows DLL缺失问题:VisualCppRedist AIO终极运行库修复方案

2026/8/4 0:07:58

3步解决Windows DLL缺失问题:VisualCppRedist AIO终极运行库修复方案 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经在打开游戏或软件时遇…

SingleFile终极指南:一键保存完整网页的5大核心功能

SingleFile终极指南:一键保存完整网页的5大核心功能

2026/8/4 0:07:58

SingleFile终极指南:一键保存完整网页的5大核心功能 【免费下载链接】SingleFile Web Extension for saving a faithful copy of a complete web page in a single HTML file 项目地址: https://gitcode.com/gh_mirrors/si/SingleFile 你是否曾经遇到过这样的…

国家中小学智慧教育平台电子课本下载终极方案:三步免费获取PDF教材

国家中小学智慧教育平台电子课本下载终极方案:三步免费获取PDF教材

2026/8/4 0:07:58

国家中小学智慧教育平台电子课本下载终极方案:三步免费获取PDF教材 【免费下载链接】tchMaterial-parser 国家中小学智慧教育平台 电子课本下载工具,帮助您从智慧教育平台中获取电子课本的 PDF 文件网址并进行下载,让您更方便地获取课本内容。…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/2 17:06:42

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/3 7:25:44

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/3 2:41:27

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…