恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
从零构建AI聊天机器人:手把手教你接入大模型API
首页
资讯中心
/
从零构建AI聊天机器人:手把手教你接入大模型API
从零构建AI聊天机器人:手把手教你接入大模型API
发布时间:2026/10/19 4:28:22
都2026年了如果你还停留在用过各种AI对话产品的阶段那我建议你把自己动手写一个AI聊天机器人当成今年第一个该做的练手项目。这几年被问得最多的一句话是我想学AI但网上那些项目动不动就训练模型、微调、跑GPU门槛高得吓人。每次听到这种话我都想拍桌子AI项目没那么玄乎。从0到1搭一个聊天机器人恰恰是你理解AI应用到底是怎么跑起来的最短路径。它不要求你懂模型原理不需要碰任何数学公式你只需要学会一件事把别人训练好的大脑接进自己的程序里。你不需要发明发动机你只需要学会造车——造车这件事是个人都能学会。这篇文章我打算当面对一个从没写过AI项目的朋友聊从选服务商、配环境到写后端、做界面再到各种我踩过的坑全程不绕弯子。所有代码都给你看所有参数都解释为什么这么设。读完你手上会多一个真正能跑、能聊天、能带记忆的机器人而不是一大堆半懂不懂的概念。1. 为什么2026年还在推荐聊天机器人当第一个AI项目1.1 它覆盖了AI应用开发的全部核心链路先聊点实在的。你不写聊天机器人直接去看什么AI画图AI语音克隆看着酷但那些项目多半是调别人的现成接口你根本看不到完整链路。聊天机器人虽然朴素但它五脏俱全有输入、有输出、有状态管理、有网络请求、有异步处理、有前端交互。这些恰恰是你在任何AI产品里都会遇到的通用能力。你今天学会了聊天机器人明天把它改成AI客服AI文档问答AI编程助手基本只需要换数据、换提示词、换个界面壳子。反过来如果你一上来就搞语音克隆你可能会被一堆音频格式和模型权重文件折磨到怀疑人生。1.2 技术栈极简任何基础都能上手聊天机器人最精简的形态只需要三样东西一个能联网发请求的后端我这里用Python、一个能打字聊天的网页前端HTML加JavaScript、一个大模型API你只需要注册账号、拿一个Key。没有数据库没有缓存没有消息队列没有任何复杂的中间件。整个项目跑起来核心代码不超过200行。你完全可以把注意力集中在我怎么跟一个AI对话这件事本身上而不是被一堆基础设施淹没。我带过不少朋友走这条路最快的一个从零基础到跑通整个项目只用了两个晚上而且他是做运营的完全没写过代码。1.3 它逼你理解上下文这个概念这是我强烈推荐聊天机器人的另一个原因它是理解大模型对话机制的最短路径。你会发现同一个模型为什么有时候回答得好有时候答非所问为什么你说帮我写个总结它不知道总结什么这些问题的答案都指向一个词——上下文。聊天机器人天然要求你处理消息历史、管理token长度这些经验在后面的AI项目里会反复用到。今天你在聊天机器人的messages数组上花的心思明天做一个文档问答工具时照样管用。很多概念你光看文档是记不住的亲手调过一次就刻进脑子里了。2. 动手前先搞清结构一台聊天机器人到底由什么组成2.1 三个角色各司其职先别急着敲代码。在脑子里画一张图你的聊天机器人由三个角色组成。第一个是大脑也就是大模型API。它负责理解你的问题、生成回答但你见不到它你只能通过HTTP请求跟它说话。第二个是邮差也就是你的后端程序。它夹在你和大脑之间收集你说的话带上必要的身份凭证和聊天记录转交给大脑再把大脑的回答原封不动地搬回来。第三个是门面也就是前端页面。它是用户唯一能看见的东西提供一个输入框和一个对话列表把消息展示出来。这三个角色的边界非常清晰。很多新手最开始犯的错误就是把逻辑全塞进前端让浏览器直接去调API。这样做的确能跑通但你的API Key会暴露在浏览器的网络面板里谁打开你的页面谁就能看到你的密钥——这就是被人拿去刷爆账单的标准姿势。2.2 事件顺序一次对话发生了什么以用户发了一条消息为起点完整的事件顺序是用户在输入框里打字点发送前端把这条消息追加到页面上的对话列表里前端把消息发给后端接口后端把历史消息加新消息组装成请求体发给大模型API大模型开始生成回答注意是开始不是一次性给你后端把回答通过流式方式一点一点转发给前端前端每收到一点内容就把它实时追加到页面上直到回答结束前端把一次完整对话画上句号理解这个顺序后你就能明白一个关键点从第5步开始数据是流动的不是一坨一坨扔过来的。这就是流式输出。2.3 为什么要做流式输出你可能觉得等模型全回答完再一次性显示不就行了行是行但体验差距巨大。大模型生成一段回答通常要几秒到十几秒如果用户点了发送之后屏幕上什么都没有然后突然冒出一整段文字用户会有两种反应要么觉得程序卡死了要么觉得你的服务慢得要命。流式输出的本质是让用户在模型还在思考的时候就能看到文字一个一个蹦出来。这个感知差别非常大——同样一个回答流式显示用户会觉得哇好流畅非流式显示用户会觉得好慢。而且流式输出还能让你实现打字机效果在对话类产品里这几乎是标配。你把浏览器开发者工具打开亲自对比一次流式和非流式的差别以后你给任何AI产品做界面都不会想回到等一整段的老路。3. 环境准备与选型暗坑都在这一步3.1 API选型三个硬性指标选大模型API是整个项目里唯一需要花钱的部分也是坑最多的地方。我建议你按照三个硬指标来选。第一个是接口兼容性。2026年的大模型服务商已经收敛得差不多了绝大多数都提供一套行业通用的HTTP接口格式各家差异只在域名、模型名和Key前缀。选的时候认准那些遵循通用格式的服务商以后你换一家只需要改配置代码几乎不用动。避开那些接口格式极其个性的服务商否则你以后每次换服务商都要重写一遍对接代码非常痛苦。第二个是流式支持。市面上基本没有不支持流式的商用API了但部分免费额度接口可能会把流式参数静默忽略这就导致你前端写的流式读取逻辑永远收不到增量数据。选的时候先在文档里确认stream参数最好直接看有没有Server-Sent Events或流式输出的说明。第三个是上下文长度。别只看模型的参数规模要看它支持的最大上下文token数。对话机器人至少要4K以上的上下文窗口否则几轮对话后历史就把窗口挤爆了。预算允许的话直接选支持长上下文的模型后面做记忆功能会轻松很多。3.2 本地环境的三个准备工作Python环境的坑就三个每一个我都见过有人踩第一Python版本。别用系统自带的那个老版本Python去官网装一个3.10以上的装的时候勾选Add Python to PATH。这一步不做后面你大概率会遇到python不是内部或外部命令这种让人血压升高的提示。第二虚拟环境。我见过太多初学者把依赖装进全局环境几个月后整个机器上的包全乱成一团。搞一个虚拟环境是成本最低的健康习惯# 创建虚拟环境 python -m venv .venv # 激活Windows .venv\Scripts\activate # 激活macOS/Linux source .venv/bin/activate第三依赖安装。这个项目其实只需要一两个库别贪多。先装一个发送HTTP请求的库就行后面如果需要写Web接口再加一个轻量Web框架。但千万别在第一步就把什么numpy、pandas、机器学习框架全都装上用不着只会让环境变得臃肿。3.3 API Key管理的正确姿势这是新手最容易忽略但最致命的一环。API Key的本质是你的钱包钥匙——按量计费的服务里Key一旦泄露对方可以拿你的Key疯狂调用账单直接起飞。正确做法永远只有一个把Key存在后端环境变量里不要写死在代码里更不要放进前端。先用命令行设置环境变量或者写到项目根目录的一个配置文件里然后在代码中通过os.environ.get()读取。这一条值得刻在显示器上代码写进仓库可以Key写进仓库就是事故。后面我会再讲到怎么用忽略列表保证Key不会被提交那是底线中的底线。4. 后端实现把大脑接进你的程序4.1 最简版本一次普通请求先写一个不含流式的最简版本让你先把链路跑通。这个版本做的事情很纯粹接收一条消息转发给大模型API拿到完整回答再返回。import os import requests # 从环境变量读取配置 API_KEY os.environ.get(LLM_API_KEY) BASE_URL https://你的服务商接口地址/v1/chat/completions def chat_with_llm(messages): headers { Authorization: fBearer {API_KEY}, Content-Type: application/json, } payload { model: 你的模型名, messages: messages, stream: False, } resp requests.post(BASE_URL, headersheaders, jsonpayload, timeout60) data resp.json() return data[choices][0][message][content]这个函数是整个项目的核心后面所有功能都围绕着怎么增强它。你往里传一个消息列表它给你返回模型回答的文本。messages列表是什么这是与大模型对话时唯一需要你理解的数据格式。它是一个数组每个元素是一段消息[ {role: system, content: 你是一个乐于助人的AI助手}, {role: user, content: 你好给我讲个笑话}, {role: assistant, content: 好的给你讲一个程序员的笑话……} ]role有三种system表示系统指令user表示用户说的话assistant表示AI自己之前说过的话。你不需要理解模型是怎么消化这些的你只需要记住把整个对话历史按顺序拼成这个数组发给模型模型就能记得前面的对话。4.2 加上Web接口让前端能访问光有上面的函数还不够你需要一个HTTP接口让前端页面能调用它。这里用Python的轻量Web框架来写一个最简服务from flask import Flask, request, jsonify import os import requests app Flask(__name__) API_KEY os.environ.get(LLM_API_KEY) BASE_URL https://你的服务商接口地址/v1/chat/completions MODEL_NAME 你的模型名 def chat_with_llm(messages): headers { Authorization: fBearer {API_KEY}, Content-Type: application/json, } payload { model: MODEL_NAME, messages: messages, stream: False, } resp requests.post(BASE_URL, headersheaders, jsonpayload, timeout60) data resp.json() return data[choices][0][message][content] app.route(/api/chat, methods[POST]) def chat_api(): body request.get_json() messages body.get(messages, []) answer chat_with_llm(messages) return jsonify({content: answer}) if __name__ __main__: app.run(host0.0.0.0, port8000, debugTrue)到这里你其实已经把传输大脑的核心链路打通了。你可以用命令测试不用打开浏览器就能验证后端是通的curl -X POST http://127.0.0.1:8000/api/chat \ -H Content-Type: application/json \ -d {messages:[{role:user,content:你好}]}4.3 升级成流式打字机效果的关键现在到了让聊天机器人活起来的关键一步——流式返回。改动两个地方就够。后端侧把stream参数改成True然后用逐行解析的方式读取返回的增量数据import os import json import requests API_KEY os.environ.get(LLM_API_KEY) BASE_URL https://你的服务商接口地址/v1/chat/completions MODEL_NAME 你的模型名 def chat_with_llm_stream(messages): headers { Authorization: fBearer {API_KEY}, Content-Type: application/json, } payload { model: MODEL_NAME, messages: messages, stream: True, } resp requests.post(BASE_URL, headersheaders, jsonpayload, streamTrue, timeout60) for line in resp.iter_lines(): if not line: continue line line.decode(utf-8) if line.startswith(data:): data_str line[5:].strip() if data_str [DONE]: break try: chunk json.loads(data_str) delta chunk[choices][0].get(delta, {}) content delta.get(content, ) if content: yield content except json.JSONDecodeError: continue这个生成器的逻辑不复杂大模型API在流式模式下会不断推送形如data: {...}的行每一行的delta.content字段里装着模型这一瞬间生成的一小段文字。你把这些小段依次向外抛前端就能一个字符一个字符地收到。然后改接口让Web服务用特定类型的响应对象把流式内容一段段返回给前端from flask import Flask, request, Response # 接上文配置 app.route(/api/chat_stream, methods[POST]) def chat_stream_api(): body request.get_json() messages body.get(messages, []) def generate(): for content in chat_with_llm_stream(messages): yield fdata: {content}\n\n return Response(generate(), mimetypetext/event-stream)看到text/event-stream这个MIME类型了吗这就是Server-Sent EventsSSE的标准响应类型前端可以用流式读取来消费它。4.4 组装上下文把历史消息带上聊天机器人跟问答机的区别在于它要记得你们前面聊了什么。实现方式前面已经埋了伏笔把历史消息数组传给模型。app.route(/api/chat_stream, methods[POST]) def chat_stream_api(): body request.get_json() messages body.get(messages, []) # 在请求体里追加系统指令设定AI的人设 system_prompt {role: system, content: 你是一个性格幽默、说话简练的AI助手请用口语化方式回答用户问题。} full_messages [system_prompt] messages def generate(): for content in chat_with_llm_stream(full_messages): yield fdata: {content}\n\n return Response(generate(), mimetypetext/event-stream)注意一个细节你在后端组装消息时不能完全信任前端传过来的数组。至少要做两件事校验消息条数上限以及强制在数组头部插入你的system指令。原因很简单前端可以被任何人伪造如果直接把前端传的messages丢给模型别人可以注入任意的系统提示词绕过你的人设和内容约束。到这里后端的核心能力已经齐了能接收消息、能带上下文、能流式返回。接下来把门面搭起来。5. 前端界面能打字、能滚动、能看流式打字机5.1 一个文件搞定HTML加JavaScript先不用上什么前端框架一个纯静态HTML文件就够。聊天机器人前端的核心只有一个拿到输入、发请求、把流式内容渲染成打字机效果。!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleAI 聊天机器人/title style body { max-width: 720px; margin: 0 auto; padding: 20px; font-family: system-ui, sans-serif; } #messages { border: 1px solid #ddd; border-radius: 12px; padding: 16px; height: 60vh; overflow-y: auto; margin-bottom: 12px; } .msg { margin-bottom: 12px; line-height: 1.6; } .msg.user { text-align: right; color: #1a73e8; } .msg.ai { text-align: left; color: #333; } #input-row { display: flex; gap: 8px; } #user-input { flex: 1; padding: 10px; border-radius: 8px; border: 1px solid #ccc; font-size: 16px; } button { padding: 10px 20px; border-radius: 8px; border: none; background: #1a73e8; color: #fff; font-size: 16px; cursor: pointer; } /style /head body h1AI 聊天机器人/h1 div idmessages/div div idinput-row input iduser-input placeholder输入你的问题... / button idsend-btn发送/button /div script // 交互逻辑见下一节 /script /body /html这个页面没有花哨的设计但把对话产品的三要素抓齐了消息区、输入框、发送按钮。5.2 核心交互用fetch读流式响应JavaScript这边的关键代码是使用fetch加流式读取来逐段接收后端推送的SSE数据const API_URL http://127.0.0.1:8000/api/chat_stream; let history []; async function sendMessage() { const input document.getElementById(user-input); const text input.value.trim(); if (!text) return; input.value ; // 1. 追加用户消息到页面 appendMessage(user, text); history.push({ role: user, content: text }); // 2. 创建一个空的AI消息占位准备接收流式内容 const aiBubble appendMessage(ai, ); const fullAnswer []; // 3. 发起流式请求 const response await fetch(API_URL, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ messages: history }), }); // 4. 逐段读取并渲染 const reader response.body.getReader(); const decoder new TextDecoder(); while (true) { const { done, value } await reader.read(); if (done) break; const chunkText decoder.decode(value, { stream: true }); // 解析 SSE 格式data: 内容 const lines chunkText.split(\n); for (const line of lines) { if (line.startsWith(data:)) { const content line.slice(5); if (content) { fullAnswer.push(content); aiBubble.textContent fullAnswer.join(); } } } // 让消息区自动滚到底部 const msgBox document.getElementById(messages); msgBox.scrollTop msgBox.scrollHeight; } // 5. 把AI回答加入历史下一轮才能记住上下文 history.push({ role: assistant, content: fullAnswer.join() }); } function appendMessage(role, text) { const box document.getElementById(messages); const div document.createElement(div); div.className msg role; div.textContent text; box.appendChild(div); return div; } document.getElementById(send-btn).addEventListener(click, sendMessage); document.getElementById(user-input).addEventListener(keydown, (e) { if (e.key Enter) sendMessage(); });这段代码有几个细节值得单独说明。第一fullAnswer数组的作用。流式内容是一段段追加的你不能直接拿每一段去覆盖textContent要先把所有片段攒起来再拼成完整字符串。如果你偷懒直接做字符串拼接在表情符号或中英文混排的场景下偶尔会出现乱码或丢字。第二历史数组的作用。history数组在每次对话结束后都会把AI的回答push进去这就是上下文记忆的最简实现。下次再发消息时整个history会被后端带上发给模型。第三滚动到底部的时机。如果你在追加内容之前滚动用户会看到消息区被卡在中间不动体验很差。每次收到新内容都强制滚到底部才能营造出文字在往下长的流畅感。5.3 跑起来启动顺序和验证清单现在把整个项目跑起来。启动顺序有讲究# 1. 确保虚拟环境已激活依赖已装好 # 2. 确保环境变量里有 LLM_API_KEY # 3. 启动后端 python app.py # 4. 用浏览器打开前端页面 # 如果前端是单独文件直接在浏览器里打开 index.html 即可 # 如果前端走本地服务就访问对应的本地地址打开页面后按这个顺序自检在输入框打你好点发送页面立刻出现你的消息气泡大约一两秒后AI气泡开始出现文字逐字增长等回答结束后继续追问一句那你能再详细讲讲吗看AI是否记得上一句的话题打开浏览器开发者工具的Network面板确认chat_stream请求的响应类型是text/event-stream如果第2步出现等很久然后一次性冒出一大段说明后端流式解析没生效去检查后端日志里有没有逐行输出。6. 从本地到能给人用绕不开的五个坑6.1 跨域问题前端一调用就被浏览器拦这是新手从本地自嗨切换到前后端分离时遇到的第一道墙。如果你的前端页面是用文件协议直接打开的或者前端目录的端口跟后端不同浏览器会因为跨域安全策略直接拦截你的请求报错信息里会出现CORS这个词。解决办法有两个二选一第一个办法把前端文件和后端放到同一个服务里统一端口访问。最简单本地跑够用。第二个办法在后端显式允许跨域。用轻量Web框架的话可以加一个响应头app.after_request def add_cors_headers(response): response.headers[Access-Control-Allow-Origin] * response.headers[Access-Control-Allow-Headers] Content-Type return response注意Access-Control-Allow-Origin设为*只适合本地开发和测试。真要部署给别人用务必把它改成你前端的真实域名否则你的后端可以被任意网站调用。6.2 超时问题模型转圈圈前端先崩了大模型API的响应时间不可控。一个复杂的提问可能要30秒短的可能1秒。如果在代码里设置了30秒超时遇到模型高峰期就可能掐断回答。我的建议是超时时间设置得宽裕一些并且在前端做等待反馈——发送按钮变成生成中...并禁用防止用户重复点击导致重复扣费。这个小改动看着不起眼实际使用体验差很多。6.3 上下文超长对话一长就报错前面提到过模型有上下文窗口上限。你聊了50轮之后history数组里的内容可能已经超长这时候再发请求API会返回类似上下文长度超限的错误。处理方式有很多种最简单的方案叫滑动窗口截断只保留最近N轮对话旧的全部丢掉。MAX_TURNS 10 def trim_messages(messages): # 保留system再保留最近MAX_TURNS轮对话 system [m for m in messages if m[role] system] rest [m for m in messages if m[role] ! system] return system rest[-(MAX_TURNS * 2):]这个方案粗暴但有效。代价是模型会忘记很久之前的对话但对于大多数闲聊场景完全够用。如果你想更精致一点可以做摘要压缩——把老对话预先让模型总结成一段话塞回历史里但这个属于进阶玩法的范畴了。6.4 并发问题本地跑着好好的一上线就崩本地测试时你是一个人一个请求永远发现不了并发问题。但一旦你把机器人发给朋友用两三个人同时发消息同步阻塞式的后端就会排队——一个人卡住所有人卡住。这个项目阶段你不需要上多复杂的架构但至少要知道部署时用支持异步的Web服务来跑别用开发模式的调试服务器。开发模式自带的服务器明确不适合生产环境这点官方文档都有写但很多人忽略了。你只需要记住本地调试随便跑真要给别人用了先查一下怎么用生产级的方式启动你的Web服务。6.5 响应慢为什么回答总是慢半拍最后一个不是bug但影响体验的点网络延迟。模型在云端你的后端在本地前端在浏览器三段传输都有延迟。实测中一段500字的回答在流式模式下用户感知大约3到6秒属于正常范围。如果感觉明显偏慢先看是不是服务商机房距离太远再看是不是代码里某个调试用的延时语句没删干净。别小看后面这条我见过有人调试流式效果时加了延时参数最后忘了删回答慢了一倍。7. 进阶玩法让聊天机器人从能聊到好用7.1 加人设用system prompt定制性格这是成本最低的换皮功能。你只需要改一行system指令同一个模型就能从严谨的客服变成毒舌的段子手。我试过一个小实验同一个模型、同一个问题把system从你是一位严谨的技术顾问回答要精确、周全改成你是一位说话很损的科技博主回答要幽默、简短、经常自嘲输出风格的差异立竿见影。这就是提示词工程最直观的威力——你不需要训练模型你只需要教会模型以什么身份说话。不过要注意分寸system指令里写得太细太长反而会挤占上下文窗口还会让模型显得机械。我一般控制在两三句话以内明确身份加语气加输出格式就够。7.2 加记忆让机器人记住你是谁滑动窗口截断的升级版是做长期记忆。最简单的方案是在对话开始前问用户你叫什么名字把名字存到一个变量里后续每次组装messages时在system后面追加一句用户的名字是小林请在回答中偶尔称呼他。再升级一点可以用一个极简的画像文件——每次对话结束后用模型自己总结出一句话的用户画像比如{name: 小林, interests: 独立游戏、手工皮具, tone: 喜欢简短回答}下次对话时把画像塞进system。这样机器人在几十轮之后依然能想起用户是谁而且是动态更新的。7.3 加工具从聊天到干活聊天机器人最容易的价值跃迁是给它加工具调用能力——让AI不只是回答问题还能触发你的代码去干实事。比如用户说帮我查一下明天的天气模型识别到意图后不是自己瞎编一个答案而是返回一个结构化指令你的后端收到后去调用天气接口拿到真实数据再喂回给模型整理成自然语言。这个模式在2026年已经非常成熟了几乎所有主流大模型都支持工具调用。实现上你只需要在后端定义工具的JSON描述然后在请求体里带上tools参数{ name: get_weather, description: 查询指定城市的天气, parameters: { type: object, properties: { city: {type: string, description: 城市名称} }, required: [city] } }然后你需要在后端写一个分发函数模型第一次返回的不是完整回答而是一个调这个工具、传这些参数的指令你的代码执行完工具后把结果拼进消息历史再让模型基于真实数据生成最终回答。这部分对新手有一定理解成本建议你把前面的基础链路跑顺之后再往这个方向拓展。8. 收尾别人看不到但你必须有的三个好习惯8.1 从第一天就放进版本管理哪怕是你一个人写的项目也建议从第一天就放进版本管理仓库里。不是为了给别人看是为了让你自己敢改代码——每次改坏了能一键回到上一次能跑的状态。这个习惯比任何技术都重要。操作起来很简单在项目根目录执行初始化命令然后提交一次初始版本。之后每完成一个功能点就提交一次提交信息写清楚加了流式输出修了上下文超长问题这种话。等你改砸了代码你会感谢那个勤快的自己。8.2 密钥保护是底线前面强调过API Key不能写进代码这里再说一个配套动作把存放密钥的配置文件加进忽略列表确保它永远不会被提交。忽略列表的写法很简单在项目根目录建一个文件里面写一行密钥文件名就行。这是程序员的基本素养也是你以后进任何团队都会被默认要求的事。养成习惯从第一个项目开始。万一Key真的泄露了怎么办马上去服务商后台把它吊销重新生成一个。不要有侥幸心理我见过有人泄露Key之后几分钟内账单就多了几十块的调用费用。8.3 展示与部署的节奏感如果你打算把这个项目展示给别人先别一上来就整云服务器、域名、HTTPS那一套。先跑在本机让朋友坐你旁边看效果就够了你只需要把页面打开把后端跑起来让他们轮流动手问几个问题。这一步主要是验证别人用起来顺不顺手你要观察的是他们会不会卡在输入环节、AI的回答会不会吓他们一跳。等你确认产品体验没问题了再考虑部署到公网。但到了那一天你会自然发现本地跑通和上线部署差的不是技术是经验——而那又是另一个值得写五千字的话题了。说实话整个流程走下来你会发现AI项目真的没有想象中那么神秘。它就是你熟悉的那套前端发请求、后端接请求、调外部接口的普通Web开发只不过你调用的这个外部接口恰好是一个聪明得有点吓人的大脑。我的亲身感受是当你第一次看到自己写的页面上一字一字蹦出AI的回答时那种我造了个什么东西的成就感比看一百篇AI趋势文章都来得实在。去试试吧代码都在上面了剩下的就是你把它们敲一遍敲完你就是写过AI项目的人了。