破冰——建立我们的AI开发实验环境

从零到一,10分钟搭建我们的第一个 AI 对话应用!

前置知识

在本篇开始之前,我们可能需要具备以下知识:

  • 会写基础的 JavaScript/node.js代码(能看懂 async/await 即可)
  • 了解环境变量的概念(不知道也没关系,跟着做就行)

万事开头难

现在处于AI发展风口期,部分人可能会觉得:这个东西好高大上,我不会...。其实任何一件事,只要开始做了,就一定能成!

第一步:注册 DeepSeek API 账号

本文以 DeepSeek 为例,实现注册我们自己的 API 账号。

为什么选 DeepSeek?

  • 国内出品,注册简单,不需要魔法
  • 价格便宜,对新手小白和开发者都比较友好
  • 社区活跃

注册步骤

  1. 打开 DeepSeek 开放平台
  2. 手机号注册
  3. 进入控制台,选择"API Keys",创建 API Key
  4. 复制 API Key!复制 API Key!复制 API Key!

这里一定要注意:为了防止 API Key 被泄漏,所有 API Key 只有在创建的时候才可以复制! 这里一定要注意:为了防止 API Key 被泄漏,所有 API Key 只有在创建的时候才可以复制! 这里一定要注意:为了防止 API Key 被泄漏,所有 API Key 只有在创建的时候才可以复制! 从上述截图中可以看到,保存之后的 API Key只有开头和结尾几个字母,中间是一大串 * ;如果创建时没保存,那么这个 API Key 只能删除重建了!

第二步:项目初始化- 创建Node.js项目

创建项目

我虽然是 Vue 开发者,但我们的第一个实验,还是用最简单的 Node.js 脚本跑通,排除前端复杂度的干扰:

bash 复制代码
# 创建项目文件夹
mkdir AiAgentLearning
cd AiAgentLearning

# 初始化npm项目
npm init -y

# 安装依赖
npm install dotenv

创建.env文件 - 存放 API Key

在项目根目录创建 .env 文件,由于我个人习惯,我是倾向把 API Key 和 请求 URL 放在一起的,方便后续成套修改:

bash 复制代码
DEEPSEEK_API_KEY=你自己的key
DEEPSEEK_BASE_URL=完整请求url

创建.gitignore - 防止 API Key 误上传

bash 复制代码
.env
node_modules

对于需要上传 GIT 的同学来说,还是得先建 .gitignore 再写代码,以免 API Key 泄漏,比较现在爬虫还是挺多的!!! 当然,如果不用上传 GIT,此步骤可以省略!

验证环境变量

一切完成之后我们可以先验证自己的环境变量是否设置成功:

typescript 复制代码
require('dotenv').config()
console.log('API Key前5位:', process.env.DEEPSEEK_API_KEY?.substring(0, 5))

如果能看到 API Key 的前几位正常打印输出就说明成功了!

第一个非流式请求 - 先跑通

前期不用追求太完美,先跑通一个最简单的非流式调用,建立信心。

创建 simple-request.js

javascript 复制代码
require('dotenv').config()

async function callDeepSeek() {
  try {
    const response = await fetch(process.env.DEEPSEEK_BASE_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${process.env.DEEPSEEK_API_KEY}`
      },
      body: JSON.stringify({
        model: 'deepseek-chat',
        messages: [
          { role: 'user', content: 'hello' }
        ],
        stream: false  // 非流式
      })
    })

    const data = await response.json()
    console.log('AI回复:')
    console.log(data.choices[0].message.content)
  } catch (error) {
    console.error('请求失败:', error)
  }
}

callDeepSeek()

如果一切顺利,我们就会看到 AI 的回复,这就成功调用了一次 API:

这只是问答示例,除了 hello ,也可以输入任何我们想输入的内容!在收到回复之前,这个过程可能要等几秒钟。

实现流式问答

为什么需要流式?

模式 体验 适用场景
非流式 等待5-10秒,然后一次性看到全部内容 后台批处理、代码生成
流式 像打字机一样逐字出现,用户体验好 聊天机器人、实时交互

核心区别:流式回答用 stream: true,数据是分块(chunk)返回的。

创建stream-request.js - 第一个流式问答

javascript 复制代码
require('dotenv').config()

async function streamChat() {
  try {
    const response = await fetch(process.env.DEEPSEEK_BASE_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${process.env.DEEPSEEK_API_KEY}`
      },
      body: JSON.stringify({
        model: 'deepseek-chat',
        messages: [
          { role: 'system', content: '你是一个前端开发助手' },
          { role: 'user', content: '解释一下Vue3的ref和reactive的区别,用生活类比' }
        ],
        stream: true  // 关键:开启流式
      })
    })

    // 处理流式响应
    const reader = response.body.getReader()
    const decoder = new TextDecoder('utf-8')
    
    let buffer = ''  // 用于处理可能的不完整数据块
    
    console.log('AI回复:\n')
    
    while (true) {
      const { done, value } = await reader.read()
      if (done) break
      
      // 解码收到的数据块
      const chunk = decoder.decode(value)
      buffer += chunk
      
      // SSE格式是以\n\n分隔的
      const lines = buffer.split('\n\n')
      buffer = lines.pop() || ''  // 最后一行可能不完整,留到下次处理
      
      for (const line of lines) {
        if (line.startsWith('data: ')) {
          const data = line.slice(6)  // 去掉 'data: ' 前缀
          
          // 跳过 [DONE] 消息
          if (data === '[DONE]') continue
          
          try {
            const parsed = JSON.parse(data)
            const content = parsed.choices[0]?.delta?.content || ''
            if (content) {
              process.stdout.write(content)  // 逐字打印,不换行
            }
          } catch (e) {
            // 忽略解析错误(有时会有空行)
          }
        }
      }
    }
    
    console.log('\n\n 流式响应完成')
  } catch (error) {
    console.error('请求失败:', error)
  }
}

streamChat()

如果一切顺利,我们就会看到 AI 的回复: 这个过程基本不需要我们等多久,就有结果开始输出了!而且流式版本就像打字机一样,逐个字符输出,用户体验好太多了。

深入理解 Token

什么是 Token

Token 是 AI 模型处理文本的基本单位,可以简单理解为:

  • 英文:1个单词 ≈ 1-2 个 token
  • 中文:1个汉字 ≈ 1-2 个 token
  • 标点符号:也算 token

举个例子:

"我爱编程"可能被切分为:["我", "爱", "编", "程"] 或 ["我爱", "编程"],大概是 8 个 token。我们向 AI 提问,AI 再返回给我们结果,这中间的所有过程,都是需要计算 token 的!

Token 计费示例

以 DeepSeek 的计价为例:

项目 价格
百万tokens输入(缓存命中) 0.2元
百万tokens输入(缓存未命中) 2元
百万tokens输出 3元

我们写一个简单点的问答,大概消耗:

  • 问题:20-50 tokens
  • 回答:100-500 tokens

总成本:约 0.00005 元(5分钱能玩100次!)

token 使用注意事项

  • 提示器和问题不要太复杂,精简系统提示
  • 控制回复长度,限制最大输出长度
  • 控制创造性,创造性越高越耗token

结语

技术的门槛往往不在技术本身,而在于我们是否愿意迈出第一步,希望这篇文章能帮我们跨过这个坎!

对于文章中错误的地方或有任何疑问,欢迎在评论区留言讨论!

相关推荐
HelloReader2 小时前
Flutter 自适应布局一套代码适配手机和平板(十二)
前端
牛奶2 小时前
HTTP裸奔,HTTPS穿盔甲——它们有什么区别?
前端·http·https
梓言2 小时前
tailwindcss构建执行npm exec tailwindcss init -p 报错
前端
哈罗哈皮2 小时前
龙虾(openclaw)本地快速安装及使用教程
前端·aigc·ai编程
用户23115444530582 小时前
React中实现“双向绑定”效果的几种方式
前端
HelloReader2 小时前
Flutter Sliver 高级滚动打造 iOS 通讯录体验(十三)
前端
a1117762 小时前
程序化几何背景生成器(html 开源)
前端·开源·html
浮笙若有梦2 小时前
我开源了一个比 Ant Design Table 更好用的高性能虚拟表格
前端·vue.js
一只程序熊3 小时前
vite-cool-unix-ctx] Unexpected token l in JSON at position 0
java·服务器·前端