本文作者:icy

[Delphi] - DeepSeek组件

icy 02-15 1468 抢沙发
[Delphi] - DeepSeek组件摘要: ...

Deepseek_logo.png

Deepseek成立于2023年,提供两种具有自动缓存的语言模型。这项技术在中国开发,受到特定文化和监管框架的影响,决定了其优先事项和发展选择。

虽然Deepseek的应用范围仍在不断发展,但它为希望尝试人工智能工具的Delphi开发人员提供了一个选择。

这个非官方的包装器旨在简化Deepseek API与Delphi项目的集成。

它为开发人员探索和测试这些模型提供了一种实用的方法,无论是用于自然语言处理、会话助手还是其他有针对性的用例。

该库可以在利用Delphi熟悉的环境的同时进行快速实验。

此包装器主要用于探索目的。它为用户提供了一个工具来评估Deepseek是否满足他们的特定需求,并在认为合适的情况下将其整合到他们的项目中。

组件工具简化本教程的工具  

为了简化本教程中提供的代码示例并便于快速实现,源代码中包含了两个单元:Deepseek。辅导的。

VCL和Deepseek。辅导的。FMX`。

根据您选择测试所提供源代码的平台,您需要在应用程序的OnCreate事件中实例化“TVCLTutorialHub”或“TFMXTutorialHub”类,如下所示: 

//uses Deepseek.Tutorial.VCL;
TutorialHub := TVCLTutorialHub.Create(Memo1, Button1);
//uses Deepseek.Tutorial.FMX;
TutorialHub := TFMXTutorialHub.Create(Memo1, Button1);
                  
请确保事先在表单中添加“TMemo”和“TButton”组件。 

“TButton”将允许中断任何流式接收。 

异步回调模式管理

在异步方法的上下文中,对于不涉及流的方法,回调使用以下通用记录:在“Deepseek”中定义的“TAsynCallBack<T>=record”。

异步。支持.pas`单元。此记录公开了以下属性:

   TAsynCallBack<T> = record
   ... 
       Sender: TObject;
       OnStart: TProc<TObject>;
       OnSuccess: TProc<TObject, T>;
       OnError: TProc<TObject, string>;

                  

对于需要流式传输的方法,回调使用通用记录“TAsynStreamCallBack<T>=record”,也在“Deepseek”中定义。异步。支持.pas`单元。此记录公开了以下属性:  

   TAsynCallBack<T> = record
   ... 
       Sender: TObject;
       OnStart: TProc<TObject>;
       OnProgress: TProc<TObject, T>;
       OnSuccess: TProc<TObject, T>;
       OnError: TProc<TObject, string>;
       OnCancellation: TProc<TObject>;
       OnDoCancel: TFunc<Boolean>;
                   

每个名称不言自明;如果需要,请参阅内部文档以了解更多详细信息。  

                       

Deepseek Models Overview

// uses Deepseek, Deepseek.Types, Deepseek.Tutorial.VCL;

  //Asynchronous example
  DeepSeek.Models.AsynList(
    function : TAsynModels
    begin
      Result.Sender := TutorialHub;
      Result.OnStart := Start;
      Result.OnSuccess := Display;
      Result.OnError := Display;
    end);

  //Synchronous example
//  var Value := DeepSeek.Models.List;
//  try
//    Display(TutorialHub, Value);
//  finally
//    Value.Free;
//  end;

要找到一个模型,尽管这并不相关,也没有在官方文件中指定:

// uses Deepseek, Deepseek.Types, Deepseek.Tutorial.VCL;

  TutorialHub.ModelId := 'deepseek-chat';

  //Asynchronous example
  DeepSeek.Models.AsynRetrieve(TutorialHub.ModelId,
    function : TAsynModel
    begin
      Result.Sender := TutorialHub;
      Result.OnStart := Start;
      Result.OnSuccess := Display;
      Result.OnError := Display;
    end);

  //Synchronous example
//  var Value := DeepSeek.Models.Retrieve(TutorialHub.ModelId);
//  try
//    Display(TutorialHub, Value);
//  finally
//    Value.Free;
//  end;



聊天
您可以发送一个仅包含文本内容的结构化输入消息列表,模型将生成对话中的下一条消息。
消息API可用于单回合请求和多回合无状态会话。创建消息

// uses Deepseek, Deepseek.Types, Deepseek.Tutorial.VCL;

  //Asynchronous example
  DeepSeek.Chat.AsynCreate(
    procedure (Params: TChatParams)
    begin
      Params.Model('deepseek-chat');
      Params.Messages([
        FromUser('What is the capital of France, and then the capital of champagne?')
      ]);
    end,
    function : TAsynChat
    begin
      Result.Sender := TutorialHub;
      Result.OnStart := Start;
      Result.OnSuccess := Display;
      Result.OnError := Display;
    end);

  //Synchronous example
//  var Value := DeepSeek.Chat.Create(
//    procedure (Params: TChatParams)
//    begin
//      Params.Model('deepseek-chat');
//      Params.Messages([
//        FromUser('What is the capital of France, and then the capital of champagne?')
//      ]);
//    end);
//  try
//    Display(TutorialHub, Value);
//  finally
//    Value.Free;
//  end;

流媒体消息
在生成消息时,您可以启用“stream”:true,通过服务器发送的事件(SSE)逐步接收响应。

// uses Deepseek, Deepseek.Types, Deepseek.Tutorial.VCL;

  //Asynchronous example
  DeepSeek.Chat.ASynCreateStream(
    procedure (Params: TChatParams)
    begin
      Params.Model('deepseek-chat');
      Params.Messages([
        FromUser('Are there accumulation points in a discrete topology?')
      ]);
      Params.MaxTokens(1024);
      Params.Stream;
    end,
    function : TAsynChatStream
    begin
      Result.Sender := TutorialHub;
      Result.OnStart := Start;
      Result.OnProgress := DisplayStream;
      Result.OnError := Display;
      Result.OnDoCancel := DoCancellation;
      Result.OnCancellation := Cancellation;
    end);

  //Synchronous example
//  DeepSeek.Chat.CreateStream(
//    procedure (Params: TChatParams)
//    begin
//      Params.Model('deepseek-chat');
//      Params.Messages([
//        FromUser('Are there accumulation points in a discrete topology?')
//      ]);
//      Params.MaxTokens(1024);
//      Params.Stream;
//    end,
//    procedure (var Chat: TChat; IsDone: Boolean; var Cancel: Boolean)
//    begin
//      if Assigned(Chat) and not IsDone then
//        DisplayStream(TutorialHub, Chat);
//    end);

多回合对话
“Deepsseek API”能够创建适合用户需求的交互式聊天体验。

它的聊天功能支持多轮问答,允许用户逐步寻求解决方案,或在复杂的多步骤问题上获得帮助。此功能对于需要持续交互的应用程序特别有用,例如:
**聊天机器人**
**教育工具**
**客户支持助理**

// uses Deepseek, Deepseek.Types, Deepseek.Tutorial.VCL;

  //Asynchronous example
  DeepSeek.Chat.ASynCreateStream(
    procedure (Params: TChatParams)
    begin
      Params.Model('deepseek-chat');
      Params.Messages([
        FromSystem('You are a funny domestic assistant.'),
        FromUser('Hello'),
        FromAssistant('Great to meet you. What would you like to know?'),
        FromUser('I have two dogs in my house. How many paws are in my house?')
      ]);
      Params.MaxTokens(1024);
      Params.Stream;
    end,
    function : TAsynChatStream
    begin
      Result.Sender := TutorialHub;
      Result.OnStart := Start;
      Result.OnProgress := DisplayStream;
      Result.OnError := Display;
      Result.OnDoCancel := DoCancellation;
      Result.OnCancellation := Cancellation;
    end);

  //Synchronous example
//  DeepSeek.Chat.CreateStream(
//    procedure (Params: TChatParams)
//    begin
//      Params.Model('deepseek-chat');
//      Params.Messages([
//        FromSystem('You are a funny domestic assistant.'),
//        FromUser('Hello'),
//        FromAssistant('Great to meet you. What would you like to know?'),
//        FromUser('I have two dogs in my house. How many paws are in my house?')
//      ]);
//      Params.MaxTokens(1024);
//      Params.Stream;
//    end,
//    procedure (var Chat: TChat; IsDone: Boolean; var Cancel: Boolean)
//    begin
//      if Assigned(Chat) and not IsDone then
//        DisplayStream(TutorialHub, Chat);
//    end);

Deepseek推理机
自2025年1月25日以来,Deepseek发布了一种名为“Deepseek reasoner”的新模型,旨在提供类似于“OpenAI的O1”模型的高级推理能力。
请参阅[专用页](https://api-docs.deepseek.com/guides/reasoning_model)在官方网站上。
>[!警告]
>**重要提示:**此模型不支持*函数调用、JSON格式的输出或中间填充(FIM)方法*。
**不支持的参数:**
*温度、top_p、存在概率、频率概率、logprobs、top_logprobs*
为了确保与现有软件的兼容性,使用*temperature、top_p、presence_penalty和frequency_penalty*不会触发错误,但对模型没有影响。但是,使用logprobs和top_logprobs会导致错误。
>[!提示]
>可以通过此包装器中提供的API访问此模型。但是,由于其推理方法需要处理时间,建议使用异步方法来防止潜在的应用程序阻塞。

// uses Deepseek, Deepseek.Types, Deepseek.Tutorial.VCL;

  //Asynchronous example
  DeepSeek.Chat.ASynCreateStream(
    procedure (Params: TChatParams)
    begin
      Params.Model('deepseek-reasoner');
      Params.Messages([
        FromUser('What does the ability to reason bring to language models?')
      ]);
      Params.MaxTokens(1024);
      Params.Stream;
    end,
    function : TAsynChatStream
    begin
      Result.Sender := TutorialHub;
      Result.OnStart := Start;
      Result.OnProgress := DisplayStream;
      Result.OnError := Display;
      Result.OnDoCancel := DoCancellation;
      Result.OnCancellation := Cancellation;
    end);
 
函数调用
>[!小心]
>DeepSeek在其[官方文件]中的注释(https://api-docs.deepseek.com/guides/function_calling)
>*“当前版本的deepseek聊天模型的函数调用能力不稳定,这可能会导致循环调用或空响应。我们正在积极进行修复,预计将在下一版本中得到解决。”*
此外,函数调用不能在流请求的上下文中进行。关于API,Delta不支持tool_calls对象。
###使用案例
**巴黎的天气怎么样**
在“Deepseek”中。功能。例如“unit”,有一个类定义了一个函数,“Deepseek”可以根据提供的选项选择是否使用该函数。该类继承自“Deepseek”中定义的父类。功能。核心单元。要创建新函数,您可以从“TFunctionCore类”派生并定义一个新插件。

在本单元中,此模式将用于函数调用。

{
    "type": "object",
    "properties": {
         "location": {
             "type": "string",
             "description": "The city and department, e.g. Marseille, 13"
         },
         "unit": {
             "type": "string",
             "enum": ["celsius", "fahrenheit"]
         }
     },
     "required": ["location"]
  }

我们将使用[`Deepseek.Functions.Example`]中定义的TWeatherReportFunction插件(https://github.com/MaxiDonkey/DelphiDeepseek/blob/main/source/Deepseek.Functions.Example.pas)单位。

  var Weather := TWeatherReportFunction.CreateInstance;
  //See step 3

然后,我们定义了一个方法,使用**天气工具**显示查询的**结果**。

procedure TMy_Form.DisplayWeather(const Value: string);
begin
  //Asynchronous example
  DeepSeek.Chat.ASynCreateStream(
    procedure (Params: TChatParams)
    begin
      Params.Model('deepseek-chat');
      Params.Messages([
        FromSystem('You are a star weather presenter on a national TV channel.'),
        FromUser(Value)
      ]);
      Params.MaxTokens(1024);
      Params.Stream;
    end,
    function : TAsynChatStream
    begin
      Result.Sender := TutorialHub;
      Result.OnProgress := DisplayStream;
      Result.OnError := Display;
      Result.OnDoCancel := DoCancellation;
      Result.OnCancellation := Cancellation;
    end);
end;

使用天气工具构建查询

// uses Deepseek, Deepseek.Types, Deepseek.Functions.Example, Deepseek.Tutorial.VCL;

  var Weather := TWeatherReportFunction.CreateInstance;
  TutorialHub.Tool := Weather;
  TutorialHub.ToolCall := DisplayWeather;

  //Asynchronous example
  DeepSeek.Chat.AsynCreate(
    procedure (Params: TChatParams)
    begin
      Params.Model('deepseek-chat');
      Params.Messages([
        TContentParams.User('What is the weather in Paris?')
      ]);
      Params.Tools([Weather]);
      Params.ToolChoice(auto);
      Params.MaxTokens(1024);
    end,
    function : TAsynChat
    begin
      Result.Sender := TutorialHub;
      Result.OnStart := Start;
      Result.OnSuccess := Display;
      Result.OnError
  end;

JSON输出
在许多情况下,用户要求模型以严格的JSON格式生成输出,以确保结构化数据,促进无缝的下游处理。
DeepSeek提供JSON输出功能,以确保生成有效的JSON字符串。
**关键考虑因素:**
1.**启用JSON输出:**
-将response_format参数设置为“{'type”:“json_object'}”。
-在系统或用户提示中包含单词“json”,并提供所需json格式的示例,以指导模型生成符合要求的输出。
2.**调整输出长度:**
-适当配置max_tokens参数以防止JSON字符串被截断。
3.**处理潜在问题:**
-API可能偶尔会返回空内容。此问题正在积极优化中。调整提示有助于减少此类事件的发生。

// uses Deepseek, Deepseek.Types, Deepseek.Tutorial.VCL;

  //Asynchronous example
  DeepSeek.Chat.AsynCreate(
    procedure (Params: TChatParams)
    begin
      Params.Model('deepseek-chat');
      Params.Messages([
        TContentParams.System('The user will provide some exam text. Please parse the "question" and "answer" and output them in JSON format. EXAMPLE INPUT: Which is the highest mountain in the world? Mount Everest. EXAMPLE JSON OUTPUT: {     "question": "Which is the highest mountain in the world?",     "answer": "Mount Everest" }'),
        TContentParams.User('Which is the longest river in the world? The Nile River')
      ]);
      Params.ResponseFormat(json_object);
    end,
    function : TAsynChat
    begin
      Result.Sender := TutorialHub;
      Result.OnStart := Start;
      Result.OnSuccess := Display;
      Result.OnError := Display;
    end);

  //Synchronous example
//  var Value := DeepSeek.Chat.Create(
//    procedure (Params: TChatParams)
//    begin
//      Params.Model('deepseek-chat');
//      Params.Messages([
//        TContentParams.System('The user will provide some exam text. Please parse the "question" and "answer" and output them in JSON format. EXAMPLE INPUT: Which is the highest mountain in the world? Mount Everest. EXAMPLE JSON OUTPUT: {     "question": "Which is the highest mountain in the world?",     "answer": "Mount Everest" }'),
//        TContentParams.User('Which is the longest river in the world? The Nile River')
//      ]);
//    end);
//  try
//    Display(TutorialHub, Value);
//  finally
//    Value.Free;
//  end;

模型将输出:

{
    "question": "Which is the longest river in the world?",
    "answer": "The Nile River"
}

上下文缓存
请参阅[官方文件](https://api-docs.deepseek.com/guides/kv_cache)
自动执行缓存具有限制生成响应多样性的效果。虽然调整温度参数可以提供一些灵活性,但并非在所有情况下都是最佳解决方案。
此外,用户无法直接干预执行手动“缓存清除”。在这方面,我建议您参考官方文件,其中规定:
-*“缓存构建需要几秒钟。一旦缓存不再使用,它将自动清除,通常在几个小时到几天内。”*
获取用户余额
查看账户详细信息,包括可用信用余额。

// uses Deepseek, Deepseek.Types, Deepseek.Tutorial.VCL;

  //Asynchronous example
  DeepSeek.User.AsynBalance(
    function : TAsynBalance
    begin
      Result.Sender := TutorialHub;
      Result.OnStart := Start;
      Result.OnSuccess := Display;
      Result.OnError := Display;
    end);

  //Synchronous example
//  var Value := DeepSeek.User.Balance;
//  try
//    Display(TutorialHub, Value);
//  finally
//    Value.Free;
//  end;

上下文缓存
请参阅[官方文件](https://api-docs.deepseek.com/guides/kv_cache)
自动执行缓存具有限制生成响应多样性的效果。虽然调整温度参数可以提供一些灵活性,但并非在所有情况下都是最佳解决方案。
此外,用户无法直接干预执行手动“缓存清除”。在这方面,我建议您参考官方文件,其中规定:
-*“缓存构建需要几秒钟。一旦缓存不再使用,它将自动清除,通常在几个小时到几天内。”*

##获取用户余额
查看账户详细信息,包括可用信用余额。

// uses Deepseek, Deepseek.Types, Deepseek.Tutorial.VCL;

  //Asynchronous example
  DeepSeekBeta.FIM.AsynCreate(
    procedure (Params: TFIMParams)
    begin
      Params.Model('deepseek-chat');
      Params.Prompt('def fib(a):');
      Params.Suffix('    return fib(a-1) + fib(a-2)');
      Params.MaxTokens(1024);
    end,
    function : TAsynFIM
    begin
      Result.Sender := TutorialHub;
      Result.OnStart := Start;
      Result.OnSuccess := Display;
      Result.OnError := Display;
    end);

  //Synchronous example
//  var Value := DeepSeekBeta.FIM.Create(
//    procedure (Params: TFIMParams)
//    begin
//      Params.Model('deepseek-chat');
//      Params.Prompt('def fib(a):');
//      Params.Suffix('    return fib(a-1) + fib(a-2)');
//      Params.MaxTokens(1024);
//    end);
//  try
//    Display(TutorialHub, Value);
//  finally
//    Value.Free;
//  end;

模型将输出:

    if a == 0:
        return 0
    elif a == 1:
        return 1
    else:

简化完工流程

// uses Deepseek, Deepseek.Types, Deepseek.Tutorial.VCL;

  //Asynchronous example
  DeepSeekBeta.FIM.AsynCreateStream(
    procedure (Params: TFIMParams)
    begin
      Params.Model('deepseek-chat');
      Params.Prompt('def fib(a):');
      Params.Suffix('  return fib(a-1) + fib(a-2)');
      Params.MaxTokens(1024);
      Params.Stream;
    end,
    function : TAsynFIMStream
    begin
      Result.Sender := TutorialHub;
      Result.OnStart := Start;
      Result.OnProgress := DisplayStream;
      Result.OnError := Display;
      Result.OnDoCancel := DoCancellation;
      Result.OnCancellation := Cancellation;
    end);

  //Synchronous example
//  DeepSeekBeta.FIM.CreateStream(
//    procedure (Params: TFIMParams)
//    begin
//      Params.Model('deepseek-chat');
//      Params.Prompt('def fib(a):');
//      Params.Suffix('  return fib(a-1) + fib(a-2)');
//      Params.MaxTokens(1024);
//      Params.Stream;
//    end,
//    procedure (var FIM: TFIM; IsDone: Boolean; var Cancel: Boolean)
//    begin
//      if Assigned(FIM) and not IsDone then
//        DisplayStream(TutorialHub, FIM);
//    end);

聊天前缀完成
要使用聊天前缀完成功能,用户必须为助手提供消息前缀,使模型能够完成其余的消息。
**重要提示**
使用前缀补全时,必须确保将消息列表中最后一条消息的角色设置为“助理”,并启用此消息的“前缀”参数(设置为“True”)。此外,用户必须配置`base_url=“https://api.deepseek.com/beta“`激活Beta功能。

// uses Deepseek, Deepseek.Types, Deepseek.Tutorial.VCL;

  //Asynchronous example
  DeepSeekBeta.Chat.AsynCreate(
    procedure (Params: TChatParams)
    begin
      Params.Model('deepseek-chat');
      Params.Messages([
        FromUser('Please write quick sort code'),
        FromAssistant('```python\n', True)
      ]);
      Params.Stop('```');
    end,
    function : TAsynChat
    begin
      Result.Sender := TutorialHub;
      Result.OnStart := Start;
      Result.OnSuccess := Display;
      Result.OnError := Display;
    begin
      Params.Model('deepseek-chat');
      Params.Messages([
        FromUser('Please write quick sort code'),
        FromAssistant('```python\n', True)
      ]);
      Params.Stop('```');
    end,
    function : TAsynChat
    begin
      Result.Sender := TutorialHub;
      Result.OnStart := Start;
      Result.OnSuccess := Display;
      Result.OnError := Display;
    end);

The model will output:

# Quick Sort implementation in Python

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)

# Example usage:
arr = [3, 6, 8, 10, 1, 2, 1]
sorted_arr = quick_sort(arr)
print("Sorted array:", sorted_arr)


end);

The model will output:

# Quick Sort implementation in Python

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)

# Example usage:
arr = [3, 6, 8, 10, 1, 2, 1]
sorted_arr = quick_sort(arr)
print("Sorted array:", sorted_arr)


Delphi-Deepseek.zip
类型:压缩文件|已下载:19|下载方式:免费下载
立即下载
文章版权及转载声明

作者:icy本文地址:https://zelig.cn/2025/02/1.html发布于 02-15
文章转载或复制请以超链接形式并注明出处软角落-SoftNook

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

阅读
分享

发表评论

快捷回复:

验证码

评论列表 (暂无评论,1468人围观)参与讨论

还没有评论,来说两句吧...