引言
在人工智能技术飞速发展的今天,将强大的 AI 能力集成到自己的应用中已成为开发者的一项重要技能。本文将详细记录我从零开始开发一个基于 DeepSeek API 的 AI 助手的完整过程,包括技术选型、环境搭建、接口对接、错误排查以及最终部署的全流程。这个项目不仅让我深入理解了现代 AI 应用的开发模式,也积累了大量宝贵的实战经验。
一、项目规划与技术选型
1.1 需求分析
我计划开发一个能够通过自然语言交互的 AI 助手,核心功能包括:
- 接收用户输入的文本消息
- 调用 DeepSeek 的对话 API 获取智能回复
- 返回格式化的响应给前端界面
- 支持多轮对话上下文
1.2 技术栈选择
经过调研,我确定了以下技术栈:
- 后端:Node.js + TypeScript(Express 框架)
- API 调用:Axios 库
- 配置管理:dotenv 环境变量
- 日志记录:Winston
- 前端:React(后续扩展)
选择 TypeScript 是因为它能提供更好的类型安全,减少运行时错误。Express 作为轻量级框架,非常适合构建这样的 API 服务。
二、开发环境搭建
2.1 初始化项目
首先创建项目目录并初始化 npm:
bash
复制
bash
mkdir ai-assistant && cd ai-assistant
npm init -y
2.2 安装核心依赖
安装生产依赖:
bash
复制
npm install express dotenv axios cors helmet winston
开发依赖:
bash
复制
bash
npm install -D typescript ts-node @types/node @types/express
2.3 配置 TypeScript
创建 tsconfig.json
:
json
复制
json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true
}
}
三、核心功能实现
3.1 环境变量配置
创建 .env
文件:
复制
ini
DEEPSEEK_API_KEY=your_api_key_here
PORT=3000
实现环境变量加载(src/config.ts
):
typescript
复制
arduino
import dotenv from 'dotenv';
import path from 'path';
dotenv.config({
path: path.resolve(__dirname, '../.env')
});
export const config = {
PORT: process.env.PORT || 3000,
DEEPSEEK_API_KEY: process.env.DEEPSEEK_API_KEY
};
3.2 实现 API 路由
创建聊天路由(src/routes/chat.ts
):
typescript
复制
javascript
import { Router } from 'express';
import { chatCompletion } from '../services/aiService';
const router = Router();
router.post('/chat', async (req, res) => {
try {
const { messages } = req.body;
const response = await chatCompletion(messages);
res.json(response);
} catch (error) {
res.status(500).json({ error: 'AI 服务暂不可用' });
}
});
export default router;
3.3 DeepSeek 服务封装
实现 AI 服务(src/services/aiService.ts
):
typescript
复制
typescript
import axios from 'axios';
import { config } from '../config';
export const chatCompletion = async (messages: any[]) => {
const response = await axios.post(
'https://api.deepseek.com/v1/chat/completions',
{
model: 'deepseek-chat',
messages,
temperature: 0.7
},
{
headers: {
'Authorization': `Bearer ${config.DEEPSEEK_API_KEY}`,
'Content-Type': 'application/json'
}
}
);
return response.data.choices[0].message;
};
四、开发过程中的关键挑战
4.1 认证失败问题
在初期测试时,我遇到了 401 Unauthorized
错误。经过排查发现:
-
API Key 未正确加载 :通过添加调试日志发现
.env
文件未被正确读取typescript
复制
arduinoconsole.log('API Key:', process.env.DEEPSEEK_API_KEY);
-
解决方案:
-
确保
.env
文件位于项目根目录 -
在
package.json
中确认启动命令包含dotenv/config
:json
复制
json"scripts": { "start": "node -r dotenv/config dist/app.js" }
-
4.2 请求格式问题
DeepSeek API 对请求格式有严格要求,初期我的请求缺少 model
参数导致失败。修正后的请求体:
typescript
复制
arduino
{
model: 'deepseek-chat', // 必须字段
messages: [...],
temperature: 0.7 // 可选参数
}
4.3 错误处理机制
为了更好的用户体验,我完善了错误处理:
typescript
复制
go
try {
// API 调用
} catch (error) {
if (error.response) {
// DeepSeek 返回的错误
console.error('API Error:', error.response.data);
res.status(error.response.status).json({
error: error.response.data.error?.message
});
} else {
// 网络或其他错误
res.status(500).json({ error: '服务内部错误' });
}
}
五、项目优化与扩展
5.1 添加速率限制
为了防止滥用,增加了速率限制:
typescript
复制
arduino
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: 100 // 每个IP限制100次请求
});
app.use('/api/', limiter);
5.2 实现上下文记忆
通过保存对话历史实现多轮对话:
typescript
复制
ini
const conversationHistory: Message[] = [];
router.post('/chat', async (req, res) => {
const userMessage = req.body.messages[0];
conversationHistory.push(userMessage);
const response = await chatCompletion([
{ role: 'system', content: '你是一个有帮助的助手' },
...conversationHistory
]);
conversationHistory.push(response);
res.json(response);
});
5.3 日志系统集成
使用 Winston 实现结构化日志:
typescript
复制
php
import winston from 'winston';
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),
new winston.transports.File({ filename: 'logs/combined.log' })
]
});
// 使用示例
logger.info('Server started on port 3000');
六、项目部署
6.1 生产环境构建
bash
复制
bash
npm run build # 编译 TypeScript
npm prune --production # 移除开发依赖
6.2 PM2 进程管理
创建 ecosystem.config.js
:
javascript
复制
css
module.exports = {
apps: [{
name: 'ai-assistant',
script: 'dist/app.js',
instances: 'max',
env: {
NODE_ENV: 'production'
}
}]
};
启动服务:
bash
复制
arduino
pm2 start ecosystem.config.js
七、经验总结
通过这个项目,我获得了以下宝贵经验:
- 环境变量管理 :
.env
文件的位置和权限至关重要 - API 集成:必须严格遵循文档要求的请求格式
- 错误处理:完善的错误处理能显著提升调试效率
- 日志系统:生产环境必须有详细的日志记录
- 安全防护:速率限制和输入验证必不可少
这个 AI 助手项目的开发过程让我深刻理解了现代 API 集成应用的完整生命周期。从最初的配置问题到最终的性能优化,每一个挑战都让我成长为更全面的开发者。未来我计划继续扩展功能,如支持文件上传分析、集成更多 AI 模型等,让这个助手变得更加强大和实用。