导语:别让「第一步」,拦住你的AI开发之路

我见过很多想入行AI大模型后端开发的新手,刷完了整套Python和FastAPI教程,甚至背完了RAG和Agent的核心原理,却始终迈不出最关键的一步:
写出第一个属于自己的、能正常运行的、可以被前端调用的大模型后端接口

要么是跟着视频敲完代码,一运行就报错,环境问题、依赖问题、网络问题,卡了3天直接放弃;
要么是只会调官方的SDK Demo,不知道怎么封装成标准的HTTP接口,不知道怎么给前端用;
要么是怕自己零基础、非科班,连代码都看不懂,觉得自己肯定学不会。

今天这篇文章,就是来解决所有新手的痛点的。我承诺:只要你会用电脑、能看懂中文,跟着这篇文章一步步走,30分钟,从零开始,写出第一个完整可运行的大模型后端接口,实现和ChatGPT一模一样的对话能力,包括基础同步对话和流式打字机效果。

全文所有代码都可以直接复制运行,所有新手会踩的坑,我都提前给你踩过了,配套了完整的报错解决方案,零门槛、零前置知识,跟着就能跑通。


一、先给新手吃定心丸:你的前置条件,几乎为零

很多新手还没开始就自我劝退:「我不会Python、我没学过后端、我不懂大模型原理,能学会吗?」
答案是:完全可以。这篇教程的所有内容,都不需要你有任何编程基础、后端知识、大模型算法功底,我会把每一个步骤、每一行代码都讲得明明白白。

1.1 你需要准备的唯一东西

  1. 一台能正常上网的电脑(Windows/Mac/Linux都可以,无配置要求)
  2. 一个手机号(用来申请大模型API密钥,免费)

1.2 为什么我们选FastAPI,而不是其他框架?

新手入门,选对工具,就成功了一半。我们全程用Python+FastAPI开发,原因非常简单:

  • 零门槛友好:Python语法接近大白话,比Java、Go更容易上手,零基础也能看懂;
  • 开发效率拉满:10行代码就能写出一个完整的接口,比Spring Boot、Flask少写80%的模板代码;
  • 原生适配AI场景:天生支持异步编程,完美适配大模型API的IO密集型场景,流式输出(打字机效果)实现成本极低;
  • 自动生成接口文档:写完代码自动生成可视化的交互式接口文档,不用装Postman,浏览器里就能直接测试接口,对新手极度友好。

1.3 为什么选国产大模型,而不是OpenAI?

这是新手最容易踩的第一个坑:很多教程一上来就用OpenAI API,结果新手没有翻墙工具,连接口都调不通,直接卡在第一步。
我们全程用字节跳动豆包大模型API,核心优势:

  1. 国内直连,无网络障碍:不需要任何翻墙工具,网络稳定,不会出现超时、连不上的问题;
  2. 免费额度充足:新用户注册就送大量免费token额度,个人开发测试完全够用,一分钱不用花;
  3. 完全兼容OpenAI格式:后面你想切换成OpenAI、通义千问、文心一言,只需要改2行代码,零成本切换;
  4. 大厂稳定保障:接口响应速度快,可用性99.9%,个人测试和生产环境都能用。

二、5分钟搞定前置准备:API密钥申请+环境搭建

2.1 3分钟申请大模型API密钥

这是我们唯一需要提前准备的「通行证」,步骤极其简单,跟着点就行:

  1. 打开【火山引擎官网】(https://www.volcengine.com/),用手机号注册并登录;
  2. 顶部搜索框搜索「豆包大模型」,进入产品页面,点击「立即使用」,免费开通服务;
  3. 进入控制台后,左侧菜单栏找到「API密钥管理」,点击「新建密钥」,创建一个专属的API密钥;
  4. 复制生成的SK(Secret Access Key),保存到记事本里,后面代码里必须用到,绝对不要泄露给任何人,更不要上传到公开的GitHub仓库!

2.2 2分钟搭建基础开发环境

我们只需要装2个软件,都是免费的,一键安装:

  1. Python 3.10+
    • 打开Python官网(https://www.python.org/downloads/),下载对应系统的最新版本(3.10及以上都可以);
    • 安装的时候,一定要勾选最下方的「Add python.exe to PATH」,这是新手最容易踩的坑,不勾选后面会无法运行Python命令;
    • 安装完成后,打开终端(Windows用PowerShell,Mac用终端),输入python --versionpip --version,能输出版本号,就说明安装成功了。
  2. VS Code
    • 打开VS Code官网(https://code.visualstudio.com/),下载对应系统的版本,一键安装即可;
    • 安装完成后,打开VS Code,在左侧扩展商店里搜索「Python」,安装微软官方的Python插件,方便我们写代码和调试。

三、10分钟完成项目初始化+依赖安装

3.1 创建项目文件夹

  1. 在电脑上新建一个文件夹,命名为llm-api-demo,名字可以随便起,不要带中文和空格;
  2. 打开VS Code,点击左上角「文件」→「打开文件夹」,选中刚才新建的llm-api-demo文件夹,打开。

3.2 创建并激活Python虚拟环境

很多新手会问:为什么要创建虚拟环境?直接装在全局不行吗?

大白话解释:虚拟环境就是给你的项目单独建了一个「独立的Python小房间」,你装的所有依赖包,都只在这个房间里生效,不会影响全局的Python环境,也不会和其他项目的依赖包版本冲突,这是Python开发的标准规范,新手从一开始就要养成好习惯。

操作步骤:

  1. 在VS Code里,按下快捷键Ctrl+(Windows)/Command+(Mac),打开终端,终端会自动定位到我们的项目文件夹;
  2. 在终端里输入下面的命令,创建虚拟环境,回车执行:
    python -m venv venv
    
    执行完成后,项目文件夹里会多出一个venv文件夹,就说明创建成功了。
  3. 激活虚拟环境,这一步非常关键,每次打开项目都要先激活虚拟环境
    • Windows系统(PowerShell):
      .\venv\Scripts\Activate.ps1
      
    • Mac/Linux系统:
      source venv/bin/activate
      
    激活成功后,你的终端前面会出现(venv)的标识,就说明已经进入虚拟环境了。
新手常见报错解决方案

如果Windows系统报错「无法加载文件,因为在此系统上禁止运行脚本」,解决方法:

  1. 用管理员身份打开PowerShell;
  2. 输入命令:Set-ExecutionPolicy RemoteSigned,按回车,输入Y确认;
  3. 关闭PowerShell,重新打开VS Code的终端,再执行激活命令,就可以了。

3.3 安装必须的依赖包

在激活了虚拟环境的终端里,输入下面的命令,一键安装所有需要的依赖包,回车执行:

pip install fastapi uvicorn httpx pydantic sse-starlette python-dotenv

每个包的作用,给新手讲明白,不用死记硬背,知道是干嘛的就行:

包名 核心作用
fastapi 我们用的Web框架,核心,用来写后端接口
uvicorn ASGI服务器,用来运行我们写的FastAPI服务
httpx 异步HTTP客户端,用来调用大模型API,比requests更适配异步场景
pydantic 数据校验工具,FastAPI原生支持,自动校验前端传的参数,自动生成接口文档
sse-starlette 流式输出必备工具,实现ChatGPT同款打字机效果
python-dotenv 环境变量管理工具,用来安全存放API密钥,避免硬编码泄露

安装完成后,终端没有报错,就说明我们的环境已经100%准备好了,接下来就可以写代码了。


四、10分钟从零写完整代码,逐行解析,复制就能跑

我们分两步走:先写一个最小Demo,验证环境没问题,拿到第一个成就感;再写完整的大模型接口,逐行解析,新手能完全看懂。

4.1 先跑通最小Demo,拿到第一个成就感

在项目文件夹里,新建一个文件,命名为main.py(必须是.py后缀,不能是.txt),写入下面的代码:

# 1. 导入FastAPI框架
from fastapi import FastAPI

# 2. 初始化FastAPI应用
# title和version会显示在自动生成的接口文档里
app = FastAPI(title="我的第一个大模型后端接口", version="1.0")

# 3. 写一个最简单的接口,用来测试服务是否正常
@app.get("/", summary="Hello World测试接口")
def hello_world():
    return {
        "code": 0,
        "message": "恭喜你!你的第一个FastAPI接口跑通了!",
        "data": "Hello AI World!"
    }

写完之后,在终端里输入启动服务的命令,回车执行:

uvicorn main:app --reload

看到终端里输出Uvicorn running on http://127.0.0.1:8000,就说明服务启动成功了!

我们来验证一下:

  1. 打开浏览器,输入http://127.0.0.1:8000,就能看到我们接口返回的JSON数据,说明服务完全正常;
  2. 打开http://127.0.0.1:8000/docs,就能看到FastAPI自动给我们生成的可视化交互式接口文档,点击「Try it out」→「Execute」,就能直接测试接口,不用装任何额外的工具,对新手极度友好。

到这里,你已经完成了最关键的一步:写出了第一个能正常运行的后端接口,已经超过了80%只看不做的新手。

4.2 完整的大模型后端接口代码,逐行解析

接下来,我们把完整的大模型接口代码,写入main.py文件里,直接替换掉之前的Demo代码即可,所有代码都有详细注释,新手能看懂每一行的作用。

完整代码(直接复制就能用)
# ------------------------------
# 1. 导入所有需要的依赖包
# ------------------------------
# FastAPI核心框架
from fastapi import FastAPI, HTTPException
# 跨域配置,解决前端调用接口的跨域问题
from fastapi.middleware.cors import CORSMiddleware
# 数据模型定义,用来做请求参数校验
from pydantic import BaseModel
# 异步HTTP客户端,用来调用大模型API
import httpx
# 流式输出SSE协议支持
from sse_starlette.sse import EventSourceResponse
# 环境变量管理,安全存放API密钥
from dotenv import load_dotenv
import os
import asyncio
import json

# ------------------------------
# 2. 基础配置,新手只需要在这里填你的API密钥
# ------------------------------
# 加载.env文件里的环境变量
load_dotenv()
# 你的豆包API密钥,从火山引擎控制台复制过来
# 生产环境绝对不要硬编码,我们用.env文件管理,后面会讲
DOUBAO_API_KEY = os.getenv("DOUBAO_API_KEY", "这里填你复制的API密钥")
# 豆包API请求地址,固定不变
DOUBAO_API_URL = "https://ark.cn-beijing.volces.com/api/v3/chat/completions"
# 默认使用的模型,这里用豆包4.0极速版,免费额度可用,响应速度快
DEFAULT_MODEL = "ep-20240801******" # 替换为你自己的模型endpoint ID

# ------------------------------
# 3. 初始化FastAPI应用
# ------------------------------
app = FastAPI(
    title="我的第一个大模型后端接口",
    description="零基础入门大模型后端开发,完整实现同步对话+流式对话",
    version="1.0"
)

# ------------------------------
# 4. 配置CORS跨域中间件,新手必加!
# ------------------------------
# 大白话解释:前端的地址和后端的地址不一样,浏览器会默认拦截请求,加了这个配置,前端就能正常调用接口了
app.add_middleware(
    CORSMiddleware,
    # 允许所有前端地址访问,生产环境可以改成你的前端域名,比如["https://your-frontend.com"]
    allow_origins=["*"],
    # 允许所有请求方法,GET/POST/PUT/DELETE等
    allow_methods=["*"],
    # 允许所有请求头
    allow_headers=["*"],
    # 允许携带凭证
    allow_credentials=True
)

# ------------------------------
# 5. 定义全局异步HTTP客户端
# ------------------------------
# 复用HTTP连接,提升性能,避免每次调用都新建连接
# 服务启动时创建,服务关闭时自动释放
async_client = httpx.AsyncClient(
    # 超时时间设置,大模型响应可能需要几秒,设置30秒足够
    timeout=httpx.Timeout(30.0, connect=5.0)
)

# 服务关闭时,自动关闭HTTP客户端,释放资源
@app.on_event("shutdown")
async def shutdown_event():
    await async_client.aclose()

# ------------------------------
# 6. 定义请求和响应的数据模型
# ------------------------------
# 大白话解释:定义前端传给我们的参数格式,FastAPI会自动校验,参数不对直接返回清晰的错误
# 对话消息模型,单条消息的格式
class ChatMessage(BaseModel):
    # 角色,只能是user(用户)、assistant(AI助手)、system(系统提示词)
    role: str
    # 消息内容
    content: str

# 对话请求体,前端传给我们的完整参数
class ChatRequest(BaseModel):
    # 对话消息列表,比如[{"role": "user", "content": "你好"}]
    messages: list[ChatMessage]
    # 模型,可选,不传就用默认模型
    model: str | None = None
    # 温度值,可选,0-2之间,越高越随机,越低越严谨,默认0.7
    temperature: float | None = 0.7
    # 是否流式输出,默认False
    stream: bool | None = False

# ------------------------------
# 7. 健康检查接口,用来测试服务是否正常
# ------------------------------
@app.get("/health", summary="健康检查接口")
async def health_check():
    return {
        "code": 0,
        "message": "服务运行正常",
        "data": {
            "status": "running",
            "version": "1.0"
        }
    }

# ------------------------------
# 8. 核心接口1:同步对话接口(非流式,一次性返回完整结果)
# ------------------------------
@app.post("/api/chat", summary="同步对话接口,一次性返回完整结果")
async def chat(chat_request: ChatRequest):
    """
    基础对话接口,前端传入对话消息,一次性返回AI的完整回答
    """
    # 1. 构建请求大模型的请求头
    headers = {
        "Authorization": f"Bearer {DOUBAO_API_KEY}",
        "Content-Type": "application/json"
    }

    # 2. 构建请求大模型的请求体
    request_body = {
        "model": chat_request.model or DEFAULT_MODEL,
        "messages": [msg.model_dump() for msg in chat_request.messages],
        "temperature": chat_request.temperature,
        "stream": False
    }

    try:
        # 3. 异步调用大模型API
        response = await async_client.post(
            DOUBAO_API_URL,
            headers=headers,
            json=request_body
        )

        # 4. 处理异常情况:接口返回非200状态码
        response.raise_for_status()

        # 5. 解析大模型返回的结果
        result = response.json()
        ai_reply = result["choices"][0]["message"]["content"]
        total_tokens = result["usage"]["total_tokens"]

        # 6. 给前端返回标准化的结果
        return {
            "code": 0,
            "message": "success",
            "data": {
                "reply": ai_reply,
                "model": request_body["model"],
                "total_tokens": total_tokens
            }
        }

    # 7. 异常处理,给前端返回清晰的错误信息,新手能快速定位问题
    except httpx.TimeoutException:
        raise HTTPException(status_code=504, detail="大模型API请求超时,请稍后重试")
    except httpx.HTTPStatusError as e:
        if e.response.status_code == 401:
            raise HTTPException(status_code=401, detail="API密钥错误,请检查你的密钥是否正确")
        elif e.response.status_code == 403:
            raise HTTPException(status_code=403, detail="API权限不足,请检查是否开通了模型服务")
        else:
            raise HTTPException(status_code=500, detail=f"大模型API调用失败:{e.response.text}")
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"服务内部错误:{str(e)}")

# ------------------------------
# 9. 核心接口2:流式对话接口(打字机效果,逐字返回)
# ------------------------------
@app.post("/api/chat/stream", summary="流式对话接口,实现ChatGPT同款打字机效果")
async def chat_stream(chat_request: ChatRequest):
    """
    流式对话接口,实现打字机效果,AI生成一个字就返回一个字,体验更好
    """
    # 1. 构建请求头和请求体
    headers = {
        "Authorization": f"Bearer {DOUBAO_API_KEY}",
        "Content-Type": "application/json"
    }
    request_body = {
        "model": chat_request.model or DEFAULT_MODEL,
        "messages": [msg.model_dump() for msg in chat_request.messages],
        "temperature": chat_request.temperature,
        "stream": True  # 开启流式输出
    }

    # 2. 定义流式生成器,逐字返回AI生成的内容
    async def event_generator():
        try:
            # 异步流式调用大模型API
            async with async_client.stream(
                "POST",
                DOUBAO_API_URL,
                headers=headers,
                json=request_body
            ) as response:
                # 处理异常状态码
                response.raise_for_status()

                # 逐行读取大模型返回的流式数据
                async for line in response.aiter_lines():
                    # 过滤空行和非数据行
                    line = line.strip()
                    if not line or not line.startswith("data: "):
                        await asyncio.sleep(0.01)
                        continue

                    # 解析SSE数据,去掉"data: "前缀
                    data = line[6:]
                    # 流式结束标识,大模型返回[DONE]就说明生成完成了
                    if data == "[DONE]":
                        yield {
                            "event": "done",
                            "data": "[DONE]"
                        }
                        return

                    # 解析JSON数据,提取逐字生成的内容
                    try:
                        json_data = json.loads(data)
                        delta_content = json_data["choices"][0]["delta"].get("content", "")
                        # 如果有内容,就通过SSE事件返回给前端
                        if delta_content:
                            yield {
                                "event": "message",
                                "data": delta_content
                            }
                    except json.JSONDecodeError:
                        continue
                    except Exception:
                        continue

        # 异常处理,通过SSE事件返回错误信息
        except httpx.TimeoutException:
            yield {
                "event": "error",
                "data": json.dumps({"code": 504, "message": "请求超时,请稍后重试"})
            }
        except Exception as e:
            yield {
                "event": "error",
                "data": json.dumps({"code": 500, "message": f"服务异常:{str(e)}"})
            }

    # 3. 返回SSE流式响应
    return EventSourceResponse(
        event_generator(),
        media_type="text/event-stream",
        ping=2000  # 2秒一次心跳,防止连接被网关断开
    )
新手需要修改的2个地方
  1. DOUBAO_API_KEY的值,替换成你从火山引擎控制台复制的API密钥;
  2. DEFAULT_MODEL的值,替换成你在火山引擎创建的模型endpoint ID(在豆包大模型控制台的「推理接入点」里能找到)。

4.3 密钥安全优化:绝对不要硬编码密钥!

新手最容易犯的致命错误:把API密钥硬编码在代码里,不小心上传到GitHub,被爬虫爬走,被盗刷几十万。
我们用.env文件来管理密钥,绝对安全,步骤如下:

  1. 在项目文件夹里,新建一个文件,命名为.env(注意前面有个点,没有后缀名);
  2. .env文件里写入下面的内容:
    # 你的豆包API密钥
    DOUBAO_API_KEY=这里填你复制的API密钥
    # 你的模型endpoint ID
    DEFAULT_MODEL=这里填你的模型endpoint ID
    
  3. main.py里的硬编码密钥删掉,改成从环境变量读取,代码已经写好了,不用改;
  4. 新建一个.gitignore文件,写入下面的内容,避免把密钥和虚拟环境上传到Git仓库:
    # 环境变量文件,绝对不能上传
    .env
    # 虚拟环境文件夹
    venv/
    # Python缓存文件
    __pycache__/
    # 日志文件
    *.log
    

到这里,我们的完整代码就写完了,接下来就可以启动服务,测试接口了。


五、5分钟运行服务+接口测试,零额外工具

5.1 启动服务

在激活了虚拟环境的终端里,输入启动命令,回车执行:

uvicorn main:app --reload

看到终端输出Uvicorn running on http://127.0.0.1:8000,没有报错,就说明服务启动成功了!

5.2 用自动生成的接口文档测试接口

FastAPI最友好的地方,就是自动生成了可视化的交互式接口文档,我们不用装任何工具,浏览器里就能直接测试。

  1. 打开浏览器,输入http://127.0.0.1:8000/docs,进入接口文档页面;
  2. 找到/api/chat同步对话接口,点击右上角的「Try it out」,进入测试模式;
  3. 下面的请求体里,已经自动生成了模板,我们只需要修改messages里的内容,比如:
    {
      "messages": [
        {
          "role": "user",
          "content": "你好,给我讲一个程序员的冷笑话"
        }
      ],
      "temperature": 0.7,
      "stream": false
    }
    
  4. 点击「Execute」,就能看到接口返回的结果,AI的回答会显示在响应体里,说明我们的接口完全跑通了!
  5. 同样的方法,你可以测试/api/chat/stream流式接口,实现打字机效果。

恭喜你!到这里,你已经从零写出了第一个完整的大模型后端接口,实现了和ChatGPT一模一样的对话能力,30分钟的承诺,你已经完成了!


六、新手90%会遇到的报错,全给你解决方案

我把新手最容易遇到的所有报错,都整理好了,遇到问题直接查,就能解决,不用到处搜:

常见报错 核心原因 解决方案
无法将“uvicorn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称 没激活虚拟环境,或者没装uvicorn 1. 重新激活虚拟环境,确保终端前面有(venv)标识;2. 执行pip install uvicorn重新安装
调用接口返回401 Unauthorized API密钥错误,或者没填对 1. 检查密钥是否和控制台的一致;2. 检查密钥前面有没有多余的空格;3. 确认密钥已经开通了豆包大模型的权限
调用接口返回403 Forbidden 模型endpoint ID错误,或者没开通对应模型的服务 1. 检查endpoint ID是否正确;2. 去控制台确认模型服务已经开通,有可用额度
调用接口超时 网络问题,或者API地址填错了 1. 检查API地址是否正确;2. 确认你的网络能正常访问火山引擎,不用翻墙;3. 把超时时间调长一点
前端调用接口报CORS跨域错误 没配置CORS跨域中间件,或者配置不对 1. 确认代码里加了CORSMiddleware;2. allow_origins改成[“*”],允许所有地址访问;3. 重启服务
流式接口没反应 没装sse-starlette,或者前端没按SSE协议处理 1. 执行pip install sse-starlette安装依赖;2. 重启服务;3. 用接口文档测试,确认后端能正常返回
启动服务报错“Address already in use” 8000端口被占用了 1. 关掉其他占用8000端口的程序;2. 启动命令加–port参数,换个端口,比如uvicorn main:app --reload --port 8001

七、进阶优化:从Demo到生产环境,你需要做的事

我们现在写的接口,已经能正常运行,但是要放到生产环境给用户用,还需要做一些优化,给新手一个进阶的方向:

  1. 完善用户管控与接口限流:给每个用户设置单日token限额和接口调用频率限制,避免被恶意刷量,导致账单爆炸;
  2. 完善容错机制:添加接口重试、熔断降级,大模型API故障的时候,返回兜底内容,避免服务崩溃;
  3. 添加日志与监控:全链路日志埋点,记录每个用户的请求、token用量、接口耗时,出问题能快速定位;
  4. 多模型适配:封装统一的模型适配层,支持一键切换豆包、OpenAI、通义千问、文心一言等多个大模型;
  5. 一键部署上线:把服务打包成Docker镜像,部署到云服务器上,让所有人都能访问你的接口。

八、可选:Java Spring Boot版本完整实现

如果你有Java基础,更习惯用Spring Boot开发,这里给你完整的Spring Boot 3.x版本实现,同样能直接跑通,实现同步+流式对话接口。

8.1 核心依赖(pom.xml)

<dependencies>
    <!-- Spring Boot WebFlux,异步非阻塞,适配流式输出 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
        <version>3.2.5</version>
    </dependency>
    <!-- Lombok,简化代码 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.32</version>
        <optional>true</optional>
    </dependency>
    <!-- Jackson,JSON处理 -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.15.3</version>
    </dependency>
</dependencies>

8.2 配置文件(application.yml)

server:
  port: 8080
llm:
  doubao:
    api-key: 你的API密钥
    api-url: https://ark.cn-beijing.volces.com/api/v3/chat/completions
    default-model: 你的模型endpoint ID

8.3 完整代码实现

package com.llm.demo.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.List;

@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "*") // 解决跨域问题
public class LlmChatController {

    @Value("${llm.doubao.api-key}")
    private String apiKey;

    @Value("${llm.doubao.api-url}")
    private String apiUrl;

    @Value("${llm.doubao.default-model}")
    private String defaultModel;

    // 初始化WebClient,异步HTTP客户端
    private final WebClient webClient = WebClient.create();
    private final ObjectMapper objectMapper = new ObjectMapper();

    // 对话消息模型
    @Data
    public static class ChatMessage {
        private String role;
        private String content;
    }

    // 对话请求体
    @Data
    public static class ChatRequest {
        private List<ChatMessage> messages;
        private String model;
        private Float temperature = 0.7f;
        private Boolean stream = false;
    }

    // 健康检查接口
    @GetMapping("/health")
    public Mono<String> healthCheck() {
        return Mono.just("服务运行正常");
    }

    // 同步对话接口
    @PostMapping("/chat")
    public Mono<JsonNode> chat(@RequestBody ChatRequest request) {
        // 构建请求体
        JsonNode requestBody = objectMapper.valueToTree(request);
        ((com.fasterxml.jackson.databind.node.ObjectNode) requestBody).put("model", request.getModel() == null ? defaultModel : request.getModel());
        ((com.fasterxml.jackson.databind.node.ObjectNode) requestBody).put("stream", false);

        // 调用大模型API
        return webClient.post()
                .uri(apiUrl)
                .header(HttpHeaders.AUTHORIZATION, "Bearer " + apiKey)
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(requestBody)
                .retrieve()
                .bodyToMono(JsonNode.class)
                .onErrorResume(e -> Mono.error(new RuntimeException("大模型调用失败:" + e.getMessage())));
    }

    // 流式对话接口,实现打字机效果
    @PostMapping("/chat/stream")
    public Flux<ServerSentEvent<String>> chatStream(@RequestBody ChatRequest request) {
        // 构建请求体
        JsonNode requestBody = objectMapper.valueToTree(request);
        ((com.fasterxml.jackson.databind.node.ObjectNode) requestBody).put("model", request.getModel() == null ? defaultModel : request.getModel());
        ((com.fasterxml.jackson.databind.node.ObjectNode) requestBody).put("stream", true);

        // 流式调用大模型API,返回SSE事件
        return webClient.post()
                .uri(apiUrl)
                .header(HttpHeaders.AUTHORIZATION, "Bearer " + apiKey)
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(requestBody)
                .retrieve()
                .bodyToFlux(String.class)
                .filter(line -> line.startsWith("data: ") && !line.equals("data: [DONE]"))
                .map(line -> {
                    try {
                        String jsonData = line.substring(6);
                        JsonNode jsonNode = objectMapper.readTree(jsonData);
                        String content = jsonNode.get("choices").get(0).get("delta").get("content").asText("");
                        return ServerSentEvent.<String>builder()
                                .event("message")
                                .data(content)
                                .build();
                    } catch (Exception e) {
                        return ServerSentEvent.<String>builder()
                                .event("error")
                                .data("解析失败")
                                .build();
                    }
                })
                .concatWithValues(ServerSentEvent.<String>builder().event("done").data("[DONE]").build())
                .onErrorResume(e -> Flux.just(ServerSentEvent.<String>builder().event("error").data(e.getMessage()).build()));
    }
}

结尾:你的AI开发之路,从这里正式开始

很多人觉得,AI大模型开发门槛很高,需要深厚的算法功底、数学基础,其实不是的。
对于99%的人来说,我们不需要去造大模型这个「发动机」,我们只需要学会用这个发动机,造出能解决实际问题的产品,而写好后端接口,就是你造产品的第一步。

今天你用30分钟,写出了第一个大模型后端接口,这不是终点,而是你AI后端开发之路的起点。后面你可以继续学习RAG知识库、Agent智能体,把你的接口变成更强大的AI产品。

如果跟着教程跑通了,欢迎在评论区留言「跑通了」,分享你的喜悦;如果遇到了任何问题,也可以在评论区留言,我会一一回复解答。

需要本文完整的代码工程包、接口调试教程、部署上线教程的同学,点赞+收藏+关注,评论区留言「接口源码」,我会一一分享给你。

更多推荐