Delphi与ChatGPT集成指南:打造智能应用
在当今AI快速发展的时代,将ChatGPT等大型语言模型集成到传统应用程序中已成为提升用户体验的重要手段。本文将详细介绍如何在Delphi应用中集成OpenAI的ChatGPT API,实现智能对话和自动化功能。
为什么要在Delphi应用中集成ChatGPT?
将ChatGPT集成到Delphi应用中可以带来以下优势:
- 增强用户交互体验:提供自然语言界面,使用户能够通过对话方式操作应用
- 自动化复杂任务:利用AI处理复杂查询和任务,减轻用户负担
- 提供智能建议和辅助:根据用户行为和输入提供个性化建议
- 扩展应用功能:为传统应用增加现代AI能力,保持竞争力
技术准备
在开始集成之前,你需要准备以下内容:
- OpenAI API密钥:访问OpenAI平台注册并获取API密钥
- Delphi开发环境:建议使用Delphi 10.4或更高版本
- REST客户端组件:可以使用Indy、REST Debugger或TRESTClient组件
- JSON处理库:如System.JSON或其他第三方JSON库
基础实现:ChatGPT API调用
首先,我们创建一个基本的ChatGPT API调用类:
unit ChatGPTClient;
interface
uses
System.SysUtils, System.Classes, System.Net.HttpClient, System.Net.URLClient,
System.JSON, System.Generics.Collections;
type
TChatMessage = record
Role: string;
Content: string;
constructor Create(const ARole, AContent: string);
end;
TChatGPTClient = class
private
FApiKey: string;
FModel: string;
FMessages: TList<TChatMessage>;
FTemperature: Double;
FMaxTokens: Integer;
FHttpClient: THTTPClient;
function BuildRequestBody: TJSONObject;
public
constructor Create(const ApiKey: string);
destructor Destroy; override;
function SendMessage(const UserMessage: string): string;
procedure ClearConversation;
property Model: string read FModel write FModel;
property Temperature: Double read FTemperature write FTemperature;
property MaxTokens: Integer read FMaxTokens write FMaxTokens;
end;
implementation
{ TChatMessage }
constructor TChatMessage.Create(const ARole, AContent: string);
begin
Role := ARole;
Content := AContent;
end;
{ TChatGPTClient }
constructor TChatGPTClient.Create(const ApiKey: string);
begin
inherited Create;
FApiKey := ApiKey;
FModel := 'gpt-3.5-turbo';
FTemperature := 0.7;
FMaxTokens := 1000;
FMessages := TList<TChatMessage>.Create;
FHttpClient := THTTPClient.Create;
end;
destructor TChatGPTClient.Destroy;
begin
FMessages.Free;
FHttpClient.Free;
inherited;
end;
function TChatGPTClient.BuildRequestBody: TJSONObject;
var
RequestObj, MessageObj: TJSONObject;
MessagesArray: TJSONArray;
Message: TChatMessage;
begin
RequestObj := TJSONObject.Create;
MessagesArray := TJSONArray.Create;
try
RequestObj.AddPair('model', FModel);
RequestObj.AddPair('temperature', TJSONNumber.Create(FTemperature));
RequestObj.AddPair('max_tokens', TJSONNumber.Create(FMaxTokens));
for Message in FMessages do
begin
MessageObj := TJSONObject.Create;
MessageObj.AddPair('role', Message.Role);
MessageObj.AddPair('content', Message.Content);
MessagesArray.AddElement(MessageObj);
end;
RequestObj.AddPair('messages', MessagesArray);
Result := RequestObj;
except
RequestObj.Free;
raise;
end;
end;
function TChatGPTClient.SendMessage(const UserMessage: string): string;
var
URL: string;
RequestBody, ResponseObj, ChoicesObj: TJSONObject;
ResponseContent, ResponseText: string;
Response: IHTTPResponse;
ChoicesArray: TJSONArray;
begin
Result := '';
URL := 'https://api.openai.com/v1/chat/completions';
// 添加用户消息到历史
FMessages.Add(TChatMessage.Create('user', UserMessage));
RequestBody := BuildRequestBody;
try
// 设置请求头
FHttpClient.CustomHeaders['Authorization'] := 'Bearer ' + FApiKey;
FHttpClient.CustomHeaders['Content-Type'] := 'application/json';
// 发送请求
Response := FHttpClient.Post(URL, TStringStream.Create(RequestBody.ToJSON), nil);
ResponseContent := Response.ContentAsString;
// 解析响应
if Response.StatusCode = 200 then
begin
ResponseObj := TJSONObject.ParseJSONValue(ResponseContent) as TJSONObject;
try
ChoicesArray := ResponseObj.GetValue('choices') as TJSONArray;
if (ChoicesArray <> nil) and (ChoicesArray.Count > 0) then
begin
ChoicesObj := ChoicesArray.Items[0] as TJSONObject;
ResponseText := (ChoicesObj.GetValue('message') as TJSONObject).GetValue('content').Value;
// 添加AI回复到历史
FMessages.Add(TChatMessage.Create('assistant', ResponseText));
Result := ResponseText;
end;
finally
ResponseObj.Free;
end;
end
else
raise Exception.CreateFmt('API错误: %d - %s', [Response.StatusCode, ResponseContent]);
finally
RequestBody.Free;
end;
end;
procedure TChatGPTClient.ClearConversation;
begin
FMessages.Clear;
end;
end.
创建简单的聊天界面
接下来,我们创建一个简单的聊天界面来测试我们的ChatGPT集成:
unit MainForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls,
ChatGPTClient;
type
TfrmChatGPT = class(TForm)
pnlTop: TPanel;
pnlBottom: TPanel;
memChat: TMemo;
edtMessage: TEdit;
btnSend: TButton;
btnClear: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btnSendClick(Sender: TObject);
procedure btnClearClick(Sender: TObject);
procedure edtMessageKeyPress(Sender: TObject; var Key: Char);
private
FChatGPT: TChatGPTClient;
procedure AddMessageToChat(const Sender, Message: string);
procedure SendUserMessage;
public
{ Public declarations }
end;
var
frmChatGPT: TfrmChatGPT;
implementation
{$R *.dfm}
procedure TfrmChatGPT.FormCreate(Sender: TObject);
const
API_KEY = '你的OpenAI API密钥'; // 替换为你的实际API密钥
begin
FChatGPT := TChatGPTClient.Create(API_KEY);
// 可选:配置ChatGPT参数
FChatGPT.Model := 'gpt-3.5-turbo';
FChatGPT.Temperature := 0.7;
FChatGPT.MaxTokens := 1000;
memChat.Lines.Add('ChatGPT助手已准备就绪。请输入您的问题...');
end;
procedure TfrmChatGPT.FormDestroy(Sender: TObject);
begin
FChatGPT.Free;
end;
procedure TfrmChatGPT.AddMessageToChat(const Sender, Message: string);
begin
memChat.Lines.Add(Format('[%s]: %s', [Sender, Message]));
memChat.Lines.Add('');
end;
procedure TfrmChatGPT.SendUserMessage;
var
UserMessage, AIResponse: string;
begin
UserMessage := edtMessage.Text;
if UserMessage.Trim.IsEmpty then
Exit;
// 显示用户消息
AddMessageToChat('用户', UserMessage);
edtMessage.Clear;
// 禁用发送按钮,显示正在处理
btnSend.Enabled := False;
Application.ProcessMessages;
try
// 发送到ChatGPT并获取响应
Screen.Cursor := crHourGlass;
AIResponse := FChatGPT.SendMessage(UserMessage);
// 显示AI响应
AddMessageToChat('ChatGPT', AIResponse);
except
on E: Exception do
begin
memChat.Lines.Add('错误: ' + E.Message);
memChat.Lines.Add('');
end;
end;
// 恢复UI状态
Screen.Cursor := crDefault;
btnSend.Enabled := True;
edtMessage.SetFocus;
end;
procedure TfrmChatGPT.btnSendClick(Sender: TObject);
begin
SendUserMessage;
end;
procedure TfrmChatGPT.edtMessageKeyPress(Sender: TObject; var Key: Char);
begin
if Key = #13 then // Enter键
begin
Key := #0;
SendUserMessage;
end;
end;
procedure TfrmChatGPT.btnClearClick(Sender: TObject);
begin
memChat.Clear;
FChatGPT.ClearConversation;
memChat.Lines.Add('对话已清除。请输入新的问题...');
end;
end.
高级功能:流式响应
OpenAI API支持流式响应,可以实现打字机效果,提升用户体验。以下是实现流式响应的代码:
// 在ChatGPTClient单元中添加流式响应方法
function TChatGPTClient.SendMessageStreaming(const UserMessage: string;
OnChunk: TProc<string>): string;
var
URL: string;
RequestBody: TJSONObject;
HttpRequest: THTTPRequest;
HttpResponse: THTTPResponse;
ResponseStream: TStringStream;
Line, Content, Delta: string;
JSONObj: TJSONObject;
FullResponse: TStringBuilder;
begin
URL := 'https://api.openai.com/v1/chat/completions';
// 添加用户消息到历史
FMessages.Add(TChatMessage.Create('user', UserMessage));
RequestBody := BuildRequestBody;
RequestBody.AddPair('stream', TJSONBool.Create(True));
FullResponse := TStringBuilder.Create;
ResponseStream := TStringStream.Create('', TEncoding.UTF8);
HttpRequest := THTTPRequest.Create;
HttpResponse := THTTPResponse.Create;
try
// 设置请求
HttpRequest.Client := FHttpClient;
HttpRequest.URL := URL;
HttpRequest.MethodString := 'POST';
HttpRequest.SourceStream := TStringStream.Create(RequestBody.ToJSON);
HttpRequest.SourceStream.Position := 0;
HttpRequest.Headers.Add('Authorization', 'Bearer ' + FApiKey);
HttpRequest.Headers.Add('Content-Type', 'application/json');
// 发送请求并处理流式响应
if HttpRequest.Execute(HttpResponse, ResponseStream) then
begin
ResponseStream.Position := 0;
while not ResponseStream.DataString.IsEmpty do
begin
Line := ResponseStream.DataString;
ResponseStream.Size := 0;
if Line.StartsWith('data: ') then
begin
Content := Line.Substring(6);
if Content = '[DONE]' then
Break;
try
JSONObj := TJSONObject.ParseJSONValue(Content) as TJSONObject;
try
if JSONObj.GetValue('choices') <> nil then
begin
Delta := (((JSONObj.GetValue('choices') as TJSONArray).Items[0] as TJSONObject)
.GetValue('delta') as TJSONObject).GetValue('content').Value;
if not Delta.IsEmpty then
begin
FullResponse.Append(Delta);
if Assigned(OnChunk) then
OnChunk(Delta);
end;
end;
finally
JSONObj.Free;
end;
except
// 忽略解析错误
end;
end;
if not HttpResponse.ConnectionClose then
HttpRequest.Execute(HttpResponse, ResponseStream);
end;
end;
Result := FullResponse.ToString;
// 添加AI回复到历史
if not Result.IsEmpty then
FMessages.Add(TChatMessage.Create('assistant', Result));
finally
FullResponse.Free;
ResponseStream.Free;
HttpRequest.Free;
HttpResponse.Free;
RequestBody.Free;
end;
end;
实际应用案例
1. 智能客服系统
// 在客服系统中集成ChatGPT处理常见问题
procedure TCustomerSupportForm.HandleCustomerQuery(const Query: string);
var
Response: string;
begin
// 首先检查是否是常见问题
if IsCommonQuestion(Query) then
DisplayPredefinedAnswer(Query)
else
begin
// 使用ChatGPT处理复杂问题
Response := FChatGPT.SendMessage(
'你是一个客服助手,请回答以下问题: ' + Query);
DisplayResponse(Response);
end;
end;
2. 代码生成助手
// 使用ChatGPT生成代码片段
procedure TCodeGeneratorForm.GenerateCode;
var
Prompt, GeneratedCode: string;
begin
Prompt := Format(
'请为以下功能生成Delphi代码: %s' + sLineBreak +
'使用的组件: %s' + sLineBreak +
'额外要求: %s',
[edtFeature.Text, edtComponents.Text, memRequirements.Text]
);
GeneratedCode := FChatGPT.SendMessage(Prompt);
// 提取代码块
GeneratedCode := ExtractCodeBlock(GeneratedCode);
// 显示生成的代码
memGeneratedCode.Text := GeneratedCode;
end;
最佳实践与注意事项
- API密钥安全:不要在代码中硬编码API密钥,考虑使用配置文件或环境变量
- 错误处理:实现完善的错误处理机制,处理网络问题和API限制
- 上下文管理:合理管理对话历史,避免超出token限制
- 用户体验:实现流式响应和加载指示器,提升用户体验
- 成本控制:监控API使用情况,实施合理的使用限制
结论
通过将ChatGPT集成到Delphi应用中,我们可以为传统应用注入AI能力,显著提升用户体验和应用功能。随着AI技术的不断发展,这种集成将变得越来越重要,成为现代应用开发的标准实践。
希望本文能帮助你在Delphi应用中成功集成ChatGPT,打造更智能、更有竞争力的应用程序。
关于作者:付乙,资深Delphi开发者,专注于将现代技术与传统应用相结合,提升软件价值和用户体验。