HarmonyOS5/ArkTs 超简单的对接DeepSeekAPI步骤

概述

开通华为云账号——>开通DeepSeek-V3-32K服务——>得到API KEY——>根据URL和KEY发送请求——>解析SSE数据

一、先开通服务

在这里插入图片描述
在这里插入图片描述
如果欠费则充值1块钱即可
在这里插入图片描述
开通后就可以查看调用说明
在这里插入图片描述
这里就可以看到API地址了,然后去生成KEY
在这里插入图片描述
创建KEY随便填,只要描述能一目了然这个KEY是干啥申请来的,再点击确定,此时,不要关闭页面!copy好这个KEY,因为这个KEY只有此时一次机会才能看到明文
在这里插入图片描述
API到这里就结束了

上代码

1,封装调用请求
这里用的harmonyOS5推荐的RPC通信,整体逻辑与HTTP无异。做一个post请求,然后在拦截器干点事儿就没了

// deepSeek的数据和我们平时请求的数据有什么区别
import { rcp } from "@kit.RemoteCommunicationKit"
import { util } from "@kit.ArkTS";
import { logger } from ".";

// 推理模型-一个字一个字在推-记录当前的文本属于哪个上下文
// 接口一口气把所有的结果都给用户

// 拦截器的class实现并继承 rcp.Interceptor
const APIKey = "Mq2__BD-yEN53auAxivaZu2cywgkU_3BkbIedR2PI9eCZAR5rfC9PMIyUMOU46pw46dl00_fP7PQrvb5V6_Oyg"; // APIkey
const url = "https://api.modelarts-maas.com/v1/chat/completions" // 请求url地址


class DeepSeekRcpRequest implements rcp.Interceptor {
  intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
    // 注入token
    context.request.headers!.authorization = `Bearer ${APIKey}`; // 注入apikey
    return next.handle(context)
  }
}

export class DeepSeekRcp {
  session: rcp.Session | null = null // rcp的请求实例对象

  initSession() {
    this.session = rcp.createSession({
      // 配置拦截器
      interceptors: [new DeepSeekRcpRequest()], // 注入token的拦截器
      // 接收二进制数据流
      requestConfiguration: {
        tracing: {
          httpEventsHandler: {
            // 接收数据
            onDataReceive: (bf)=>{
              // SSE数据
              // bf => Json
              // ArrayBuffer => Uint8Array
              const uin8 = new Uint8Array(bf)
              // 解码器 =>
              const decoder = new util.TextDecoder()
              const str = decoder.decodeToString(uin8); // 输出结果
              logger.info(str)  // 
            }
          }
        }
      }
    })
  }

  // 发送问题给deepSeek
  postDeepSeek(data: object) {
    if (!this.session) {
      this.initSession()
    }

    // 发送deepSeek请求 不能立刻渴望得到结果 内容推理 一个字一个字在推
    this.session?.post(url, data);
  }
}

export const deepSeekRcp = new DeepSeekRcp()

UI代码:

// 调用rcp的方法
  sendData() {
    let params: DeepSeekParams = {
      model: 'DeepSeek-V3',
      max_tokens: 1024,
     messages = [
     //整个对话过程分为两个角色,system为deepseeek方,user为客户端方
        {"role": "system", "content": "You are a helpful assistant"},
        {"role": "user", "content": "你好"},
    ],
      stream: true,
      temperature: 1
    }
    deepSeekRcp.postDeepSeek(params);
  }

  build() {
      Column() {
        Button('测试DeepSeek')
          .onClick(()=>{
            this.sendData()
          })
      }
      .width("100%")
      .height("100%")
    }
    .hideTitleBar(true)
}

以上一个简单的测试demo就好了,你可以拿去测一下了哦
2,解析SSE消息

// deepSeek的数据和我们平时请求的数据有什么区别
import { rcp } from "@kit.RemoteCommunicationKit"
import { util } from "@kit.ArkTS";
import { logger } from ".";

// 推理模型-一个字一个字在推-记录当前的文本属于哪个上下文
// 接口一口气把所有的结果都给用户

// 拦截器的class实现并继承 rcp.Interceptor
const APIKey = "Mq2__BD-yEN53auAxivaZu2cywgkU_3BkbIedR2PI9eCZAR5rfC9PMIyUMOU46pw46dl00_fP7PQrvb5V6_Oyg"; // APIkey
const url = "https://api.modelarts-maas.com/v1/chat/completions" // 请求url地址


class DeepSeekRcpRequest implements rcp.Interceptor {
  intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
    // 注入token
    context.request.headers!.authorization = `Bearer ${APIKey}`; // 注入apikey
    return next.handle(context)
  }
}

export class DeepSeekRcp {
  session: rcp.Session | null = null // rcp的请求实例对象

  private textCallBack?: (message: String[], finished: boolean) => void // 不间断调用
  private cacheMessage: Map<String, String[]> = new Map(); // 暂存消息

  initSession() {
    this.session = rcp.createSession({
      // 配置拦截器
      interceptors: [new DeepSeekRcpRequest()], // 注入token的拦截器
      // 接收二进制数据流
      requestConfiguration: {
        tracing: {
          httpEventsHandler: {
            // 接收数据
            onDataReceive: (bf)=>{
              // SSE数据
              // bf => Json
              // ArrayBuffer => Uint8Array
              const uin8 = new Uint8Array(bf)
              // 解码器 =>
              const decoder = new util.TextDecoder()
              const str = decoder.decodeToString(uin8); // 输出结果
              logger.info(str)  
              //********************************************解析开始了哦********************************************//
              // 把消息取出放入数组,你现在看到内容都是一行一行的,所以我们先去掉换行组织称一个数组
              const list = str.split('\n\n')

              // 针对数组的每一条数据处理
              // 把data:截取出
              for(let item of list){
                const dealStr = item.substring(5);
                if (dealStr) {
                  // 1. 把消息转换出来
                  const message = JSON.parse(dealStr) as ChatCompletionChunk

                  // 2. 判断map中是否缓存过同一条消息的部分内容
                  if(!this.cacheMessage.has(message.id)){
                    this.cacheMessage.set(message.id, [])
                  }
                  // 3. 把消息放入缓存
                  const list = this.cacheMessage.get(message.id)
                  message.choices.map(obj => {
                    // logger.info(obj.delta.content, '-----')
                    list?.push(obj.delta.content)
                  })
                  // 4. 判断消息是否结束
                  let isFinished = false
                  if(message.choices[0].finish_reason === 'stop'){
                    // 此时消息结束
                    isFinished = true
                  }
                  // 5. 把消息写入临时缓存
                  this.cacheMessage.set(message.id, list)
                  // 6.把消息回调出去
                  this.textCallBack?.(list, isFinished)
                  // 7. 判断消息是否完成
                  if(isFinished){
                    this.cacheMessage.delete(message.id)
                  }
                }
              }
            }
          }
        }
      }
    })
  }

  // 发送问题给deepSeek
  postDeepSeek(data: object, callback?: (message: String[], finished: boolean) => void) {
    if (!this.session) {
      this.initSession()
    }

    // 方便上面方法调用该回调函数
    this.textCallBack = callback

    // 发送deepSeek请求 不能立刻渴望得到结果 内容推理 一个字一个字在推
    this.session?.post(url, data);
  }
}
export const deepSeekRcp = new DeepSeekRcp()

UI修改

// 调用rcp的方法
  sendData() {
    let params: DeepSeekParams = {
      model: 'DeepSeek-V3',
      max_tokens: 1024,
     messages = [
     //整个对话过程分为两个角色,system为deepseeek方,user为客户端方
        {"role": "system", "content": "You are a helpful assistant"},
        {"role": "user", "content": "你好"},
    ],
      stream: true,
      temperature: 1
    }
    deepSeekRcp.postDeepSeek(params, (cacheMessage, finished) => {
    this.response = cacheMessage.join("");
    if (finished) {
      AlertDialog.show({ message: "消息发完了" });
    }
  });
  }

  build() {
      Column() {
        Button('测试DeepSeek')
          .onClick(()=>{
            this.sendData()
          })
      }
      .width("100%")
      .height("100%")
    }
    .hideTitleBar(true)
}

看懂了啵,鼓励一个一键三连叭,一起创建harmonyOS5的生态环境叭

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值