加入华为开发者学堂班级链接:https://developer.huawei.com/consumer/cn/training/classDetail/1a9e0218ec0b4fc9934c0675fbe9da61?type=1?ha_source=hmosclass&ha_sourceId=89000248

| 本文将带你从零开始在鸿蒙应用中集成DeepSeek AI,实现一个智能对话功能。通过完整的代码示例和详细讲解,掌握鸿蒙网络请求的核心技术。

前言:AI赋能鸿蒙应用

随着AI技术的普及,越来越多的应用需要集成智能对话功能。DeepSeek作为一款强大的AI模型,提供了便捷的API接口。本文将手把手教你如何在鸿蒙应用中调用DeepSeek API,打造智能对话体验。

一、项目准备与环境搭建

1.1 创建鸿蒙项目

首先,确保你已经安装了DevEco Studio,然后创建一个新的ArkTS项目:

1.2 获取DeepSeek API Key

访问DeepSeek官网(https://platform.deepseek.com/)注册账号并获取API Key:

  1. 注册/登录DeepSeek平台

  2. 进入API Keys管理页面

  3. 创建新的API Key

  4. 复制生成的Key(格式:sk-xxxxxxxxxxxxxxxx

⚠️ 重要提示:实际开发中请勿在代码中硬编码API Key,建议使用环境变量或配置文件。

二、核心代码解析

下面是完整的鸿蒙ArkTS代码,实现了DeepSeek API的调用:

import { http } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
struct DeepSeekChatApp {
  @State userInput: string = '';
  @State aiResponse: string = '';
  @State isLoading: boolean = false;
  @State chatHistory: Array<{ role: string, content: string }> = [];
  
  // 网络请求配置
  private readonly API_URL: string = 'https://api.deepseek.com/chat/completions';
  private readonly API_KEY: string = 'your_api_key_here'; // 请替换为你的实际API Key
  
  // 发送请求到DeepSeek API
  sendToDeepSeek() {
    // 输入验证
    if (!this.userInput.trim()) {
      this.showToast('请输入问题内容');
      return;
    }
    
    // 显示加载状态
    this.isLoading = true;
    this.aiResponse = '思考中...';
    
    // 将用户输入添加到历史记录
    this.chatHistory.push({
      role: 'user',
      content: this.userInput
    });
    
    // 创建HTTP请求实例
    let httpRequest = http.createHttp();
    
    // 构建请求数据
    const requestData = {
      "messages": this.chatHistory,
      "model": "deepseek-chat",
      "frequency_penalty": 0,
      "max_tokens": 2048,
      "presence_penalty": 0,
      "response_format": {
        "type": "text"
      },
      "stop": null,
      "stream": false,
      "temperature": 0.7, // 调整创造性程度
      "top_p": 1,
      "tools": null,
      "tool_choice": "none",
      "logprobs": false,
      "top_logprobs": null
    };
    
    // 发送请求
    httpRequest.request(
      this.API_URL,
      {
        method: http.RequestMethod.POST,
        header: {
          "Content-Type": "application/json",
          "Authorization": `Bearer ${this.API_KEY}`
        },
        extraData: JSON.stringify(requestData),
        connectTimeout: 60000,
        readTimeout: 60000
      },
      (err: BusinessError, data: http.HttpResponse) => {
        // 请求完成,更新UI状态
        this.isLoading = false;
        
        if (!err) {
          // 成功处理
          this.handleSuccessResponse(data);
        } else {
          // 错误处理
          this.handleErrorResponse(err);
        }
        
        // 销毁请求实例
        httpRequest.destroy();
      }
    );
  }
  
  // 处理成功响应
  private handleSuccessResponse(data: http.HttpResponse) {
    try {
      const response = JSON.parse(data.result.toString());
      
      if (response.choices && response.choices.length > 0) {
        const aiMessage = response.choices[0].message.content;
        this.aiResponse = aiMessage;
        
        // 将AI回复添加到历史记录
        this.chatHistory.push({
          role: 'assistant',
          content: aiMessage
        });
        
        // 限制历史记录长度,避免token过多
        if (this.chatHistory.length > 10) {
          this.chatHistory = this.chatHistory.slice(-10);
        }
        
        this.showToast('回复成功');
      } else {
        this.aiResponse = '未收到有效回复';
        this.showToast('API返回格式异常');
      }
    } catch (parseError) {
      this.aiResponse = '解析响应数据失败';
      this.showToast('数据解析错误');
    }
  }
  
  // 处理错误响应
  private handleErrorResponse(err: BusinessError) {
    let errorMessage = '请求失败';
    
    if (err.code === 401) {
      errorMessage = 'API Key无效或过期';
    } else if (err.code === 429) {
      errorMessage = '请求过于频繁,请稍后再试';
    } else if (err.code === 500) {
      errorMessage = '服务器内部错误';
    } else {
      errorMessage = `错误代码: ${err.code}, 信息: ${err.message}`;
    }
    
    this.aiResponse = errorMessage;
    this.showToast(errorMessage);
  }
  
  // 显示Toast提示
  private showToast(message: string) {
    promptAction.showToast({
      message: message,
      duration: 2000
    });
  }
  
  // 清空对话
  clearChat() {
    this.chatHistory = [];
    this.userInput = '';
    this.aiResponse = '';
    this.showToast('对话已清空');
  }
  
  // 复制AI回复
  copyResponse() {
    // 这里可以添加复制到剪贴板的逻辑
    this.showToast('复制成功');
  }
  
  build() {
    Column({ space: 20 }) {
      // 标题
      Text('DeepSeek智能助手')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 30 })
      
      // 对话历史显示区域
      Scroll() {
        Column({ space: 15 }) {
          ForEach(this.chatHistory, (message, index) => {
            if (message.role === 'user') {
              // 用户消息
              Column({ space: 5 }) {
                Text('你:')
                  .fontSize(14)
                  .fontColor(Color.Gray)
                  .align(Alignment.Start)
                  .width('100%')
                
                Text(message.content)
                  .fontSize(16)
                  .padding(10)
                  .backgroundColor('#E3F2FD')
                  .borderRadius(10)
                  .width('80%')
                  .align(Alignment.End)
                  .margin({ left: '20%' })
              }
            } else {
              // AI消息
              Column({ space: 5 }) {
                Text('AI助手:')
                  .fontSize(14)
                  .fontColor(Color.Gray)
                  .align(Alignment.Start)
                  .width('100%')
                
                Text(message.content)
                  .fontSize(16)
                  .padding(10)
                  .backgroundColor('#F5F5F5')
                  .borderRadius(10)
                  .width('80%')
                  .align(Alignment.Start)
              }
            }
          }, (item, index) => index.toString())
        }
        .padding(15)
      }
      .height('60%')
      .width('100%')
      .backgroundColor(Color.White)
      .borderRadius(15)
      .margin({ left: 15, right: 15 })
      
      // AI回复显示区域(当前回复)
      if (this.isLoading) {
        Text(this.aiResponse)
          .fontSize(16)
          .padding(15)
          .backgroundColor('#FFF3E0')
          .borderRadius(10)
          .width('90%')
          .margin({ top: 10, bottom: 10 })
      } else if (this.aiResponse && this.chatHistory.length === 0) {
        Text(this.aiResponse)
          .fontSize(16)
          .padding(15)
          .backgroundColor('#E8F5E9')
          .borderRadius(10)
          .width('90%')
          .margin({ top: 10, bottom: 10 })
      }
      
      // 输入区域
      Column({ space: 10 }) {
        TextInput({ placeholder: '请输入您的问题...' })
          .width('100%')
          .height(50)
          .fontSize(16)
          .border({ width: 1, color: '#CCCCCC' })
          .borderRadius(8)
          .padding(10)
          .onChange((value: string) => {
            this.userInput = value;
          })
          .onSubmit(() => {
            if (this.userInput.trim()) {
              this.sendToDeepSeek();
            }
          })
        
        // 按钮区域
        Row({ space: 15 }) {
          Button('发送')
            .width('40%')
            .height(45)
            .fontSize(16)
            .backgroundColor('#2196F3')
            .fontColor(Color.White)
            .enabled(!this.isLoading && !!this.userInput.trim())
            .onClick(() => {
              this.sendToDeepSeek();
            })
          
          Button('清空')
            .width('40%')
            .height(45)
            .fontSize(16)
            .backgroundColor('#FF9800')
            .fontColor(Color.White)
            .enabled(!this.isLoading && (this.chatHistory.length > 0 || !!this.userInput))
            .onClick(() => {
              this.clearChat();
            })
        }
        .width('100%')
        .justifyContent(FlexAlign.Center)
      }
      .width('90%')
      .padding(15)
      .backgroundColor(Color.White)
      .borderRadius(15)
      .margin({ bottom: 30 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F0F2F5')
    .justifyContent(FlexAlign.SpaceBetween)
  }
}

三、关键技术点详解

3.1 网络请求模块详解

import { http } from '@kit.NetworkKit';

关键API说明:

  • http.createHttp(): 创建HTTP请求实例

  • http.RequestMethod.POST: 指定请求方法

  • HttpResponse: 响应数据接口

  • BusinessError: 业务错误处理类

3.2 请求头配置

正确的请求头配置是调用API成功的关键:

header: {
  "Content-Type": "application/json",
  "Authorization": `Bearer ${this.API_KEY}`
}

注意事项:

  1. Content-Type必须为application/json

  2. Authorization格式为Bearer {your_api_key}

  3. API Key需要妥善保管,不要提交到版本控制系统

3.3 错误处理机制

// 详细的错误分类处理
private handleErrorResponse(err: BusinessError) {
  if (err.code === 401) {
    // 认证失败
  } else if (err.code === 429) {
    // 限流处理
  } else if (err.code === 500) {
    // 服务器错误
  }
}

四、功能扩展与优化

4.1 流式响应支持

如果需要实现类似ChatGPT的打字机效果,可以使用流式响应:

// 流式响应示例(概念代码)
async function streamResponse() {
  // DeepSeek API支持stream参数
  const requestData = {
    ...otherParams,
    "stream": true,
    "stream_options": {
      "include_usage": true
    }
  };
  
  // 需要处理分块接收的数据
}

4.2 本地存储对话历史

添加本地存储功能,保存对话记录:

import { Preferences } from '@kit.ArkUI';

// 保存对话历史
async function saveChatHistory(history: Array<any>) {
  try {
    await Preferences.getPreferences(this.context)
      .then(preferences => {
        preferences.put('chatHistory', JSON.stringify(history))
          .then(() => {
            console.info('保存成功');
          });
      });
  } catch (error) {
    console.error('保存失败:', error);
  }
}

// 读取对话历史
async function loadChatHistory() {
  try {
    const preferences = await Preferences.getPreferences(this.context);
    const history = await preferences.get('chatHistory', '[]');
    return JSON.parse(history);
  } catch (error) {
    console.error('读取失败:', error);
    return [];
  }
}

4.3 多模型支持

扩展支持DeepSeek的其他模型:

enum AIModel {
  DEEPSEEK_CHAT = 'deepseek-chat',
  DEEPSEEK_CODER = 'deepseek-coder',
  // 其他模型...
}

class AIConfig {
  private model: AIModel = AIModel.DEEPSEEK_CHAT;
  private temperature: number = 0.7;
  private maxTokens: number = 2048;
  
  // 根据用途选择模型
  selectModelForPurpose(purpose: string) {
    switch (purpose) {
      case 'coding':
        this.model = AIModel.DEEPSEEK_CODER;
        this.temperature = 0.3;
        break;
      case 'creative':
        this.model = AIModel.DEEPSEEK_CHAT;
        this.temperature = 0.9;
        break;
      default:
        this.model = AIModel.DEEPSEEK_CHAT;
        this.temperature = 0.7;
    }
  }
}

五、性能优化建议

5.1 请求优化

// 1. 使用连接池
private httpRequestPool: Array<http.HttpRequest> = [];

// 2. 请求去重
private pendingRequests: Map<string, Promise<any>> = new Map();

// 3. 超时设置
connectTimeout: 30000,  // 连接超时
readTimeout: 60000     // 读取超时

5.2 内存管理

// 及时销毁资源
componentWillUnmount() {
  this.httpRequestPool.forEach(request => {
    request.destroy();
  });
  this.httpRequestPool = [];
}

5.3 用户体验优化

  1. 加载状态指示:显示加载动画

  2. 输入防抖:避免频繁请求

  3. 离线提示:网络异常时友好提示

  4. 历史记录:保存对话上下文

六、常见问题与解决方案

问题1:API返回401错误

原因:API Key无效或过期
解决方案

  1. 检查API Key是否正确

  2. 确保有足够的余额

  3. 验证API Key的权限设置

问题2:网络请求超时

原因:网络不稳定或服务器响应慢
解决方案

  1. 增加超时时间设置

  2. 添加重试机制

  3. 优化请求数据大小

问题3:中文响应乱码

原因:编码问题
解决方案

// 确保使用UTF-8编码
const responseText = new TextDecoder('utf-8').decode(data.result);

七、总结与展望

通过本文的学习,你已经掌握了在鸿蒙应用中集成DeepSeek AI的核心技术。关键点总结:

  1. 网络请求基础:掌握鸿蒙的@kit.NetworkKit模块使用

  2. API集成:理解如何调用第三方AI服务

  3. 错误处理:建立完善的错误处理机制

  4. 用户体验:优化界面和交互设计

随着鸿蒙生态的不断发展,AI功能的集成将成为应用开发的重要方向。DeepSeek API提供了强大的AI能力,结合鸿蒙系统的分布式能力,可以打造出更加智能、便捷的应用体验。

未来扩展方向:

  • 语音输入集成

  • 多模态AI支持(图像识别)

  • 本地模型部署

  • 分布式AI计算

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐