sgcAI 五分钟上手
一个组件,一个提供商属性,一次调用。本页让 Delphi 应用程序与大型语言模型对话,向您展示如何流式获取回答而不是干等,并清楚说明那个容易让人踩坑的平台限制。
一个组件,一个提供商属性,一次调用。本页让 Delphi 应用程序与大型语言模型对话,向您展示如何流式获取回答而不是干等,并清楚说明那个容易让人踩坑的平台限制。
一个组件、一个密钥、一个模型名称和一个提示词。无需构建 JSON,也无需配置 HTTP 客户端。
SGC AI 组件面板页上的 TsgcAIChat。它是 TsgcAI_Chat 的一个轻量级已发布封装,随包附带的演示就是在代码中创建 TsgcAI_Chat。
类使用 sgcAI_Chat.pas,组件面板组件使用汇总单元 sgcAI.pas。演示中写的是 uses sgcAI_Chat;。
Provider,类型为 TsgcAIChatProvider。七个成员是 aicpOpenAI、aicpAnthropic、aicpGemini、aicpDeepSeek、aicpOllama、aicpGrok 和 aicpMistral。您代码中的其他部分都不需要改动。
TsgcAIChat 仅为 Windows(Win32 和 Win64)编译。各供应商的 REST 客户端以及 MCP 客户端和服务器不受此限制。原因请参见下表。
版本列给出的是控制代码的定义,以及它在 Source/sgcVer.inc 中所在的行号。
| 项目 | 值 |
|---|---|
| IDE | Delphi 7 到 RAD Studio 13,以及相应的 C++Builder 版本。ChatAsync 是唯一最低版本要求更高的成员,因为它被包裹在 {$IFDEF D2010} 中。 |
| uses 子句 | TsgcAI_Chat、TsgcAIChatProvider 和事件类型使用 sgcAI_Chat。 |
| 版本,在 sgcWebSockets 内 | SGC_AI 定义在第 798 行,位于从第 760 行延伸到第 839 行的 {$IFDEF SGC_EDT_ENT} 块内。因此是 Enterprise 及以上版本,不是 Standard,也不是 Professional。 |
| 版本,独立包 | sgcAI 产品在第 854 行定义 SGC_PACK_AI,其自己的第 943 行到第 957 行的块在第 945 行定义 SGC_AI。组件相同,只是不含库的其余部分。 |
| 为什么仅限 Windows | SGC_AI 的两处定义都位于 {$IFDEF MSWINDOWS} 之内,分别在第 797 行和第 944 行。在 Windows 之外,该定义永远不会出现,因此 sgcAI_Chat.pas 会编译成空单元。该组件还带有 ComponentPlatforms(pidWin32 or pidWin64)。 |
| 哪些是跨平台的 | 第 800 行和第 954 行的 SGC_AI_MCP 没有平台保护。因此 MCP 客户端和服务器也能在 Linux、macOS、iOS 和 Android 上运行。第 787 行到第 793 行的提供商定义 SGC_OPENAI、SGC_ANTHROPIC、SGC_GEMINI、SGC_DEEPSEEK、SGC_OLLAMA、SGC_GROK 和 SGC_MISTRAL 同样没有平台限制。 |
要构建 Linux 服务或移动应用?请跳过 TsgcAIChat,直接调用供应商的 REST 客户端,例如 TsgcHTTP_API_OpenAI 或 TsgcHTTP_API_Anthropic。在 Delphi 中调用 LLM 指南并排展示了这两种方式。
sgcAI 包含在 sgcWebSockets 安装程序中,也作为独立的包提供。无论哪种方式,安装流程都相同。
将下载文件解压到一个文件夹,下文称之为 {$DIR}。
依次选择 Tools、Options、Library。添加 {$DIR}\source 以及与您的 IDE 对应的 lib 文件夹,例如 {$DIR}\libD13\$(Platform)。
在 {$DIR}\Packages\ 下,打开与您的 IDE 版本对应的包组。先编译运行时 .dpk,再安装 dcl 设计时包。
会出现一个名为 SGC AI 的页面,包含十五个组件。TsgcAIChat 是第一个。如果在非 Windows 目标上缺少该页面,这是正常的,因为 SGC_AI 受 Windows 限制。
对于托管的提供商,您需要从该供应商处获取自己的密钥,并将其赋给 ChatOptions.ApiKey。Ollama 完全不需要密钥,因为模型运行在您自己的机器上。
创建组件,设置提供商、密钥和模型,然后调用 Chat 并读取它返回的字符串。
uses
Classes, SysUtils,
// sgc
sgcAI_Chat;
procedure TfrmUnifiedChat.btnChatClick(Sender: TObject);
var
oChat: TsgcAI_Chat;
begin
oChat := TsgcAI_Chat.Create(nil);
try
oChat.Provider := aicpOpenAI;
oChat.ChatOptions.ApiKey := GetApiKey;
oChat.ChatOptions.Model := 'gpt-4o-mini';
oChat.ChatOptions.MaxTokens := 1024;
oChat.SystemMessage := 'You are a concise assistant inside a Delphi ERP.';
memoResponse.Lines.Text := oChat.Chat(memoPrompt.Text);
finally
oChat.Free;
end;
end;
更换供应商只需改一行。Provider 接受 aicpOpenAI、aicpAnthropic、aicpGemini、aicpDeepSeek、aicpOllama、aicpGrok 和 aicpMistral。其他一切保持原样。
procedure TfrmUnifiedChat.OnChatStream(Sender: TObject; const aChunk: string;
var Cancel: Boolean);
begin
memoResponse.Text := memoResponse.Text + aChunk;
// set Cancel to stop the generation early
end;
procedure TfrmUnifiedChat.OnChatError(Sender: TObject; const aError: string);
begin
memoResponse.Text := 'error: ' + aError;
end;
procedure TfrmUnifiedChat.btnChatStreamClick(Sender: TObject);
begin
GetChat.Provider := aicpAnthropic;
GetChat.ChatOptions.ApiKey := GetApiKey;
GetChat.ChatOptions.Model := 'claude-sonnet-4-20250514';
GetChat.SystemMessage := memoSystem.Text;
memoResponse.Lines.Clear;
GetChat.ChatStream(memoPrompt.Text);
end;
演示在 GetChat 中一次性构建组件,并在那里为 OnChatStream 和 OnChatError 赋值。ChatStream 同样会返回完整的回答,因此您可以忽略返回值而只使用事件,也可以两者都用。
uses
Classes, SysUtils,
// sgc
sgcAI_Chat;
var
oChat: TsgcAI_Chat;
begin
oChat := TsgcAI_Chat.Create(nil);
try
// no API key at all: the model runs on this machine
oChat.Provider := aicpOllama;
oChat.ChatOptions.Model := 'llama3';
// BaseUrl is read only for the Ollama provider, and only when
// the server is not on the default address. Internally it is
// forwarded to the Ollama client's Host property.
oChat.ChatOptions.BaseUrl := 'http://localhost:11434';
Writeln(oChat.Chat('Summarise this invoice in one line.'));
finally
oChat.Free;
end;
end;
没有 OllamaOptions.BaseUrl。在原始 API 层面,该属性是 TsgcHTTP_API_Ollama 上的 OllamaOptions.Host,而在这一层,由 ChatOptions.BaseUrl 为它提供值。
前两个选项卡是随包附带的演示 Demos\15.AI\02.Applications\06.UnifiedChat\fUnifiedChat.pas,其中的窗体控件已替换为字面量。第三个选项卡是同一个组件指向本地 Ollama 服务器的情形。同一文件夹中的另一个演示 07.ConversationHistory 展示了历史记录 API。
Chat 在调用失败时不会抛出异常,这会让人感到意外。它会返回空字符串,并触发一个事件。
Chat 以 string 形式返回助手的文本。空字符串表示调用失败,因为失败不会抛出异常。
OnChatErrorprocedure(Sender: TObject; const aError: string)。Chat 和 ChatStream 都会捕获异常并转发到这里。这是首先要连接的事件,先于其他一切。
OnChatStreamprocedure(Sender: TObject; const aChunk: string; var Cancel: Boolean)。在模型仍在书写时,文本就出现在备注框中,这证明流式输出正在工作,而不是在缓冲。
GetHistory 返回组件在下一次调用时将重放的内容。MaxHistoryMessages 限制其数量,ClearHistory 则重新开始。
六个问题几乎涵盖了所有失败的第一次调用。
这是有意设计的。SGC_AI 定义在第 797 行和第 944 行的 {$IFDEF MSWINDOWS} 之内,因此在 Linux、macOS、iOS 和 Android 上 sgcAI_Chat.pas 是一个空单元。在这些目标上请使用供应商的 REST 客户端。
Chat 和 ChatStream 会吞掉异常并将其转发到 OnChatError,其签名是 procedure(Sender: TObject; const aError: string)。在调试其他任何问题之前,先连接该事件。
Ollama 的基础地址应设置在 ChatOptions.BaseUrl 上,而不是供应商选项对象上。它会在内部转发给 OllamaOptions.Host,并且是唯一会读取 BaseUrl 的提供商。
Chat 和 ChatStream 是同步的。在 Delphi 2010 及更高版本上,请使用 ChatAsync,它返回 IsgcFuture<string>。在更旧的编译器上,请在您自己的线程中运行该调用。
模型名称属于供应商,而不属于组件,并且会发生变化。ChatOptions.Model 会被直接传递,因此在供应商控制台中可用的名称在这里同样可用。
组件在每次调用时都会重放历史记录,这正是后续提问能够奏效的原因。请用 MaxHistoryMessages 限制其数量,并用 ClearHistory 重新开始。
提示词输入框只是开始。下面这四项都已包含在包中。
使用 TsgcAIOpenAIEmbeddings 把您的内容转换为向量,存储到 TsgcAIDatabaseVectorFile 或 TsgcAIDatabaseVectorPinecone 中,并检索最接近的段落放入提示词。
TsgcAIOpenAIChatBot 把录音器、转录、聊天调用和文本转语音整合到一个组件中。TsgcAIOpenAITranslator 为实时翻译提供同样的整合。
MCP 服务器组件会把您的应用程序变成助手可以调用的工具,而 MCP 客户端则使用其他服务器。两者都不受 Windows 限制,因此用 Delphi 编写的 MCP 服务器可以在 Linux 上运行。
参考页面记录了每个选项和事件。演示项目包含在下载包内,位于 Demos\15.AI 下。
| 指南:在 Delphi 中调用 LLM 详尽的操作演练:流式输出、工具调用,以及托管模型与本地模型的对比。 | 打开 | |
参考:OpenAI 客户端
TsgcHTTP_API_OpenAI 上的每个方法、选项和事件。
|
打开 | |
参考:Anthropic 客户端
TsgcHTTP_API_Anthropic 上的消息、工具、视觉、批处理和令牌计数。
|
打开 | |
| 参考:MCP 服务器 让助手能够调用您的应用程序的组件。 | 打开 | |
| TsgcAIChat 组件页面 聊天组件上的每个属性和事件,其余十四个组件也可从中链接访问。 | 打开 | |
| 在线帮助 自动生成的参考,始终与当前版本保持同步。 | 打开 |
相关阅读:构建 AI 驱动的 Delphi 应用、从 Delphi 比较各个提供商和编写 MCP 服务器。每个产品都有自己的快速入门,列在入门页面上。
TsgcAIChat。它在 sgcAI.pas 中声明,是 TsgcAI_Chat 的已发布封装,而 TsgcAI_Chat 声明在 sgcAI_Chat.pas 中。像随包附带的演示那样在运行时创建对象的代码,使用 TsgcAI_Chat 和 uses sgcAI_Chat;。两者提供的属性相同。
SGC_AI,它定义在 sgcVer.inc 的第 798 行,位于从第 760 行延伸到第 839 行的 SGC_EDT_ENT 块内。也就是 Enterprise 及以上版本。Standard(第 675 行到第 724 行)和 Professional(第 727 行到第 758 行)都没有定义它。如果您不需要库的其余部分,独立的 sgcAI 包在第 854 行定义 SGC_PACK_AI,其自己的第 943 行到第 957 行的块会启用相同的组件。
SGC_AI 只会在 {$IFDEF MSWINDOWS} 之内定义,分别位于 Enterprise 块的第 797 行和独立包块的第 944 行。在没有该定义时,sgcAI_Chat.pas 以及 sgcAI.pas 中的 TsgcAIChat 部分都会编译成空。设计时通过 ComponentPlatforms(pidWin32 or pidWin64) 体现这一点。在这些目标上,请改为调用供应商的 REST 客户端,或使用没有平台保护的 MCP 组件。
Provider。它接受 aicpOpenAI、aicpAnthropic、aicpGemini、aicpDeepSeek、aicpOllama、aicpGrok 和 aicpMistral。然后设置该供应商的密钥和模型。对于 aicpOllama,不需要密钥;如果服务器不在默认地址上,请设置 ChatOptions.BaseUrl,组件会在内部将其转发给 Ollama 客户端。
ChatStream 而不是 Chat,并处理 OnChatStream。其签名是 procedure(Sender: TObject; const aChunk: string; var Cancel: Boolean):在 aChunk 到达时把它追加到备注框中,并把 Cancel 设置为 True 以提前停止生成。
Chat 和 ChatStream 不会抛出异常。它们会捕获异常,用消息触发 OnChatError,并返回空字符串。因此,一个未处理的 OnChatError 看起来与模型什么都没回答完全一样。请首先连接它。
ChatAsync,它被包裹在 {$IFDEF D2010} 中,并返回 IsgcFuture<string>。在 Delphi 7 到 2009 上不存在该方法,因此请在您自己创建的线程上运行 Chat。
MaxHistoryMessages 限制重放的数量,ClearHistory 开始新的对话,GetHistory 返回已存储的消息。