当前位置: 首页 > news >正文

基于无头浏览器与Puppeteer的ChatGPT API模拟器部署与实战指南

1. 项目概述:一个无头浏览器的ChatGPT API模拟器

如果你正在寻找一种绕过官方API限制、直接通过你的ChatGPT账户与AI对话的本地化方案,那么Headless ChatGPT这个项目很可能就是你需要的工具。简单来说,它是一个基于Node.js和Puppeteer构建的本地服务器,通过自动化控制一个无头(或带界面的)Chrome浏览器,模拟用户与ChatGPT网页版的交互,并将这些交互封装成一套简洁的HTTP API。这意味着,你无需等待OpenAI的API审批,也无需支付API调用费用,仅凭一个可用的ChatGPT账户,就能在自己的机器上搭建一个私有的、功能近乎完整的“ChatGPT API服务”。

这个项目的诞生背景非常“极客”:开发者HalilCan因为遇到了官方API访问的诡异错误而无法使用,一怒之下决定自己动手,丰衣足食。这种“没有条件就创造条件”的思路,恰恰是开源社区精神的体现。它解决的痛点非常明确——为那些因地域限制、API等待名单、费用考量或特定自动化需求而无法直接使用官方接口的开发者,提供了一个可行的替代方案。无论是想集成AI能力到自己的桌面应用、构建一个本地的代码助手,还是进行批量的对话测试,这个工具都能派上用场。接下来,我将带你从零开始,深入拆解这个项目的部署、使用、原理以及那些官方文档里不会写的实战避坑指南。

2. 核心原理与架构拆解

2.1 无头浏览器与Puppeteer:自动化基石

要理解Headless ChatGPT如何工作,首先得明白它的两大技术支柱:无头浏览器和Puppeteer。无头浏览器,顾名思义,就是一个没有图形用户界面的浏览器。它能像普通浏览器一样渲染网页、执行JavaScript、处理网络请求,但所有操作都在后台通过命令行或程序接口完成。这使其成为网页自动化、测试和爬虫的理想工具。

Puppeteer则是Google官方推出的一个Node.js库,它提供了高级API来控制Chrome或Chromium浏览器。你可以把它想象成一个遥控器,通过代码来指挥浏览器“点击这里”、“输入文字”、“截图”、“获取页面内容”。Headless ChatGPT的核心,就是利用Puppeteer启动一个浏览器实例,导航到chat.openai.com,然后模拟真实用户的所有操作:登录、点击新聊天按钮、在输入框打字、点击发送、最后从DOM中提取AI的回复文本。

这种方式的优势在于,它直接与ChatGPT的Web前端交互,因此能享受到Web端的所有功能(例如最新的模型、联网搜索、文件上传等,只要网页端支持),且完全避开了官方API的调用限制和费用。但劣势也同样明显:它依赖于ChatGPT网页版的结构稳定性,一旦OpenAI更新了前端UI,选择器就可能失效,导致脚本报错;同时,它的性能和稳定性不如真正的API,容易受到网络波动、页面加载速度以及反机器人检测机制的影响。

2.2 项目架构:从浏览器操作到HTTP API

Headless ChatGPT的架构可以清晰地分为两层:浏览器控制层API服务层

浏览器控制层是项目的引擎,由Puppeteer驱动。它负责:

  1. 浏览器生命周期管理:启动、关闭浏览器实例。
  2. 页面导航与状态维护:确保浏览器始终处于ChatGPT的对话页面,并处理可能的登录态过期、网络错误等异常。
  3. DOM交互模拟:这是最核心的部分。项目代码中包含了大量针对ChatGPT网页元素的选择器(如输入框的CSS选择器、发送按钮的XPath、回复消息容器的类名)。通过Puppeteer的API(如page.click()page.type()page.waitForSelector()),它精确地模拟了用户的点击、输入、等待等行为。
  4. 数据提取:当AI回复生成后,脚本需要从复杂的HTML结构中定位到包含纯文本回复的那个元素,并将其内容提取出来。这通常需要等待特定的元素出现(如代表“正在输入”的动画消失),并解析其内部文本或HTML。

API服务层是项目的对外接口,通常基于Node.js的HTTP模块或Express框架构建。它将底层复杂的浏览器操作封装成一个个简单的HTTP端点(Endpoint)。例如,当你向/queryAi发送一个POST请求时,API层会:

  1. 解析请求体中的text参数。
  2. 调用浏览器控制层的相应函数,执行“在输入框输入文本 -> 点击发送按钮 -> 等待回复 -> 提取文本”这一系列操作。
  3. 将提取到的回复文本包装成JSON格式,通过HTTP响应返回给调用者。

这种分层设计的好处是解耦。使用者无需关心Puppeteer的复杂语法或ChatGPT页面的DOM结构,只需要像调用普通REST API一样发送HTTP请求即可。项目的server.js文件就是这两层逻辑的粘合剂,它既启动了HTTP服务器,也初始化并管理着Puppeteer的浏览器实例。

3. 环境准备与项目部署实操

3.1 系统环境与前置依赖检查

在开始之前,请确保你的开发环境已就绪。Headless ChatGPT是一个Node.js项目,因此首要条件是安装Node.js及其包管理器npm。建议使用Node.js的LTS(长期支持)版本,如18.x或20.x,以获得更好的稳定性和兼容性。你可以在终端运行node -vnpm -v来检查是否已安装及版本号。

注意:由于Puppeteer需要下载一个特定版本的Chromium浏览器(约120MB),请确保你的网络环境能够顺畅访问Google相关的资源。在某些网络环境下,这可能会成为部署过程中的第一个障碍。如果下载缓慢或失败,可以考虑配置npm镜像源,但更关键的是Puppeteer自身的下载源可能需要通过环境变量PUPPETEER_DOWNLOAD_HOST来指向国内镜像,这是一个常见的坑点。

除了Node.js,理论上无需其他特殊依赖。但为了后续操作顺畅,建议准备一个有效的ChatGPT Plus或免费账户。虽然项目可能支持未登录状态下的某些操作,但核心的对话功能必然要求已登录状态。

3.2 一步步安装与启动服务

安装过程非常标准,遵循Node.js项目的通用流程。但我会补充一些细节和解释,帮你理解每一步在做什么。

  1. 创建项目目录并初始化:首先,为你这个实验创建一个独立的文件夹是个好习惯,可以避免污染全局环境。

    mkdir my-headless-chatgpt && cd my-headless-chatgpt

    你可以在此目录下直接安装Headless ChatGPT。

  2. 安装Headless ChatGPT包:通过npm安装它。这会将这个包及其所有依赖(最重要的是Puppeteer)下载到本地的node_modules目录。

    npm install headless-chatgpt

    安装完成后,你可以检查node_modules目录下是否存在headless-chatgptpuppeteer文件夹。

  3. 补全依赖与安装Chromium:根据项目说明,有时可能需要显式安装缺失的依赖。更关键的一步是确保Puppeteer的Chromium浏览器已正确安装。

    npm install node node_modules/puppeteer/install.js

    第二行命令是专门用于下载Chromium的。如果你看到类似“Downloading Chromium rXXXXXX...”的提示,并在稍后看到“Chromium downloaded to /path/to/...”的完成信息,说明浏览器本体已就绪。这个过程耗时取决于你的网速。

  4. 定位并启动服务器:安装完成后,核心的可执行文件是headless-chatgpt包里的server.js。你需要找到它的确切路径来启动。通常,你可以使用npm提供的npx命令来直接运行位于node_modules/.bin或包目录下的脚本。最直接的方式是:

    node node_modules/headless-chatgpt/server.js 3000

    这里的3000是指定服务器监听的端口号,你可以换成任何未被占用的端口,如8080

  5. 首次运行与登录:当你第一次运行上述命令时,Puppeteer会启动一个Chromium浏览器窗口(默认是有界面的,方便你观察和登录)。浏览器会自动打开ChatGPT的登录页面。

    • 手动登录:此时,你需要像平常一样,手动输入账号密码完成登录,并处理可能出现的验证码。如果开启了双重认证,也需要完成验证。
    • 处理弹窗:登录成功后,ChatGPT可能会有一些欢迎或功能介绍的弹窗。务必手动点击关闭或“下一步”直到进入主聊天界面。这是至关重要的一步,因为自动化脚本默认预期浏览器处于一个干净、可用的聊天页面状态。
    • 确认就绪:当浏览器稳定地停留在ChatGPT的主聊天界面,并且你能看到输入框和模型选择器(如GPT-3.5/GPT-4)时,说明初始化成功。此时,终端中运行的Node.js服务器应该处于等待请求的状态。

实操心得:强烈建议在第一次启动时使用有头模式(即显示浏览器界面)完成登录和初始化。这能让你直观地看到自动化过程,并在出现问题时(如页面卡在验证环节)及时干预。后续为了节省资源,你可以研究通过Puppeteer启动参数配置无头模式,并尝试复用浏览器缓存或用户数据目录来避免每次重启都需要重新登录。

4. API接口详解与实战调用

服务器启动并完成登录后,它就在你指定的端口(例如3000)上提供了一系列HTTP端点。我们可以使用任何能发送HTTP请求的工具来测试,比如curl、Postman,或者用你熟悉的编程语言(Python、JavaScript等)编写脚本。下面,我将分类详解最核心的几个API,并提供具体的调用示例和注意事项。

4.1 核心对话接口:/queryAi 与 /retry

这两个接口是实现AI对话功能的核心,一个用于发起新提问,一个用于重试上一个提问。

POST /queryAi这是最主要的对话接口。你需要向它发送一个JSON格式的请求体。

  • 请求体{ "text": "你的问题或指令" }。你还可以添加一个可选的"context"字段,用于提供对话上下文(但根据我的测试,Web版ChatGPT的上下文是连续在会话中的,这个参数的具体行为需看源码实现)。
  • 响应:成功时返回{ "response": "AI生成的回复文本" };失败时返回包含错误信息的JSON。

示例调用 (使用curl)

curl -X POST http://localhost:3000/queryAi \ -H "Content-Type: application/json" \ -d '{"text": "用Python写一个快速排序函数"}'

调用后的内部过程

  1. 服务器接收到请求,解析出text
  2. Puppeteer脚本在已打开的ChatGPT页面中,定位到消息输入框(通常通过特定的CSS选择器,如textarea#prompt-textarea)。
  3. 脚本将text内容输入到输入框中。
  4. 脚本模拟点击“发送”按钮(或按下回车键)。
  5. 脚本进入等待状态,持续监测页面变化。它会等待代表“AI正在思考”的动画或元素消失,并等待新的、包含AI回复的消息气泡出现。
  6. 脚本从新消息气泡的DOM元素中提取纯文本内容。
  7. 服务器将该内容封装成JSON响应返回。

GET /retry这个接口用于让AI重新生成上一次提问的回复。它不需要请求体,直接发送GET请求即可。

  • 用途:当你对AI的上一次回复不满意(比如它中断了、胡言乱语了),可以调用此接口让它再试一次。这模拟了点击网页上的“Regenerate response”按钮。
  • 示例调用curl http://localhost:3000/retry

注意事项/queryAi是阻塞式调用。这意味着从发送请求到收到响应,你的程序需要等待整个“输入-等待-输出”流程完成,耗时可能从几秒到几十秒不等,取决于问题的复杂度和AI的响应速度。在设计你的调用程序时,务必考虑超时设置和异步处理。

4.2 会话管理接口:/newChat, /selectChat, /currentChatList

ChatGPT网页版支持多个并行的对话会话。Headless ChatGPT也提供了管理这些会话的接口。

POST /newChat用于开启一个新的聊天会话,并可以选择模型。

  • 请求体{ "model": "GPT-4" }model字段的值必须是/currentGptList接口返回的列表中的字符串,例如"GPT-3.5""GPT-4", 或者是某个自定义GPT的名称。为了兼容,也接受"3""4"
  • 作用:调用此接口后,浏览器会点击“New chat”按钮,并如果指定了模型,还会切换到对应的模型。这对于隔离不同主题的对话或切换模型进行测试非常有用。

POST /selectChat用于切换到侧边栏历史记录中的一个已有聊天。

  • 请求体{ "chatName": "之前聊天的标题" }chatName必须与/currentChatList返回的列表中的某个标题完全匹配。
  • 用途:实现对话历史的回溯和继续。你可以先获取列表,然后选择其中一个进行续聊。

GET /currentChatList获取侧边栏当前已加载的所有历史聊天标题列表。

  • 响应:一个字符串数组,如["Python学习", "旅行计划", "故事构思"]
  • 注意:ChatGPT的侧边栏默认只加载一部分最近的历史记录。要加载更早的记录,需要手动滚动或调用/loadMoreChats接口。

实战场景:假设你正在构建一个自动化测试框架,需要针对同一个问题用GPT-3.5和GPT-4分别生成答案进行比较。你可以这样设计流程:

  1. 调用/newChatmodel设为"GPT-3.5", 然后调用/queryAi提问,保存结果。
  2. 再次调用/newChatmodel设为"GPT-4", 使用相同的提问文本调用/queryAi,保存结果。
  3. 最后,你可以再调用/selectChat回到GPT-3.5的对话,继续深入提问。

4.3 浏览器控制与DOM操作接口

这类接口提供了更底层的浏览器控制能力,让你可以执行自定义的页面操作,灵活性极高,但需要对前端技术和ChatGPT页面结构有一定了解。

POST /typeInElem & POST /select这两个接口允许你向页面上的任何元素输入文本或点击它。

  • /typeInElem:请求体为{ "selector": "#some-input", "string": "hello" }, 会在匹配#some-input选择器的元素中输入“hello”。
  • /select:请求体为{ "selector": "button[aria-label='Send']" }, 会点击发送按钮。
  • 应用:你可以用它们实现官方API未封装的操作。例如,如果ChatGPT推出了一个新的“附件上传”按钮,你可以先通过浏览器开发者工具找到这个按钮的选择器,然后通过/select接口来模拟点击它,再结合文件选择操作(这通常更复杂,可能需要input[type='file']的赋值)。

POST /getInnerHtml 与 /getInnerHtmlOfLast用于获取特定元素的HTML内容。这在你想获取AI回复的富文本格式(而不仅仅是纯文本),或者需要检查页面某个特定区域的状态时非常有用。

  • 区别/getInnerHtml获取匹配选择器的第一个元素的HTML;/getInnerHtmlOfLast获取匹配选择器的最后一个元素的HTML。在聊天场景中,最后一个匹配.message类的元素很可能就是AI的最新回复。

GET /visit这是一个通用接口,用于让浏览器导航到任意URL。curl "http://localhost:3000/visit?url=https://example.com"。虽然主要用途是访问ChatGPT,但在调试或扩展功能时,可以用于访问其他相关页面。

5. 常见问题排查与实战经验分享

在实际使用Headless ChatGPT的过程中,你几乎一定会遇到各种问题。下面我总结了一份从部署到调用各个阶段可能遇到的“坑”及其解决方案,这些是纯官方文档不会告诉你的实战经验。

5.1 部署与启动阶段问题

问题1:Puppeteer无法下载或启动Chromium。

  • 表现:运行node node_modules/puppeteer/install.js时网络超时,或启动服务器时报错Failed to launch the browser process!
  • 排查与解决
    1. 网络问题:这是最常见的原因。可以尝试设置npm镜像和Puppeteer下载镜像。
      # 设置npm镜像(如淘宝源) npm config set registry https://registry.npmmirror.com # 设置Puppeteer跳过Chromium下载(之后手动指定) export PUPPETEER_SKIP_DOWNLOAD=true npm install # 然后手动下载Chromium,或使用系统中已安装的Chrome
    2. 手动指定浏览器路径:如果你系统已有Chrome/Chromium,可以在启动服务器的代码中,修改Puppeteer的启动参数,指定executablePath为你本地浏览器的路径。
    3. 依赖缺失:在Linux系统上,Puppeteer可能需要一些额外的系统库。可以尝试安装常见依赖:
      # Ubuntu/Debian sudo apt-get install -y ca-certificates fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 lsb-release wget xdg-utils

问题2:浏览器启动后,无法自动登录或登录后页面状态不对。

  • 表现:浏览器打开了,但卡在登录页面,或者登录后一堆弹窗没关,导致后续API调用失败(找不到输入框等元素)。
  • 排查与解决
    1. 首次手动干预:正如之前强调的,第一次运行务必使用有头模式,并手动完成所有登录和初始弹窗关闭操作。确保浏览器最终停留在干净的聊天主界面。
    2. 复用用户数据:为了后续自动登录,可以配置Puppeteer使用一个持久的用户数据目录(User Data Directory)。这样,Cookie和本地存储信息会被保存,下次启动时可能无需再次登录。在启动脚本中查找puppeteer.launch的调用,添加userDataDir: './user_data'参数。但请注意,这可能会带来账户安全风险,请仅在可信环境中使用。
    3. 检查选择器:如果登录成功但API仍报错“找不到元素”,很可能是ChatGPT前端更新了UI,导致项目代码中的CSS选择器失效。你需要打开浏览器开发者工具(F12),手动检查当前页面中输入框、按钮等元素的实际选择器,并与项目源码(通常是server.js或其引用的模块)中的选择器进行对比、修改。

5.2 API调用与运行时问题

问题3:调用/queryAi后长时间无响应或超时。

  • 表现:请求发出后,一直等待,最终可能返回超时错误,或者根本收不到响应。
  • 排查与解决
    1. 前端页面卡住:首先直接观察浏览器窗口(如果是有头模式)。看看AI是否在正常生成回复?有没有出现“网络错误”、“发生错误,请重试”等红色提示?有时ChatGPT服务器端会出错,导致前端卡住。手动在浏览器里点一下“重试”或刷新页面可能解决。
    2. 脚本等待逻辑缺陷:这是更常见的原因。Puppeteer脚本在等待AI回复时,依赖特定的页面元素变化作为“回复完成”的信号。如果OpenAI更新了前端,这个信号元素可能变了,脚本就会永远等下去。你需要:
      • 查看服务器终端的日志输出,看它卡在哪一步。
      • 修改源码中的等待逻辑。例如,将page.waitForSelector(‘.some-streaming-class’)改为等待包含最终回复文本的容器元素,或者采用超时+轮询检查的方式。
    3. 网络或服务器负载:你的网络延迟过高,或ChatGPT服务器响应极慢,也可能导致超时。可以考虑在调用端增加合理的超时时间(如120秒),并对超时情况进行重试或降级处理。

问题4:返回的回复内容不完整或包含多余HTML标签。

  • 表现:API返回了文本,但只有前半句,或者夹杂着<div><p>等标签。
  • 排查与解决
    1. 提取逻辑过早:脚本可能在AI还在流式输出(Streaming)过程中就尝试提取文本,此时只拿到了已生成的部分。确保脚本的等待条件是“流式输出结束”,通常可以等待代表“正在输入”的动画或特定类名消失。
    2. 提取了错误的元素:脚本可能定位到了包含富文本格式的父元素,而不是纯文本节点。需要调整选择器,或者在使用element.innerText属性提取后,再进行一些字符串清理工作(如替换多余的换行、空格)。
    3. 源码调整:找到负责提取回复文本的函数(可能在server.js中搜索responseinnerHtml),修改其DOM选择器和文本处理方法。一个更稳健的方法是:先等待最终的回复消息容器出现,然后使用page.evaluate()方法在浏览器上下文中执行JavaScript,精确地提取所需文本。

问题5:频繁使用后出现“验证”或“访问被拒绝”页面。

  • 表现:浏览器中突然跳转到一个要求验证你是人类的页面(如Cloudflare挑战),或者直接显示“Access Denied”。
  • 排查与解决
    • 行为像机器人:Puppeteer的自动化特征(如固定的输入速度、无鼠标移动)容易被网站的反机器人系统检测到。这是使用此类工具的最大风险。
    • 缓解措施
      1. 降低频率:在请求之间增加随机延迟(如3-10秒),模拟人类打字和思考的间隔。
      2. 模拟人类行为:在Puppeteer脚本中注入随机鼠标移动、滚动等操作。有一些库如puppeteer-extra-plugin-stealth可以帮您隐藏Puppeteer的自动化特征。
      3. 使用真实浏览器配置文件:如前所述,使用userDataDir并让这个浏览器实例也进行一些正常的人类浏览活动,可能有助于建立“可信”的浏览器指纹。
      4. 接受现实:如果验证频繁出现,可能意味着当前IP或账户行为已被标记。最根本的解决方法是遵守ChatGPT的使用条款,不要进行高频、自动化的滥用行为。这个项目更适合用于低频、个人或研究用途的自动化。

5.3 进阶维护与扩展建议

当你基本跑通项目后,可能会考虑将其用于更严肃的场景,这时就需要考虑健壮性和扩展性。

日志与监控:务必为你的服务器添加详细的日志记录。记录每一次API调用、Puppeteer操作的成功与失败,以及错误信息。这将是出现问题后排查的第一手资料。你可以使用console.log,但更推荐使用winstonpino这样的日志库。

错误处理与重试机制:在你的调用客户端(即使用Headless ChatGPT API的程序)中,不要假设每次调用都会成功。实现一个健壮的重试机制。例如,如果调用/queryAi超时或返回非预期错误,可以等待几秒后重试(最多2-3次)。对于登录失效这类错误,可能需要设计一个“重启流程”,自动调用/close/start,并引导至登录页面(尽管自动登录很难)。

容器化部署:如果你需要在服务器上长期运行,考虑使用Docker容器化。可以基于Node.js官方镜像,将项目代码、依赖和启动脚本打包进去。这能解决环境一致性问题,并方便部署和迁移。在Dockerfile中,你需要处理Chromium在容器内的安装和运行权限问题(通常需要添加--no-sandbox等启动参数)。

参与贡献:正如项目作者所说,这是一个可以轻松添加新功能的项目。如果你修复了一个bug,或者为新的ChatGPT UI更新了元素选择器,非常鼓励你向原GitHub仓库提交Pull Request。在贡献之前,仔细阅读项目的代码结构,确保你的修改不会破坏现有功能,并添加相应的测试(如果项目有测试框架的话)。

http://www.jsqmd.com/news/789053/

相关文章:

  • 别再搞混了!QGIS 3.20+ 和 3.18 之前版本安装Python库的正确姿势(附版本区别详解)
  • 军种战役学考研辅导班推荐:专门针对性培训机构评测 - michalwang
  • Adobe-GenP 3.0终极指南:3步解锁Adobe全家桶完整功能的免费方案
  • 3分钟搞定!Blender 3MF插件终极指南:让3D打印文件转换变得如此简单
  • AI工具搭建自动化视频生成Wipster
  • 2026瑞祥商联卡回收平台实测口碑榜:TOP3安全高效平台推荐 - 京顺回收
  • FPGA硬件视角:拆解IOBUF原语,看一根引脚如何分时扮演输入和输出
  • MySQL导入SQL文件报错1046?详解“No database selected”的根源与一键修复
  • AI助力京剧:Gemini3.1Pro修复失传剧本
  • 【Unity × Steam】从零到一:成就系统集成与多语言适配实战
  • 2026年AI时代论文收藏教程:从查重率修罗场到一键降重、降AI率 - 降AI实验室
  • ​回顾凯旋广州公司成功挂牌!大力推动内地企业借注册澳门公司出海 - GrowthUME
  • 基于Streamlit与Gemini API构建轻量级AI代码生成与对话工具
  • 如何用免费离线OCR软件轻松提取图片文字?Umi-OCR全功能指南
  • 构建智能分诊与供应链协同平台:从规则引擎到数据总线的实战指南
  • 佛山手表回收避坑指南:这5类套路要当心,附5家正规门店 - 奢侈品回收测评
  • 5分钟搞定:Scroll Reverser终极配置指南 - 彻底解决macOS滚动方向混乱问题
  • 告别D-Bus臃肿:在嵌入式Linux上用BlueZ MGMT接口实现轻量级BLE从设备
  • 深度解析SMUDebugTool:AMD Ryzen处理器底层硬件调试架构剖析
  • 浙南公立医美优选:温州市中心医院百里坊院区,叶英海主任医师匠心塑美 - GrowthUME
  • 基于MCP协议构建AI钱包助手:安全架构与Claude集成实践
  • 什么是体视荧光显微镜 - 实了个验
  • 军事教育训练学考研辅导班推荐:专门针对性培训机构评测 - michalwang
  • 基于Three.js与生物信号的情绪可视化:开源项目Open Vibe Island技术解析
  • PHP接入Bing AI:非官方库实现聊天与图像生成功能详解
  • 西安婚纱照实探18家精选10家|双强口碑领先,其余各有取舍 - 江湖评测
  • 水产养殖考研辅导班推荐:专门针对性培训机构评测 - michalwang
  • 戴尔G15散热控制神器:3步告别AWCC卡顿,开启极速散热新时代
  • agentmemory:解决编码代理记忆难题,多特性优势显著,还支持多方面扩展与开发
  • 如何快速掌握NPYViewer:面向新手的NumPy数组可视化完整实战指南