1. 项目概述:从零开始,构建你的第一个AI对话应用

最近几年,AI对话模型已经从实验室里的尖端科技,变成了开发者工具箱里的“瑞士军刀”。无论是想做个智能客服原型,还是给自己的产品加个聊天机器人,或者单纯想体验一下大语言模型的魔力,ChatGPT这类API都成了首选。但很多刚接触的朋友,面对API文档、密钥管理、代码调用这些环节,常常感觉无从下手,被一堆技术术语和配置细节劝退。

“aiplaybookin/novice-ChatGPT”这个项目,就像一位经验丰富的向导,它的核心目标非常明确: 手把手地带一个完全的新手,用最清晰、最直接的方式,跑通从申请API到完成一次完整对话调用的全流程 。它不追求构建一个多么复杂、功能齐全的应用,而是聚焦于那个从0到1的“第一次成功调用”。这个“第一次”至关重要,它能帮你建立起最基础的信心和认知框架,让你知道“哦,原来整个过程是这样的”,后续无论是增加功能、优化交互还是集成到其他系统,都有了坚实的起点。

这个项目非常适合以下几类朋友: 对AI应用开发充满好奇但不知如何入门的编程新手 有一定开发经验,但从未调用过OpenAI这类云端AI API的开发者 产品经理或运营同学,想快速验证一个AI对话点子是否可行 。如果你属于其中任何一类,那么跟着这个“新手剧本”走一遍,将会是最高效的启动方式。

2. 核心思路拆解:为什么“极简”是最好的起点

当我们决定要学习使用ChatGPT API时,市面上有无数种教程和开源项目。有的教你搭建带Web界面的聊天室,有的教你实现上下文记忆,还有的教你做联网搜索。这些当然都很棒,但对于一个纯粹的新手来说,信息过载反而是最大的敌人。 “novice-ChatGPT”项目选择了一条截然不同的路径:做减法,做极致的减法。

它的设计哲学是“单点突破”。想象一下,你要学开车,教练不会第一天就让你上高速,而是先教你认识方向盘、刹车和油门,然后让你在空旷的场地直线前进、后退。这个项目做的就是这件事——它把“调用ChatGPT API”这个复杂任务,拆解成了几个不可再分的基础动作,并确保你每一个动作都能独立完成且理解其意义。

2.1 环境隔离:为实验创造安全沙箱

很多新手会犯的一个错误是,直接在重要的项目目录或者全局环境里安装各种包,一旦版本冲突或者操作失误,可能影响其他工作。这个项目通常的第一步,就是引导你创建一个独立的Python虚拟环境。这不是多此一举,而是一个非常重要的工程习惯。

提示:虚拟环境就像一个独立的“工作间”。在这个工作间里,你安装的Python包只在这里生效,不会和你电脑上其他项目的包混在一起。这样,你可以大胆尝试不同版本的库,而不用担心把系统环境搞乱。

使用 venv 或者 conda 创建虚拟环境,然后激活它,这短短两行命令,是你迈向规范开发的第一步。它背后的逻辑是 隔离与可复现性 。确保你的代码在任何一台新电脑上,只要重建这个环境,就能一模一样地运行起来。

2.2 依赖最小化:只安装必需的“武器”

项目不会让你安装一个庞大的、包含几十个依赖的“全家桶”。它的 requirements.txt 文件(或类似的依赖说明)会非常精简,核心通常只有两个库: openai python-dotenv

  • openai :这是官方提供的Python SDK,是对HTTP API的一层友好封装。你不用自己去拼凑HTTP请求头、处理JSON解析,这个库提供了像 openai.ChatCompletion.create() 这样直观的函数。
  • python-dotenv :这是一个管理环境变量的神器。你的API密钥(Key)是最高机密,绝对不能直接硬编码在代码文件里,然后上传到GitHub(这会导致密钥泄露,造成财产损失)。 dotenv 库让你可以把密钥写在一个单独的 .env 文件中,代码运行时从这个文件读取。 .env 文件本身会被添加到 .gitignore 中,确保安全。

这种最小依赖的设计,减少了安装出错的可能,也让你能更清晰地理解每个库所承担的角色。

2.3 配置先行:安全地保管你的“钥匙”

在写第一行调用代码之前,项目会花重要篇幅教你如何获取和配置API Key。这步看似简单,却埋着最多的“坑”。

首先,你需要去OpenAI的官网注册账号并创建API Key。这里有个关键点: OpenAI提供的免费额度(通常有5美元)是有有效期的 ,一般是三个月。很多新手拿到Key后不急着用,等想起来的时候发现额度已经过期了,所以创建后最好尽快开始实验。

创建Key后,项目会教你创建 .env 文件,内容类似:

OPENAI_API_KEY=sk-你的真实密钥内容

然后在Python代码中,通过 dotenv.load_dotenv() 加载,再通过 os.getenv(“OPENAI_API_KEY”) 来获取。这个过程强化了一个关键的安全理念: 密钥与代码分离

2.4 调用逻辑:理解“对话”的格式

这是最核心的部分。ChatGPT的API调用,本质上是向云端发送一个结构化的请求(Request),然后接收一个结构化的回复(Response)。对于新手,项目会聚焦于最基础的“单轮对话”模型。

请求的核心是一个 messages 列表,列表里的每个元素都是一个字典,代表对话中的一条消息。每条消息必须有 role (角色)和 content (内容)两个字段。角色通常有三种:

  • system : 设定AI助手的背景和行为指令(例如:“你是一个乐于助人的翻译助手”)。
  • user : 代表用户输入的问题或指令。
  • assistant : 代表AI助手之前的回复(在多轮对话中用于提供上下文)。

一个最简单的新手调用示例,可能就是只包含一条 user 消息。项目会带你写出类似下面的代码,并解释每个参数:

import openai
import os
from dotenv import load_dotenv

load_dotenv()  # 加载.env文件中的环境变量
openai.api_key = os.getenv(“OPENAI_API_KEY”) # 设置API密钥

response = openai.ChatCompletion.create(
    model=“gpt-3.5-turbo”,  # 指定使用的模型
    messages=[
        {“role”: “user”, “content”: “请用一句话介绍你自己。”}
    ],
    temperature=0.7,  # 控制回复的随机性
    max_tokens=150     # 控制回复的最大长度
)

# 提取AI的回复内容
answer = response.choices[0].message.content
print(answer)

项目会带你一行行理解这段代码: model 怎么选(新手用 gpt-3.5-turbo 性价比高), temperature 是什么(值越高回答越随机创意,越低越稳定),如何从返回的 response 这个复杂对象里,像剥洋葱一样找到最终的文本内容( response.choices[0].message.content )。

2.5 结果验证:看到“Hello, AI World”

最后,运行脚本。当你在终端看到AI返回的第一句自我介绍时,整个“新手剧本”就圆满落幕了。这个瞬间,你完成了一个完整的闭环:环境准备 -> 密钥配置 -> 编写请求 -> 发送调用 -> 解析结果。你获得的不仅仅是一段回复文本,更是一个 可复现、可扩展的最小可行流程

这个极简思路的高明之处在于,它把认知负担降到了最低。你不需要同时理解Web框架、前端渲染、会话状态管理。你只需要集中精力,理解“如何用代码和AI对话”这一件事。掌握了这件事,你就拥有了打开AI应用开发大门的钥匙。

3. 关键步骤详解与避坑指南

按照“novice-ChatGPT”的指引一步步操作,看似顺理成章,但几乎每个环节都有一些“魔鬼细节”。这些细节教程里不一定都会强调,却直接关系到你的成功率和后续体验。下面我结合自己的实操经验,把这些关键步骤再掰开揉碎,并附上必须注意的避坑点。

3.1 虚拟环境:选对工具,事半功倍

创建虚拟环境是第一步,但Python环境管理本身就有多个工具。 venv 是Python 3.3+内置的,最通用; conda 则更擅长管理复杂的科学计算环境,包更全。

  • 对于纯新手,我强烈推荐使用 venv 。因为它无需额外安装,且概念更简单。
    # 在你的项目目录下执行
    python -m venv venv
    
    这行命令会在当前目录创建一个名为 venv 的文件夹,里面就是独立的Python环境。接下来激活它:
    • Windows (PowerShell): .\venv\Scripts\Activate.ps1
    • macOS/Linux: source venv/bin/activate 激活后,你的命令行提示符前通常会显示 (venv) ,表示你已经在这个“工作间”里了。

注意:在Windows PowerShell上执行激活脚本时,可能会遇到执行策略限制的错误。这是因为PowerShell默认禁止运行脚本。你可以用管理员身份打开PowerShell,执行 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser 来临时解决,或者更简单点,在VSCode等编辑器里使用集成的终端,它通常已经处理好了这些问题。

3.2 安装依赖:警惕版本“玄学”

在激活的虚拟环境中,使用 pip install -r requirements.txt 安装依赖。这里最大的坑是 库的版本 。OpenAI的API和其Python库都在快速迭代,可能你看到的教程用的是老版本的调用方式(比如 openai.Completion.create ),而新版本已经变为了 openai.ChatCompletion.create

  • 避坑技巧 :在写 requirements.txt 时,最好指定相对稳定的版本,而不是直接用 openai 。例如:
    openai>=0.27.0, <1.0.0
    python-dotenv>=0.19.0
    
    这样可以避免因库的重大升级(比如从0.x升级到1.x)导致的代码不兼容。安装后,可以用 pip list 命令确认安装的版本。

3.3 API密钥管理:安全是头等大事

.env 文件是本地开发的黄金标准,但有几个细节必须注意:

  1. 立即将 .env 加入 .gitignore :在你创建 .env 文件的第一时间,就确保它在Git的忽略列表里。你可以创建一个 .gitignore 文件,里面写一行 .env 。这是防止密钥意外提交到代码仓库的最后一道防线。
  2. .env 文件的格式 :键值对之间等号两边最好不要有空格。虽然有些解析器能容忍,但保持 KEY=VALUE 的格式是最稳妥的。
  3. 不要将 .env 文件通过任何即时通讯工具发送 。即使是私聊,也存在泄露风险。如果需要分享项目,只分享代码和 requirements.txt ,密钥由协作者自行配置。

3.4 编写第一个调用:参数里的学问

让我们再仔细看看那个最简单的调用代码,里面有几个参数值得深入理解:

  • model 参数 :对于新手, gpt-3.5-turbo 是完美的起点。它速度快、成本低(约为 gpt-4 的1/10到1/20)、能力足够应对大多数对话场景。在初期实验阶段,完全没必要使用更贵的 gpt-4
  • temperature 参数 :这是控制生成文本“创造性”的核心旋钮。取值范围是0到2。
    • temperature=0 :输出确定性最高,相同的输入几乎总是得到相同的输出。适合需要稳定、事实性答案的场景,比如分类、提取。
    • temperature=0.7 :一个常用的平衡值,输出有一定变化,既不死板也不至于太天马行空。
    • temperature>1 :输出会非常随机、有创意,甚至可能不连贯。新手建议在0.5到0.9之间尝试。
  • max_tokens 参数 :这个参数限制了AI单次回复的最大长度(1个token约等于0.75个英文单词或半个汉字)。 它并不是设得越大越好 。设置过大,一方面可能产生不必要的费用(因为API按输入+输出的总token数计费),另一方面如果AI的回复其实很短,它也可能“没话找话”凑字数。对于简单的问答,设为150-300通常足够。你需要根据对话的复杂程度来调整。

3.5 运行与调试:看懂错误信息

点击运行,最激动人心也最紧张的时刻来了。如果一切顺利,你会看到回复。但更常见的情况是,新手会遇到各种错误。

  • AuthenticationError (认证错误) :这几乎100%是API Key的问题。检查:1) .env 文件里的Key是否正确(有没有多余的空格、换行);2) 是否在代码中正确加载了 .env 文件;3) 这个Key是否还有额度、是否已被禁用。
  • RateLimitError (频率限制错误) :免费用户或新账号有每分钟请求次数的限制。别着急,等一分钟再试就好。这是平台防止滥用的正常机制。
  • APIConnectionError (连接错误) :可能是网络问题,特别是如果你的网络环境比较复杂。可以尝试检查网络连通性。
  • InvalidRequestError (无效请求错误) :这通常是请求参数格式错了。比如 messages 列表的格式不对,或者 max_tokens 设得比模型允许的最小值还小。 仔细阅读错误信息 ,OpenAI的API错误信息通常很详细,会直接告诉你哪个字段有问题。

当你第一次成功打印出AI的回复时,我建议你不要立刻进行下一步。多尝试几次,修改一下 temperature ,问不同的问题,感受参数变化对结果的影响。这个试错的过程,是你建立对模型行为“直觉”的宝贵机会。

4. 从成功调用到实际应用:扩展你的第一个脚本

成功实现单次调用,就像学会了骑自行车保持平衡。接下来,我们要让它能载着我们想去的地方。原始的“新手剧本”可能到此为止,但一个真正可用的脚本还需要一些实用的增强。下面我们来为这个基础脚本添加几个关键功能,让它从一个实验片段,变成一个可以反复使用的小工具。

4.1 添加持续对话循环

一个不能连续说话的聊天机器人显然是不完整的。我们可以用一个简单的 while 循环来实现。

import openai
import os
from dotenv import load_dotenv

load_dotenv()
openai.api_key = os.getenv(“OPENAI_API_KEY”)

# 初始化对话历史。我们可以从一个系统指令开始,让AI扮演特定角色。
conversation_history = [
    {“role”: “system”, “content”: “你是一个知识渊博且幽默的助手。请用简洁易懂的方式回答用户的问题。”}
]

print(“你好!我是你的AI助手。输入‘退出’或‘quit’来结束对话。”)
while True:
    # 获取用户输入
    user_input = input(“\n你: “)
    if user_input.lower() in [“退出”, “quit”, “exit”]:
        print(“再见!”)
        break

    # 将用户输入添加到对话历史
    conversation_history.append({“role”: “user”, “content”: user_input})

    try:
        # 调用API,这次传入的是整个对话历史
        response = openai.ChatCompletion.create(
            model=“gpt-3.5-turbo”,
            messages=conversation_history,  # 关键变化:发送全部历史
            temperature=0.7,
            max_tokens=300
        )

        # 获取AI回复
        ai_reply = response.choices[0].message.content
        print(f“AI: {ai_reply}”)

        # 将AI回复也添加到对话历史,以便下一轮对话保持上下文
        conversation_history.append({“role”: “assistant”, “content”: ai_reply})

    except openai.error.RateLimitError:
        print(“请求过于频繁,请稍后再试。”)
    except openai.error.APIConnectionError:
        print(“网络连接错误,请检查你的网络。”)
    except Exception as e:
        print(f“发生未知错误: {e}”)

这个改进带来了几个重要概念:

  1. 对话历史 ( conversation_history ) :我们用一个列表在内存中维护了整个对话。每一轮,我们都把新的用户消息和AI回复追加进去。这样,下一次请求时,AI就能看到之前所有的对话内容,从而实现有记忆的连续对话。
  2. 系统指令 ( system role) :我们在对话历史开头插入了一条 system 消息。这是“调教”AI行为的有力工具。你可以在这里定义它的身份(“你是一个资深程序员”)、风格(“回答请严谨且带有代码示例”)或规则(“不要回答与医疗相关的问题”)。
  3. 简单的错误处理 ( try…except ) :我们捕获了最常见的两种API错误(频率限制和网络问题),并给出了友好的用户提示,而不是让程序直接崩溃。

4.2 控制上下文长度与成本

上面的循环有一个潜在问题:对话会一直进行下去, conversation_history 列表会越来越长。而API调用是按发送的 总token数(输入+输出) 计费的。一段很长的对话历史,不仅会增加每次调用的成本,还可能超过模型本身的上下文长度限制(例如 gpt-3.5-turbo 的上下文窗口是4096个token)。

因此,一个健壮的对话脚本需要具备 上下文窗口管理 能力。一个简单的策略是“滑动窗口”:只保留最近N轮对话。

def manage_conversation_history(history, max_rounds=10):
    “”“管理对话历史,只保留最近的若干轮对话。
    同时,我们通常希望保留最初的system指令。”“”
    # 确保system指令始终在开头
    system_message = [msg for msg in history if msg[“role”] == “system”]
    other_messages = [msg for msg in history if msg[“role”] != “system”]

    # 只保留最近的 max_rounds*2 条消息(因为一轮包含user和assistant两条)
    recent_messages = other_messages[-(max_rounds * 2):]

    # 重新组合
    return system_message + recent_messages

# 在每一轮对话结束后,可以调用这个函数来修剪历史
# conversation_history = manage_conversation_history(conversation_history, max_rounds=5)

这个 manage_conversation_history 函数会确保 system 指令不被丢弃,同时只保留最近10轮(可配置)的实际对话。这是一种在成本、效果和上下文长度之间的平衡。

4.3 为对话增加一点“个性”

除了在 system 指令中设定角色,我们还可以通过参数微调对话体验。例如, presence_penalty frequency_penalty 这两个参数可以用来控制回复的多样性。

  • presence_penalty (存在惩罚,-2.0 到 2.0) :正值会惩罚模型谈论到目前为止已经出现过的主题,从而鼓励它引入新话题。如果你希望对话不要老在一个地方打转,可以适当调高这个值(如0.5)。
  • frequency_penalty (频率惩罚,-2.0 到 2.0) :正值会惩罚模型重复使用相同的词语。如果你觉得AI的用词有些重复,可以调高这个值。

这些参数比较微妙,对新手来说, temperature 是首要调节的,这两个可以暂时使用默认值(通常是0)。当你对基础调用驾轻就熟后,再尝试它们来精细控制输出风格。

4.4 将脚本模块化

当代码越来越多,最好将其整理成函数,提高可读性和可复用性。例如,我们可以把调用API的部分封装成一个函数:

def chat_with_gpt(messages, model=“gpt-3.5-turbo”, temp=0.7, max_tokens=300):
    “”“发送消息到ChatGPT并返回回复。
    参数:
        messages: 完整的消息历史列表
        model: 使用的模型
        temp: temperature参数
        max_tokens: 回复最大长度
    返回:
        ai_reply (str): AI的回复文本
        full_response (obj): 完整的API响应对象(用于调试)
    ”“”
    try:
        response = openai.ChatCompletion.create(
            model=model,
            messages=messages,
            temperature=temp,
            max_tokens=max_tokens
        )
        ai_reply = response.choices[0].message.content
        return ai_reply, response
    except openai.error.OpenAIError as e:
        # 这里可以更精细地处理不同类型的OpenAI错误
        print(f“调用API时出错: {e}”)
        return None, None

这样,主循环会变得非常清晰:

while True:
    user_input = input(“\n你: “)
    if user_input.lower() in [“退出”, “quit”]:
        break

    conversation_history.append({“role”: “user”, “content”: user_input})

    ai_reply, _ = chat_with_gpt(conversation_history)

    if ai_reply:
        print(f“AI: {ai_reply}”)
        conversation_history.append({“role”: “assistant”, “content”: ai_reply})
        # 可选:在这里管理历史长度
        # conversation_history = manage_conversation_history(conversation_history)

通过以上这些扩展,你的脚本已经从一个一次性实验,进化成了一个具备基础对话能力、有简单错误处理、并初步考虑了成本和上下文管理的可复用工具。这个过程本身,就是学习如何将一个最小可行产品(MVP)迭代成更实用工具的最佳实践。

5. 常见问题排查与进阶思考

即使按照指南一步步操作,在实际动手过程中,你依然可能会遇到一些令人困惑的问题。下面我整理了几个最常见的问题场景、排查思路以及解决后可以进行的进阶思考。

5.1 问题一:一切代码正确,但返回 ‘choices’ 为空或内容奇怪

  • 现象 :调用成功(没有报错), response 对象也有,但 response.choices[0].message.content 是空字符串,或者内容不是预期的对话回复。
  • 排查思路
    1. 首先,打印完整的 response 对象 。在调用后直接 print(response) 。你会看到一个庞大的JSON结构。检查 response[‘choices’] 这个列表是否为空。如果为空,说明API执行了请求,但模型没有生成任何内容(这很罕见)。
    2. 检查 finish_reason 字段 。在 response.choices[0] 里,有一个 finish_reason 字段。如果它的值是 “length” ,意味着生成的回复因为达到了你设置的 max_tokens 限制而被截断了。这时你需要增大 max_tokens 的值。
    3. 检查 system 指令是否过于严格或矛盾 。如果你设定了 system 消息,比如“你只回答是或否”,那么对于开放性问题,模型可能会困惑而生成空内容或无关内容。尝试暂时移除或简化 system 指令进行测试。
    4. 检查 temperature 是否设置为0且输入完全相同 。如果 temperature=0 ,对于相同的输入,模型会输出概率最高的结果。但如果你的输入非常模糊或模型认为没有唯一高概率答案,它也可能输出奇怪的内容。

5.2 问题二:对话进行几轮后,AI“失忆”或回答质量下降

  • 现象 :刚开始对话很顺畅,但聊了十几轮后,AI似乎忘记了之前约定的内容,或者回答变得敷衍、重复。
  • 原因与解决
    • 主要原因 :上下文窗口被填满。正如前面提到的,模型有token数限制。当对话历史的总长度接近这个限制时,模型无法有效处理所有信息,性能会下降。最古老的对话内容会被“挤出”上下文窗口。
    • 解决方案 :实施 上下文窗口管理策略 。除了前面提到的“滑动窗口”法,还有更智能的方法:
      • 总结压缩 :当历史记录过长时,可以调用一次AI,让它自己总结之前的对话要点,然后用这个总结替换掉大部分旧历史,只保留最近几轮详细对话。这需要额外的API调用,但能更有效地保留长期记忆。
      • 关键信息提取 :对于重要的用户信息(如名字、偏好),可以手动提取出来,始终放在 system 指令或对话开头。
    • 实操建议 :对于 gpt-3.5-turbo ,将对话轮次限制在10-15轮以内通常是比较安全的。你可以实时计算token数(使用OpenAI的 tiktoken 库),但作为新手,先用轮次限制是一个简单有效的起点。

5.3 问题三:响应速度慢,或者经常遇到 RateLimitError

  • 现象 :等待回复时间很长,或者频繁看到“Rate limit reached”的错误。
  • 排查与优化
    1. 确认网络环境 :API服务器在海外,网络延迟是影响速度的首要因素。使用网络工具测试到 api.openai.com 的连通性和延迟。
    2. 理解速率限制 :免费用户和按量付费用户的速率限制不同。错误信息里通常会提示 requests per min (每分钟请求数)和 tokens per min (每分钟token数)。你触达的是哪一个限制?
    3. 实施重试与退避机制 :在代码中添加简单的重试逻辑是生产环境应用的基本功。不要一遇到限流就报错退出,可以等待一段时间后重试。
      import time
      from openai.error import RateLimitError
      
      def chat_with_retry(messages, max_retries=3):
          for i in range(max_retries):
              try:
                  return chat_with_gpt(messages)  # 使用前面封装好的函数
              except RateLimitError:
                  if i < max_retries - 1:
                      wait_time = (i + 1) * 5  # 退避等待,例如5秒,10秒,15秒
                      print(f“达到速率限制,等待{wait_time}秒后重试…”)
                      time.sleep(wait_time)
                  else:
                      raise  # 重试多次后仍然失败,抛出异常
      
    4. 优化请求内容 :避免在每次请求中发送过长的、不变的历史记录。做好上下文管理,本身就是减少token消耗、从而降低触发token速率限制概率的最佳方法。

5.4 问题四:如何估算使用成本?

对于个人开发者和小项目,成本控制很重要。OpenAI API按token计费, gpt-3.5-turbo 的价格非常低廉(例如每1000个token只需几美分),但心里有数总是好的。

  1. 计算token数量 :最准确的方式是使用OpenAI官方库 tiktoken 。你可以用它来统计一段文本或整个 messages 列表的token数。
    import tiktoken
    encoding = tiktoken.encoding_for_model(“gpt-3.5-turbo”)
    text = “你好,世界!”
    token_count = len(encoding.encode(text))
    print(f”文本的token数: {token_count}“)
    
    将输入和输出的token数相加,再乘以单价,就是单次调用的成本。
  2. 在OpenAI控制台设置预算警报 :在OpenAI官网的账户设置里,你可以设置每月预算和使用量硬限制。这是防止意外超额消费的最有效手段。
  3. 心理估算 :一个简单的估算方法是:对于中英文混合场景,可以粗略认为 1个token ≈ 0.75个英文单词 ≈ 0.5个汉字 。一次简单的问答(输入100字,输出200字),大约在200-300个token左右,成本几乎可以忽略不计。

当你成功解决了上述问题,并能让你的脚本稳定运行后,你的学习就可以进入下一个阶段了。你可以思考:如何为这个对话机器人增加一个图形界面(使用 gradio streamlit 可以快速实现)?如何将它集成到你的网站或微信公众号里?如何利用它来处理特定领域的任务,比如总结长文章、润色邮件、或者分析数据?这时,“novice-ChatGPT”项目作为入门基石的任务就圆满完成了,它已经为你铺好了通往更广阔AI应用开发世界的第一段路。

更多推荐