참고 자료
Delphi로 구축된 샘플 ChatGPT 프로젝트를 소개합니다.
ChatGPT에서 제공하는 개방형 API를 통해 Delphi로 ChatGPT 앱을 쉽게 구축할 수 있습니다. 최근에는 한국어로 질문에 답하는 것이 가능해 번역기를 사용하지 않고도 한국어로 질문하고 한국어로 답할 수 있다.
welcome.devgear.co.kr
한국어로 질문하면 한국어로 답변이 되지만 속도가 느려서 파파고를 이용해서 영어로 번역한 후 물어보고 답을 다시 한국어로 번역해보세요.
파파고 레퍼런스
REST 클라이언트 활용법 네이버 파파고(번역 서비스) OPEN API 이용 안내
네이버에서 제공하는 다양한 OPEN API 중에서 많이 사용하는 파파고 번역 서비스의 사용법을 소개합니다. 사용 환경은 Rad Studio 11과 post-call 방식입니다. REST API를 사용하는 방법을 알고 있다면 다른 많은 일을 할 수 있습니다.
welcome.devgear.co.kr
한국어 질문 -> Paparo API 번역 -> ChatGPT -> 영어 답변 -> Papago API 번역 -> 한국어 답변
나는 이렇게했다.
unit uMainCGPT;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, System.JSON,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Memo.Types, FMX.StdCtrls, FMX.Controls.Presentation, FMX.ScrollBox,
FMX.Memo, System.Net.URLClient, System.Net.HttpClient, System.Net.HttpClientComponent, FMX.Layouts, System.Diagnostics
;
type
TfMain = class(TForm)
Memo_Ans: TMemo;
Memo_HanQ: TMemo;
BT_Question: TButton;
NetHTTPClient: TNetHTTPClient;
NetHTTPRequest: TNetHTTPRequest;
Layout1: TLayout;
Layout2: TLayout;
Layout3: TLayout;
Layout4: TLayout;
Layout5: TLayout;
SpeedButton1: TSpeedButton;
NetHTTPClientPaPaGo: TNetHTTPClient;
NetHTTPRequestPaPaGo: TNetHTTPRequest;
btnPaPaGo: TButton;
StyleBook1: TStyleBook;
SpeedButton2: TSpeedButton;
ckbTrans: TCheckBox;
procedure BT_QuestionClick(Sender: TObject);
procedure NetHTTPClientRequestCompleted(const Sender: TObject; const AResponse: IHTTPResponse);
procedure Memo_HanQDblClick(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure btnPaPaGoClick(Sender: TObject);
procedure NetHTTPRequestPaPaGoRequestCompleted(const Sender: TObject;
const AResponse: IHTTPResponse);
procedure NetHTTPRequestRequestCompleted(const Sender: TObject;
const AResponse: IHTTPResponse);
procedure SpeedButton2Click(Sender: TObject);
private
function Response_To_GetPapagoData(rData: string): string;
procedure PaPaGoTrans(nString, nSource, nTarget: string);
procedure Delay(ms: Integer);
{ Private declarations }
public
{ Public declarations }
end;
var
fMain: TfMain;
_PapagoAns, _GPTAns : string; // 파파고 번역후 받은 메세지, GPT 답변
_PapagoAnsAll : string; // 계속 대화를 더해 나간다.
_Time_out : integer;
// ChatGPT 개인키 받는곳 : https://beta.openai.com/account/api-keys
Const MyGPTKey = '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'; // 발급 받은 개인키를 이곳에 할당
implementation
{$R *.fmx}
procedure TfMain.Delay(ms: Integer);
var
StopWatch: TStopWatch;
begin
StopWatch := TStopWatch.Create;
StopWatch.Start;
repeat
Application.ProcessMessages;
Sleep(1);
until StopWatch.ElapsedMilliseconds >= ms;
end;
procedure TfMain.Memo_HanQDblClick(Sender: TObject);
begin
Memo_HanQ.Lines.Clear;
end;
// 질문 하기 *********************************************
procedure TfMain.btnPaPaGoClick(Sender: TObject);
begin
// AndroidTTS1.Speak('I am good');
exit;
_PapagoAns := '';
PaPaGoTrans(Memo_HanQ.Text, 'ko','en');
_Time_out := 0;
repeat
if _Time_out > 500 then exit;
inc(_Time_out);
delay(10);
until _PapagoAns <> '' ;
if _PapagoAns <> '' then begin
Memo_HanQ.Text := _PapagoAns;
_PapagoAns := '';
end;
end;
procedure TfMain.PaPaGoTrans(nString, nSource, nTarget : string);
var
sParam : TStringList;
sURL : string;
begin
sURL := 'https://openapi.naver.com/v1/papago/n2mt';
NetHTTPClientPaPaGo.Accept := 'application/json';
NetHTTPClientPaPaGo.ContentType := 'application/x-www-form-urlencoded; charset=UTF-8;';
NetHTTPClientPaPaGo.AcceptCharSet := 'UTF-8';
NetHTTPClientPaPaGo.CustomHeaders('X-Naver-Client-Id') := 'kOlZPHwk8XGvcO99TYyV'; // 애플리케이션 등록 시 발급받은 클라이언트 아이디 값
NetHTTPClientPaPaGo.CustomHeaders('X-Naver-Client-Secret') := 'WXSzJpfcVi'; // 애플리케이션 등록 시 발급받은 클라이언트 시크릿 값
sParam := TStringList.Create;
sParam.Add( 'source=" + nSource );
sParam.Add( "target=" + nTarget );
sParam.Add( "text=" + nString );
NetHTTPRequestPaPaGo.Post( sURL, sParam ) ;
end;
procedure TfMain.BT_QuestionClick(Sender: TObject);
var
LPostdata: string;
LPostDataStream: TStringStream;
begin
try
_PapagoAns := "';
PaPaGoTrans(Memo_HanQ.Text, 'ko','en');
_Time_out := 0;
repeat
if _Time_out > 500 then exit;
inc(_Time_out);
delay(10);
until _PapagoAns <> '' ;
if _PapagoAns <> '' then begin
Memo_HanQ.Text := _PapagoAns;
_PapagoAnsAll := _PapagoAnsAll + _PapagoAns;
// _PapagoAns := '';
end;
_GPTAns := '';
LPostData := '{' +
'"model": "text-davinci-003",'+
'"prompt": "' + _PapagoAnsAll + '",'+
'"max_tokens": 2048,'+
'"temperature": 0'+
'}';
LPostDataStream := TStringStream.Create( LPostData, TEncoding.UTF8);
NetHTTPClient.CustomHeaders('Authorization') := 'Bearer ' + MyGPTKey;
NetHTTPClient.CustomHeaders('Content-Type') := 'application/json';
LPostDataStream.Position := 0;
NetHTTPClient.Post('https://api.openai.com/v1/completions', LPostDataStream );
_Time_out := 0;
repeat
if _Time_out > 1000 then exit;
inc(_Time_out);
delay(10);
until _GPTAns <> '' ;
if ckbTrans.IsChecked = False then exit; // 번역 체크가 아니면 끝냄.
if _GPTAns <> '' then begin
_PapagoAns := '';
PaPaGoTrans(_GPTAns, 'en','ko');
_Time_out := 0;
repeat
if _Time_out > 500 then exit;
inc(_Time_out);
delay(10);
until _PapagoAns <> '' ;
if _PapagoAns <> '' then begin
Memo_Ans.Text := _PapagoAns;
// _PapagoAns := '';
end;
end;
except
end;
end;
// 답변 받기 *******************************************************************************************
procedure TfMain.NetHTTPClientRequestCompleted(const Sender: TObject; const AResponse: IHTTPResponse);
var
LString, ansStr : string;
LJson: TJsonObject;
begin
if AResponse.StatusCode = 200 then
begin
LString := AResponse.ContentAsString;
LJson := TJSONObject.ParseJSONValue(LString) as TJSONObject;
try
ansStr := LJson.GetValue('choices').A(0).FindValue('text').Value;
_GPTAns := ansStr;
finally
LJson.Free;
end;
end else begin
ansStr := 'HTTP response code: ' + AResponse.StatusCode.ToString;
end;
Memo_Ans.Lines.Clear;
Memo_Ans.Lines.Add( ansStr );
end;
procedure TfMain.NetHTTPRequestPaPaGoRequestCompleted(const Sender: TObject;
const AResponse: IHTTPResponse);
begin
// Memo_HanQ.Lines.Clear;
// Memo_HanQ.Lines.Add( AResponse.ContentAsString() ); // 응답받은 전체 Json 데이터
_PapagoAns := Response_To_GetPapagoData( AResponse.ContentAsString());
// Memo_HanQ.Lines.Clear;
// Memo_HanQ.Lines.Add( Response_To_GetPapagoData( AResponse.ContentAsString() ) ); // 번역된 내용
end;
procedure TfMain.NetHTTPRequestRequestCompleted(const Sender: TObject;
const AResponse: IHTTPResponse);
var
LString, ansStr : string;
LJson: TJsonObject;
begin
// if AResponse.StatusCode = 200 then
// begin
// LString := AResponse.ContentAsString;
// LJson := TJSONObject.ParseJSONValue(LString) as TJSONObject;
// try
// ansStr := LJson.GetValue('choices').A(0).FindValue('text').Value;
// finally
// LJson.Free;
// end;
// end
// else
// ansStr := 'HTTP response code: ' + AResponse.StatusCode.ToString;
//
// Memo_Ans.Lines.Clear;
// Memo_Ans.Lines.Add( ansStr );
end;
function TfMain.Response_To_GetPapagoData( rData : string ) : string;
var
jSONValue : TJSONValue;
begin
// https://developers.naver.com/docs/papago/papago-nmt-api-reference.md
// 결과 Json 데이터 샘플
// {
// "message": {
// "@type": "response",
// "@service": "naverservice.nmt.proxy",
// "@version": "1.0.0",
// "result": {
// "srcLangType":"ko",
// "tarLangType":"en",
// "translatedText": "tea" <<<<< 번역된 결과 값 항목.
// }
// }
// }
JsonValue := TJSonObject.ParseJSONValue( rData );
result := JsonValue.GetValue<string>('message.result.translatedText');
JsonValue.Free;
end;
procedure TfMain.SpeedButton1Click(Sender: TObject);
begin
Memo_HanQ.Text := '';
end;
procedure TfMain.SpeedButton2Click(Sender: TObject);
begin
_PapagoAns := '';
_PapagoAnsAll := '';
Memo_HanQ.Text := '';
end;
end.
그리고 휴대폰에서 사용할 수 있도록 Android APK를 생성합니다.
(결과)
답장을 받기까지 5-10초가 걸립니다. 너무 답답해서 사용할 수 없을 것 같은 느낌이 듭니다.
많은 사람들이 Iron Man Jarvis가 그리 멀지 않은 것으로 생각한다고 생각합니다.
다음에는 Clova API를 사용하여 음성을 인식하고 음성으로 응답해 보도록 하겠습니다.
그리고 느린 반응에 대한 대책을 마련해야 합니다.