十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

前端转AI应用开发:用Next.js + LangChain.js打造你的第一个大模型产品

前端转AI应用开发:用Next.js + LangChain.js打造你的第一个大模型产品 最近总有人问我前端是不是到头了。问这话的人多半是还在写管理后台、每天跟表格和弹窗死磕的CRUD选手。我能理解这种焦虑——你刷招聘软件满屏都是“AI应用开发”“大模型产品落地”点进去一看要求会Python、懂模型训练、有深度学习背景瞬间觉得这赛道和自己没关系。但我要泼一盆反常识的冷水现在真正缺的不是训练模型的人而是能把大模型能力包装成产品的人。而这恰恰是前端最擅长的事。我用Next.js LangChain.js把这个链路跑通过之后最大的感受是前端转AI应用开发学习成本比想象中低得多你不需要重学一套后端语言不需要啃论文只要把一套新工具链用熟就能从纯CRUD的泥潭里出来往AI应用方向走。这篇文章就把我整个思路、选型过程、最小可运行的项目代码以及踩过的坑都翻出来讲讲给想转型的朋友一条能直接参考的路线。1. 先想清楚前端做AI应用到底要会什么1.1 AI应用开发不是造模型而是“编排模型”很多前端朋友对AI开发的第一反应是我不会训练模型怎么搞这里有个巨大的认知误区。市面上绝大多数落地中的AI应用从对话机器人、文档问答、智能客服到数据分析助手核心工作根本不是训练模型而是把现成的大模型API接入业务流定义提示词、管理上下文、调用外部工具、存取对话历史、做结果格式化。用生活化的类比来解释大模型就像是刚招进来的一个能力很强但很死板的实习生。他知识面很广能写文案、能读文档、能写代码但你安排工作必须清清楚楚你要完成什么任务、有哪些约束条件、遇到什么情况调用哪个工具。AI工程师干的事情说白了就是“带实习生”——把需求拆解成流程、写清楚工作手册提示词、给实习生配好工具Function Calling / Tools最后把产出包装给用户看。这件事的门槛主要在工程化怎么接模型、怎么做流式输出、怎么让模型调用外部API、怎么把用户文档切块存进向量库供检索。这些全部是工程能力不是算法能力。而工程能力恰恰是前端每天都在练的东西你只是把对象从“后端接口”换成了“大模型”。1.2 前端转AI的隐藏优势交付链路全掌握我经常跟人讲前端转AI应用开发有一个天然优势你懂“怎么把能力变成产品”。一个AI功能光有大模型在后面是不够的。用户看到了什么、等了多久、出错怎么提示、流式打字机效果怎么实现、对话记录怎么持久化、部署在哪里全都是体验问题。你去看看市面上很多AI产品模型能力没得说但界面一塌糊涂流式响应卡顿、回答过程中没法中断、历史消息一刷新就丢、markdown渲染错乱、状态提示缺失。这些问题不是算法工程师能解决的是需要前端来兜底的。另一个隐藏优势是Next.js这类全栈框架让人具备了“顺手写完服务端”的能力。以前前端做个AI应用得求后端大哥加接口现在Next.js的API Route和Server Actions直接让前端拥有了一个轻量后端部署也简单。一个人从数据库到接口到界面全链路打通在面试和实际项目里都很加分。1.3 转型的三种常见路径和选择逻辑我见过的前端转AI大致有三种路径。第一种是转算法工程师去补机器学习和深度学习的数学基础这个路径难度最大周期按年算除非你真的对算法有热情否则我不推荐。第二种是转AI平台开发做模型训练平台、推理服务调度、数据标注系统本质还是前后端工程但离算法近一点薪资偏向传统后端。第三种是我自己走的路转AI应用开发/Agent开发直接用大模型API搭产品。第三种路径对前端最友好而且市场缺口真不小。你看招聘网站标题写着“前端开发”“前后端全栈”的岗位正在大量增加“熟悉大模型API”“有Agent开发经验”“了解LangChain/LlamaIndex”这类要求。这波红利本质上是在原有web工程能力之上加乘一层AI工具链能力底子还是那套前端/Node.js工程能力。所以选路径千万不要一上来就学Python写神经网络先做能落地的东西。2. 技术栈选型为什么这套组合对前端友好2.1 Next.js解决了“AI应用放哪里”的问题AI应用和传统CRUD应用有一个很大区别它不是等用户点按钮后拿一个JSON而是一个持续生成内容的过程。一次对话可能十几秒你要边生成边往页面上推数据这就非常考验服务端和客户端的配合。Next.js是我用下来最适合前端起步的全栈框架没有之一。它是React之上的一套完整解决方案保留了React组件模型又内置了服务端渲染、静态生成、API路由、路由处理程序这些能力。最核心的API Route机制让前端不用单独维护一个Node.js后端项目直接在同一个工程里开一个接口文件夹写起来就是普通的TypeScript函数。这意味着什么意味着你的部署单元从“前端一个项目后端一个项目可能要处理跨域和联调”变成了“一个项目全搞定”。对一个人做AI Demo或者小团队快速验证产品来说这个效率提升是决定性的。我最早试过单独开一个Express后端再配Vite前端结果联调、跨域、环境变量管理折腾了一整天换成Next.js之后半天就把一个会话机器人端到端跑通了。2.2 LangChain.js不是“JavaScript版LangChain”而是独立的编排框架很多人听到LangChain就以为是Python专属其实LangChain.js是官方维护的一等公民项目不是另外一个社区移植版本。它做的事情是抽象AI应用里最常见的重复劳动连接模型、写提示词、管理上下文、调用工具、做检索增强、处理流式输出。你可以把它理解为前端生态里的“组件库”只不过组件从按钮卡片变成了Model、Prompt、Chain、Agent、Retriever这些抽象。为什么不用原生fetch直接调OpenAI API当然可以但很快你就会被几个问题缠住流式解析要自己处理SSE格式多轮对话要把历史消息拼来拼去让模型调用外部工具时要根据模型返回的tool_calls写递归逻辑换成国产模型或开源模型的兼容接口又要改一遍请求格式。LangChain.js把这些全部做了统一抽象换模型只是换一个类加点配置就行。还有一个细节很多人没注意到LangChain.js和Vercel AI SDK其实是一对好搭档。Vercel AI SDK负责React侧的流式渲染LangChain.js负责服务端的模型编排两者通过流格式互通。我自己的项目里就是LangChain.js在服务端组织Agent和工具链前端用原生fetch读流这样架构最简单依赖最少。2.3 和Spring AI、LlamaIndex等其他方案怎么选我经常被问既然公司后端是Java要不要学Spring AI我的建议是如果你想做AI应用LangChain.js的学习优先级一定高于Spring AI。原因是前端转型讲究“复用能力”你在TypeScript/React/Node生态里的经验可以无缝迁移到LangChain.js而Spring AI等于让你同时学Java体系和新AI抽象成本翻倍而且多数AI产品团队本身就是Node/Next技术选型。LlamaIndex的定位和LangChain有点差别它更偏向“文档索引和检索”这一件事做RAG很强但做Agent和工具调用没有LangChain生态全。我的建议是先学LangChain.js把Agent、Retriever、Memory这些核心概念吃透将来真要处理复杂的海量文档检索再引入LlamaIndex或专业的向量数据库方案也是顺手的事。工具是次要的关键是你脑子里要有那套抽象模型。3. 从0到1用Next.js LangChain.js做一个流式对话应用3.1 准备项目环境和依赖先说明一下我下面演示的代码基于Next.js 14/15的App Router写法。你本地装好Node.js 18以上然后执行npx create-next-applatest ai-chat-demo创建时如果问你TypeScript和App Router直接选Yes。Tailwind这个可装可不装不影响核心逻辑。然后安装AI相关的依赖npm install langchain/openai langchain/corelangchain/openai负责接OpenAI兼容的模型接口langchain/core是LangChain的核心抽象比如提示词模板和消息对象都在这里。如果你用的是国产模型就看它有没有OpenAI兼容的API地址有的话只需要改一下配置字段后面我会说。3.2 环境变量的配置方式在项目根目录下新建.env.local文件OPENAI_API_KEY你的密钥 OPENAI_BASE_URLhttps://api.openai.com/v1 OPENAI_MODELgpt-4o-mini这里有一个关键点环境变量绝对不要写在客户端组件里。Next.js里如果你在组件代码里给变量加NEXT_PUBLIC_前缀它会被打包进浏览器端的代码等于把密钥公开到全世界。API密钥永远只在服务端使用也就是下面要写的API Route里使用。如果用的是DeepSeek、Moonshot这类国产模型它们的API通常兼容OpenAI格式你只需要改OPENAI_BASE_URL为对应平台地址再把OPENAI_MODEL改成对应模型名其他代码不用动。这就是LangChain抽象的好处。3.3 写一个最小可用的对话接口在app/api/chat/route.ts里写服务端接口import { ChatOpenAI } from langchain/openai; import { ChatPromptTemplate } from langchain/core/prompts; import { NextRequest } from next/server; // 强制使用 Node.js 运行时因为流式读写在 Edge 上容易遇到限制 export const runtime nodejs; // 这是 POST 接口由 /api/chat 触发 export async function POST(req: NextRequest) { const body await req.json(); const userMessage body?.messages?.at(-1)?.content; if (!userMessage) { return new Response(缺少用户消息, { status: 400 }); } // 1. 初始化模型temperature 控制随机性 const model new ChatOpenAI({ apiKey: process.env.OPENAI_API_KEY, model: process.env.OPENAI_MODEL || gpt-4o-mini, temperature: 0.7, streaming: true, }); // 2. 定义提示词模板system 加 human const prompt ChatPromptTemplate.fromMessages([ [system, 你是一个乐于助人的中文AI助手回答要简洁、友好、准确。], [human, {input}], ]); // 3. 用 LangChain 的 pipe 语法把模板和模型串起来 const chain prompt.pipe(model); // 4. stream 方法拿到一个异步迭代器一块一块产出回答文本 const stream await chain.stream({ input: userMessage }); // 5. 把 LangChain 的流转换成 Web ReadableStream返回给前端 const encoder new TextEncoder(); const readableStream new ReadableStream({ async start(controller) { for await (const chunk of stream) { const text chunk?.content; if (text) { controller.enqueue(encoder.encode(text)); } } controller.close(); }, }); return new Response(readableStream, { headers: { Content-Type: text/plain; charsetutf-8, Cache-Control: no-cache, no-transform, X-Accel-Buffering: no, }, }); }这段代码看着不多但每一行都有讲究。第三部的prompt.pipe(model)是LangChain里的Runnable协议它保证了prompt的输出格式正好匹配model的输入格式串联起来以后可以直接调用streamLangChain会自动把模板渲染、模型调用的流程跑完。你如果手动做就得自己拼消息数组、自己调API、自己处理返回流写出来的代码量至少翻一倍。3.4 前端页面的流式读取实现服务端接口有了前端页面要做的事就两件发请求、读流。新建一个客户端组件use client; import { useState } from react; export default function ChatBox() { const [input, setInput] useState(); const [answer, setAnswer] useState(); const [loading, setLoading] useState(false); async function handleSend() { if (!input.trim()) return; setLoading(true); setAnswer(); try { const res await fetch(/api/chat, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ // 这里先用最后一条用户消息多轮记忆在后面的章节扩展 messages: [{ role: user, content: input }], }), }); if (!res.body) return; const reader res.body.getReader(); const decoder new TextDecoder(); let done false; let result ; // 循环读取流式数据每拿到一段就更新页面 while (!done) { const { value, done: doneReading } await reader.read(); done doneReading; result decoder.decode(value ?? new Uint8Array(), { stream: !done }); setAnswer(result); } } finally { setLoading(false); } } return ( div classNameflex min-h-screen flex-col items-center justify-center gap-4 p-8 form classNameflex w-full max-w-xl gap-2 onSubmit{(e) { e.preventDefault(); handleSend(); }} input classNameflex-1 rounded-lg border p-3 value{input} onChange{(e) setInput(e.target.value)} placeholder输入你的问题... / button typesubmit disabled{loading} classNamerounded-lg bg-blue-600 px-6 py-3 text-white disabled:opacity-50 发送 /button /form div classNamew-full max-w-xl whitespace-pre-wrap rounded-lg border p-4 {answer || 回答会流式显示在这里} /div /div ); }很多初学者在网上查流式实现一看SSE、Web Stream之类就头大。其实核心就一个reader.read()的循环后台产出一段文本前端就追加一段到页面效果就是你在ChatGPT里看到的打字机输出。这样做的意义不只是视觉好看更重要的是用户不用傻等十几秒看一个空白页第一行字往往一两秒就出来体验差别非常大。3.5 在做完第一个Demo之后立刻要做三件事接口和页面跑通以后别急着做很炫酷的功能先补三件事。第一把markdown渲染加上。大模型习惯用markdown格式回答你在页面上直接用whitespace-pre-wrap显示看起来是一堆井号和星号体验很LOW。装一个react-markdown包把answer传进去渲染代码很少效果立竿见影。第二加“停止生成”按钮。流式响应背后是一次HTTP请求前端中断就是调用reader.cancel()然后顺势把对应的服务端请求 abort 掉。虽然直接中断fetch也能停下但服务端可能还在跑模型浪费token还会产生半截回答。实现方式是给fetch传一个AbortController用户点停止的时候调controller.abort()。第三对话历史至少要存在本地。最简单实用的是存localStorage页面加载时读回来发送时带上历史消息。等到单条消息超过窗口限制再去研究滑动窗口和摘要压缩那是后面章节的话题。4. 进阶玩法Agent工具调用与RAG向量检索4.1 从“聊天”到“干事”给模型接上工具调用能力纯聊天机器人价值有限真正值钱的是Agent——模型不只会说还会干活。干活的本质就是工具调用模型根据你的指令决定去调用某个函数比如查天气、查库存、发邮件然后把函数结果再交给模型让它组织成最终回答。LangChain.js里定义工具非常简单。以后端查数据库为例可以写一个getUserOrderCount的函数工具。工具需要写清楚名称、描述、参数结构。为什么要写描述因为描述就是给模型看的“使用说明”模型自己不会猜你描述得越清楚它调用得越准。下面是一个最小工具定义import { tool } from langchain/core/tools; import { z } from zod; const getUserOrderCount tool( async ({ userId }) { // 这里替换成真实验数据查询逻辑 return JSON.stringify({ userId, orderCount: 12 }); }, { name: getUserOrderCount, description: 根据用户ID查询用户的订单总数用户ID是纯数字字符串, schema: z.object({ userId: z.string().describe(用户的ID), }), } );有了工具之后把它传进模型的绑定方法里const modelWithTools model.bindTools([getUserOrderCount]); // 用 Agent 相关方法让模型自己决定是否调用工具 const res await modelWithTools.invoke(帮我查一下用户10086的订单数量);如果模型判断需要查数据它会返回一个tool_calls里面包含工具名和参数。你再根据这个结果执行工具把结果传回给模型生成最终答案。这个“模型发起调用工具执行结果回填”的过程就是Agent的雏形。LangChain的createAgent或AgentExecutor可以帮我们处理循环调用的流程但即便你手写循环逻辑也不复杂。4.2 工具调用最容易踩的三个细节第一个细节是参数校验。工具的参数模型用了Zod这是类型安全和运行时校验的保障。模型有时候会生成多一个字段、少一个字段、或者把日期格式传错Zod会在入口直接拦住不会让你的数据库查询因为脏参数而崩溃。第二个细节是描述要写“模型能看懂”的话。比如描述里写“用户ID是纯数字字符串”模型就能避免给你传用户10086这种带中文的值。这不是玄学是标注工程在工具调用里的应用。你写工具描述花了多少心思模型调用准确率就有多高。第三个细节是工具别太多、命名别太像。模型本质是靠概率选择两个工具一个叫“查订单数”一个叫“查订单总额”它很可能选错。宁可把工具合并成一个大工具用参数来区分也不要给模型留太多二选一的难题。4.3 让模型“读文档”RAG检索增强入门RAG是另一个必须掌握的概念全称是Retrieval-Augmented Generation。原理一句话在让模型回答之前先从你的知识库里检索相关片段把片段塞进提示词再让模型基于这些内容回答。为什么不把文档全塞给模型因为模型有上下文窗口限制塞不进几十万字就算塞得进去费用也高得离谱无关内容还会干扰回答质量。RAG就是把“找相关内容”和“生成回答”拆成两步找这一步是工程活用向量检索。实现RAG的标准流程分三步。第一把文档切成小段每一段用Embedding模型转成一串向量。第二把向量存进向量数据库比如pgvector、Chroma、Pinecone都行开发阶段用内存版就能跑。第三用户提问时把问题也转成向量在数据库里找最相似的若干片段拼进提示词送给大模型。LangChain.js里做RAG的链条写起来很顺伪代码如下import { OpenAIEmbeddings } from langchain/openai; import { MemoryVectorStore } from langchain/vectorstores/memory; // 1. 文档切成片段并向量化 const embeddings new OpenAIEmbeddings({ apiKey: process.env.OPENAI_API_KEY }); const vectorStore await MemoryVectorStore.fromTexts( [你的知识片段1, 你的知识片段2], [{ id: 1 }, { id: 2 }], embeddings ); // 2. 检索相似片段 const retriever vectorStore.asRetriever(3); const docs await retriever.invoke(用户问的问题); // 3. 把 docs 拼进提示词交给模型RAG这东西不难但要做好非常吃细节。分块大小多少、分块重叠多少、检索返回几个片段、提示词里怎么告诉模型“资料里没有就直说”全部要反复调才能达到能用的水平。它是AI应用开发里最值得花时间打磨的方向之一因为直接决定了产品回答的可靠性。4.4 多轮对话的记忆管理方案对话应用绕不开多轮记忆。最朴素的做法是把每轮对话都传给模型但上下文窗口撑不了几十轮。实际项目里我更常用两种方案。第一种是滑动窗口只保留最近N条消息比如10条超出就丢弃。这个方案简单粗暴缺点是模型会忘掉最早说过的话。第二种是摘要压缩每次角色切换或满窗口时把前面的对话让模型总结成一段摘要之后只传摘要加最近几条消息。这个方案效果好一点但多一次模型调用费用和延迟都增加。在Next.js这种无状态服务端里要特别注意内存保存的history会在进程重启或者多实例部署时丢失。生产环境要么用Redis存session要么依赖登录态从数据库恢复聊天记录。我自己踩过一次坑本地跑得好好的部署到云端多实例之后用户的历史消息时有时无排查了半天才发现是服务端内存不能跨实例共享。这是新手最容易忽视的问题。5. 简历与面试前端转AI怎么包装才不过度5.1 2026年前端面试风向已经变了经常有人拿着“前端面试八股文”问我还要不要背那些闭包、原型链、事件循环我的看法是基础该补还是要补但2026年的面试风向明显变了。面试官尤其是做AI产品团队的面试官已经不像以前那样只关心你怎么实现一个组件而是更关心你有没有完整的AI应用落地经验遇到流式中断怎么处理、上下文超长怎么取舍、模型乱答怎么兜底。与其刷几百道八股题不如把一个AI应用实实在在做出来。我在面试中聊得最多的不是八股而是你在项目里怎么设计提示词、怎么处理模型返回的异常格式、怎么评估回答质量。这些问题教科书上没有只有动手做过才有体感。5.2 项目怎么写突出链路完整性而不是堆名词写简历最忌讳的就是堆一串名词熟悉Next.js、LangChain.js、RAG、Agent、向量数据库……面试官一眼就看出来你没有深度。正确的写法是讲一个具体项目用了什么模型、解决了什么问题、你怎么设计工具调用流程、最终效果怎么样。举个例子同样是写“基于LangChain的智能客服”两种写法对比一下写法A熟悉LangChain.js做过基于RAG的智能客服使用Next.js开发调用了OpenAI接口。写法B基于Next.js LangChain.js开发企业知识库问答系统将产品文档按固定长度切块并向量化存入pgvector用户提问时先检索Top-3相关片段再交给gpt-4o-mini生成回答针对模型编造问题设计“资料无法回答时明确拒绝”的提示词策略通过API Route实现流式输出首字响应时间控制在1.5秒以内。不要小看这个区别。写法B每一句都是真实工程决策面试官随便追一句“为什么用Top-3这个数量怎么定的”“系统提示词具体怎么写”你都能答上来。写法A一追就露馅。5.3 跟着“前端转Agent开发”的热潮补哪些技能点现在前端圈最火的方向就是“前端转Agent开发”因为Agent开发本质上就是“把任务拆给模型去执行”而这个“拆任务”的过程只是一个更复杂的服务端流程和传统后端开发并不冲突。你需要补的技能点我按优先级列一下第一优先级是流式处理。你要不靠库也能写明白fetch读流和SSE解析。这是AI应用的前端基本功几乎每个产品都会用到。第二优先级是工具调用。给模型定义函数、处理multi-tool-calls的循环。第三优先级是RAG。懂切块、向量化、检索、重排这条完整链路。第四优先级才是各种Agent框架的API。这四层的熟练度完全可以自己用项目练出来不需要报班。我甚至在GitHub上见过有人把自己给AI模型写提示词的过程做成了一个工具调用演示项目最后成功拿到面试机会。作品比简历更有说服力这句话在AI应用领域特别成立。6. 实操路上的坑流式、超时、Key安全与模型幻觉6.1 流式输出被“卡住”的真相代理缓冲做流式输出时最让人抓狂的现象是本地一切正常部署到服务器后回答要等全部生成完了才一次性显示或者生成到一半突然断了。绝大多数情况下这是反向代理在缓冲你的响应。Nginx默认会对后端响应做缓冲它攒够一定大小才发给浏览器。所以在服务端响应头里一定要设置这个HeaderX-Accel-Buffering: no Cache-Control: no-cache, no-transformno-transform也很重要因为有些CDN会对文本做压缩转换一旦做了缓冲转换流式效果就会丢失。如果你部署在Vercel或Netlify这种平台通常会好一点但如果是自己拿Docker部署在云服务器上Nginx配置和响应头这两关必须过。6.2 超时问题Edge Runtime和Node.js Runtime的差别Next.js里API Route默认可以使用Node.js运行时也可以在文件里单独指定Edge运行时。我第一次做流式输出时为了追求“快”把export const runtime edge写上去了结果发现Edge环境有执行时间限制长时间对话很容易被平台掐断而且很多npm包在Edge里跑不了。后来我老老实实把关键接口放在Node.js运行时跑问题就消失了。在实际部署层面还要看你的平台限制。如果你用Docker自建部署这个超时主要取决于你自己Nginx的proxy_read_timeout建议设成60秒以上。如果用的是平台即服务的产品就要注意平台的函数最长执行时间流式接口长时间挂着不结束很容易被平台判定为超时强杀。6.3 模型幻觉怎么兜底模型一本正经地胡说八道是AI应用最影响信任感的问题。常见的处理手段有几个第一在系统提示词里明确约束“不要编造你没把握的信息尤其是具体的数字、日期、人名”第二用RAG把回答范围限制在给定的知识源内并要求“只基于资料回答资料没有就说明不知道”第三把回答的结构约束成schema比如强制输出JSON再用代码校验字段是否合理。需要注意这三种手段只能降低概率不能根除。更现实的做法是在产品层面做兜底用户投诉通道、回答禁用词过滤、二次校验接口。尤其对面向客户的场景一定要设置当模型输出异常时给用户的备用回复避免把模型的错误答案直接暴露在正式渠道上。6.4 成本与token的日常管理最后聊一下钱的问题。用大模型API做产品成本管理是绕不开的。我自己踩过的坑是调试的时候把开发日志写得很爽结果后台账单出来吓了一跳——因为每次请求时系统提示词里放了一大堆无用内容。管理方式就两条。第一条给系统提示词减肥。固定的系统提示词虽然看着不贵但每个请求都带上人一多倍数效应非常吓人。第二条给模型分级。复杂任务用大模型简单任务用便宜的小模型甚至可以用关键词规则先过滤一遍不必要的就不调模型。没有人规定一个应用只能用一个模型混合使用节省的成本肉眼可见。最后说两句实在的做前端转AI应用开发这段时间我最大的体会是真正拦住你转型的不是数学不是Python不是论文而是“我不行”的预设。你完全可以在周末两天里用Next.js和LangChain.js把一个能跑通的AI聊天应用做出来。然后第二个周末给它加一个工具调用。第三个周末加一个RAG文档问答。几个月后你手里的项目就会成为简历上最硬的一张牌。最后再分享一个小技巧刚开始做一个AI应用的时候不要把功能范围定太大就做一个问答机器人加一个工具调用就够。功能越少你越能把提示词打磨到位把错误处理做扎实把流式体验调到顺滑。这些精细的体验打磨恰恰是区分“会调API”和“会做AI产品”的关键也是你真正值钱的地方。
返回列表