ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Delphi AI开发实战:基于TMS AI Studio源码的集成、定制与应用

Delphi AI开发实战:基于TMS AI Studio源码的集成、定制与应用 简介本资源是面向Delphi 11–13 Florence版本开发者的AI功能集成工具包——TMS AI Studio v1.3.0.0完整源码版专为缺乏AI底层经验但熟悉Delphi快速开发的中高级开发者设计解决在传统桌面/跨平台应用中便捷嵌入图像识别、自然语言处理与机器学习能力的痛点。压缩包共216个文件含68个Pascal源文件核心控件逻辑、32个DPROJ工程配置适配多版本Delphi、23个DPR主程序入口、9个DFM/FMX界面定义及8个RES资源文件辅以说明文档PDF/MD、示例数据库sample.db与启动脚本movefiles.bat整体大小61.44MB。已有111人下载学习可直接编译运行全部示例如Uaisimple.dfm、Uaiweather.dfm等深入理解AI控件封装机制完整源码支持二次定制、调试追踪与算法模块替换显著降低Delphi场景下AI工程落地门槛。1. 项目概述一份来自社区的“硬核”资源最近在Delphi开发者圈子里一个名为“TMS AI Studio v1.3.0.0 for Delphi 11-13 Florence Full Source.rar”的压缩包文件引起了不小的讨论。从文件名就能看出它的分量这是一个由知名第三方组件厂商TMS Software出品的AI集成开发套件版本号v1.3.0.0支持从Delphi 11 Alexandria到最新的Delphi 12 Athens项目标题中的“13 Florence”可能指代社区对Delphi 12的早期内部代号或误称并且最关键的是——它附带“Full Source”即完整源代码。对于任何一位深耕Delphi生态的开发者来说这都像是一份从天而降的“宝藏”。TMS的组件向来以高质量和稳定性著称但通常以编译后的二进制包形式授权分发。能拿到其核心产品TMS AI Studio的完整源代码意味着你不仅可以无限制地使用这套强大的AI工具集更能深入其内部理解每一行代码的实现逻辑进行定制化修改甚至学习顶尖组件厂商的架构设计。这不仅仅是获得了一个工具更是拿到了一本“武功秘籍”。无论是想快速为自家应用注入AI能力如智能文本分析、图像识别还是希望研究大型VCL/FireMonkey组件库该如何组织这个资源都具有极高的参考价值。当然随之而来的也是关于版权、版本兼容性以及如何正确“消化”这份资源的现实挑战。2. TMS AI Studio 核心价值与功能模块解析2.1 为什么是TMS AI Studio在Delphi的第三方组件生态中TMS Software是毫无争议的巨头之一。他们的产品线覆盖了UI控件、报表、图表、ORM、云连接等几乎所有领域。TMS AI Studio则是他们面向人工智能浪潮推出的战略级产品。与网络上零散的、基于某个特定AI接口如只封装了OpenAI ChatGPT的组件不同TMS AI Studio是一个统一的、可扩展的AI能力集成框架。它的核心价值在于抽象与整合。它将不同AI服务提供商如OpenAI、Google AI、Hugging Face、本地运行的Ollama等的API以及不同的AI任务类型聊天补全、文本嵌入、图像生成、语音识别等封装成一套统一的、基于Delphi接口的组件。开发者无需关心底层是调用HTTP REST API还是本地DLL只需在设计时拖放TMSAI、TMSAIChat、TMSAIImage等控件设置好Provider供应商和模型参数就能以一致的编程模式调用AI功能。这极大地降低了在Delphi应用中集成AI的门槛和复杂度。2.2 主要功能模块拆解拥有完整源代码我们可以清晰地看到其架构。通常TMS AI Studio会包含以下几个核心模块核心接口与抽象层 (TMS.AI.Core)这是整个库的基石。它定义了IAIProvider、IAIChat、IAIImage等核心接口以及TAIRequest、TAIResponse等通用数据模型。所有具体的AI服务实现都是这些接口的派生。这种设计遵循了“依赖倒置”原则使得上层应用代码依赖于抽象接口而非具体实现从而轻松切换AI服务商。提供商实现层 (TMS.AI.Providers)这个目录下包含了针对各个AI服务的具体实现。例如TMS.AI.Provider.OpenAI.pas: 封装OpenAI的GPT系列、DALL-E等模型的API调用。TMS.AI.Provider.GoogleAI.pas: 封装Google Gemini API的调用。TMS.AI.Provider.Ollama.pas: 封装与本地Ollama服务用于运行Llama2、Mistral等开源模型的通信。可能还有TMS.AI.Provider.Azure、TMS.AI.Provider.Claude等。每个Provider单元都负责处理身份验证、网络请求、错误处理以及将服务商特有的响应格式转换为库定义的通用格式。可视化控件层 (TMS.AI.Components)这是提供给开发者在IDE表单上直接拖放使用的控件。例如TMSAI: 主控件用于配置全局的API密钥、默认提供商等。TMSAIChat: 专门用于聊天对话场景管理对话历史、发送消息、流式接收回复。TMSAIImage: 用于图像生成或图像理解任务。TMSAITranscription: 用于语音转文字。这些控件在内部会创建并管理对应的Provider实例将属性设置和事件调用桥接到核心API上。工具与辅助单元包括用于处理JSON序列化/反序列化因为大部分AI API使用JSON、异步任务管理、日志记录、本地缓存用于存储嵌入向量或对话历史等功能的辅助单元。注意分析源代码时要特别注意其网络请求库的选择是使用Indy、NetHTTPClient还是其他、异步处理模型是基于线程、匿名线程还是使用System.Threading以及错误处理机制。这些是评估其稳定性和性能的关键。3. 从源代码到可用组件库的完整构建指南拿到一个.rar格式的完整源代码包直接使用是不行的。我们需要将其编译、安装到Delphi的IDE中或者至少将其编译为可供项目引用的DCU/BPL文件。以下是基于常见实践的标准化步骤。3.1 环境准备与源代码审视首先确保你的开发环境符合要求。根据文件名它支持Delphi 11-13。建议使用Delphi 12 Athens进行尝试因为其兼容性最好。你需要准备好对应版本的IDE。解压“TMS AI Studio v1.3.0.0 for Delphi 11-13 Florence Full Source.rar”后不要急于打开所有文件。先花时间浏览目录结构。一个规范的TMS源码包通常包含以下关键文件/目录Source\: 核心源代码目录里面按模块分文件夹。Demos\: 示例程序这是学习如何使用该库的最佳资料。Packages\: 包含各种版本的DPKDelphi Package项目文件用于编译和安装。Readme.txt或Install.txt: 安装说明如果有的话但社区资源往往缺失。License.txt: 许可协议**必须仔细阅读**社区分享的完整源码可能涉及版权风险仅限个人学习研究。第一步寻找入口点。进入Packages文件夹你会看到类似TMSAIStudio_D12.dprojDelphi项目文件和TMSAIStudio_D12.dpk包文件的文件。D12代表Delphi 12。找到与你IDE版本匹配的文件。3.2 编译与安装的详细步骤这里以在Delphi 12中安装运行时包Runtime Package和设计时包Design-Time Package为例。运行时包包含核心功能代码设计时包负责在IDE工具栏注册控件。设置库路径Library Path在安装前最好先将源码路径添加到IDE的库路径中。打开Delphi点击Tools - Options - Language - Delphi Options - Library。在Library path中添加你的源码根目录例如D:\Components\TMSAIStudio\Source。这能确保编译器在编译时能找到所有依赖的单元。编译运行时包在IDE中打开Packages目录下的TMSAIStudio_D12.dpk文件。在项目管理器Project Manager中右键点击该包选择“Compile”。如果编译成功会在输出目录通常是.\Bin生成TMSAIStudio_D12.bpl运行时包和.dcu文件。如果编译失败需要根据错误信息排查。常见错误1缺少依赖单元。错误信息可能提示找不到Vcl.Controls或System.JSON等。这通常是因为项目搜索路径未包含Delphi标准库路径但标准包一般不会出现此问题。更可能的是缺少TMS自家的其他依赖包比如TMS的核心库TMS.Comm.Base等。你需要确认这个AI Studio包是否依赖其他TMS组件并确保那些组件的源码或DCU路径也在库路径中。常见错误2版本不兼容语法。例如源代码中使用了Delphi 12的新特性而你的环境是Delphi 11。这时需要根据错误行进行语法降级调整或者寻找对应Delphi 11版本的包文件。安装设计时包编译通过后在项目管理器中右键点击TMSAIStudio_D12.dpk这次选择“Install”。这个操作会将设计时包注册到IDE。如果安装成功IDE会提示“Package xxxx has been installed”并且在工具栏的“TMS”或“AI”分类下你应该能看到TMSAI、TMSAIChat等控件图标。备用方案仅使用DCU文件如果安装过程复杂或总失败可以采用更轻量的方式。不执行“Install”只“Compile”。编译成功后将生成的.dcu文件分散在Source各子目录下全部复制到一个统一的目录如.\DCU。然后在你的应用程序项目中通过Project - Options - Delphi Compiler - Unit scope names或直接在该项目的搜索路径中添加这个.\DCU目录。这样你就可以在代码中uses相关的AI单元来编程调用只是无法在表单设计器上拖放控件。3.3 验证安装与跑通第一个Demo安装成功后创建一个新的VCL Application项目。在工具栏找到TMS AI控件拖一个TMSAI和TMSAIChat到表单上。查看TMSAI控件的属性找到Provider属性将其设置为OpenAI或其他你配置好的提供商。然后在TMSAI控件的属性中填入你的API密钥注意为了安全永远不要将硬编码的API密钥提交到版本控制系统应使用环境变量或配置文件。接下来打开Demos文件夹找一个最简单的聊天Demo例如ChatDemo打开并运行。这是验证整个库是否正常工作的最快方式。运行Demo输入消息看是否能收到AI的回复。如果Demo运行成功说明从源码到编译安装的整个链条是通的。4. 核心功能实战构建一个智能文本分析工具为了深入理解TMS AI Studio的使用我们抛开Demo从头构建一个实用的工具一个本地文档智能摘要与问答工具。它将支持加载文本文件利用AI生成摘要并允许用户就文档内容进行提问。4.1 界面设计与控件布局我们使用VCL框架。在表单上放置以下控件TMemo(命名为MemoSource): 用于显示和编辑原始文档文本。TButton(命名为BtnLoadFile): 点击后打开文件对话框加载.txt文件到MemoSource。TMSAI(命名为AI): 全局AI控制器。设置其Provider为Ollama假设我们在本地运行了Ollama和Llama2模型在OnCreate事件中设置其BaseURL为http://localhost:11434Ollama默认地址。TMSAIChat(命名为AIChat): 将其AI属性指向AI控件。这是我们与模型交互的核心。TButton(命名为BtnSummarize): 点击后触发摘要生成。TMemo(命名为MemoSummary): 显示生成的摘要。TEdit(命名为EditQuestion): 用于输入关于文档的问题。TButton(命名为BtnAsk): 点击后提交问题。TMemo(命名为MemoAnswer): 显示AI对问题的回答。4.2 关键代码实现与逻辑1. 摘要生成功能procedure TFormMain.BtnSummarizeClick(Sender: TObject); var Prompt: string; begin if MemoSource.Text.Trim.IsEmpty then begin ShowMessage(请先加载文档内容。); Exit; end; // 构建一个指令清晰的Prompt Prompt : 请为以下文本生成一个简洁、准确的摘要突出核心内容。文本内容如下 sLineBreak sLineBreak MemoSource.Text; // 设置聊天角色和消息。我们使用“系统”消息来设定AI行为“用户”消息传递文本。 AIChat.ClearMessages; AIChat.Messages.AddRole(TMessageRole.System).Content : 你是一个专业的文本分析助手擅长生成简洁的摘要。; AIChat.Messages.AddRole(TMessageRole.User).Content : Prompt; MemoSummary.Lines.Text : 正在生成摘要请稍候...; BtnSummarize.Enabled : False; // 异步调用避免界面卡死 AIChat.ExecuteAsync( procedure begin // 此回调在AI响应完成后在主线程中执行 TThread.Synchronize(nil, procedure begin MemoSummary.Lines.Text : AIChat.Messages.Last.Content; BtnSummarize.Enabled : True; end); end, procedure (const Error: string) begin // 错误处理回调 TThread.Synchronize(nil, procedure begin MemoSummary.Lines.Text : 摘要生成失败 Error; BtnSummarize.Enabled : True; end); end ); end;2. 文档问答功能这个功能的关键在于将文档内容作为“上下文”提供给AI。对于长文档我们需要使用“嵌入”或“上下文窗口”技术。这里演示一个简单版将整个文档假设不长作为上下文附加到每个问题中。procedure TFormMain.BtnAskClick(Sender: TObject); var Question: string; ContextPrompt: string; begin Question : EditQuestion.Text.Trim; if Question.IsEmpty then Exit; // 将文档内容作为上下文与问题一起发送 ContextPrompt : 请根据以下文档内容回答问题。如果文档中没有明确答案请说明“根据提供文档无法找到相关信息”。 sLineBreak sLineBreak 【文档内容开始】 sLineBreak MemoSource.Text sLineBreak 【文档内容结束】 sLineBreak sLineBreak 问题 Question; AIChat.ClearMessages; // 可以保留一个系统角色设定 AIChat.Messages.AddRole(TMessageRole.System).Content : 你是一个严谨的文档分析员只根据提供的文档内容回答问题。; AIChat.Messages.AddRole(TMessageRole.User).Content : ContextPrompt; MemoAnswer.Lines.Text : 正在思考...; BtnAsk.Enabled : False; AIChat.ExecuteAsync( procedure begin TThread.Synchronize(nil, procedure begin MemoAnswer.Lines.Text : AIChat.Messages.Last.Content; BtnAsk.Enabled : True; end); end, procedure (const Error: string) begin TThread.Synchronize(nil, procedure begin MemoAnswer.Lines.Text : 回答失败 Error; BtnAsk.Enabled : True; end); end ); end;实操心得在实际使用中直接将长文档作为上下文会很快耗尽模型的Token限制通常4K-128K。对于生产环境更优的做法是文档分块将长文档按段落或固定大小分割成多个片段。向量化与检索使用TMS AI Studio的文本嵌入功能如果该版本支持将每个片段转换为向量并存入向量数据库如Chroma、Qdrant。语义检索当用户提问时将问题也向量化在向量数据库中检索出最相关的几个文档片段。构建Prompt只将这些相关片段作为上下文发送给大模型生成答案。这就是经典的RAG检索增强生成架构。TMS AI Studio的完整源码为我们实现这套流程提供了底层API支持。5. 深度定制与源码学习修改Provider以适配国产大模型拥有完整源代码的最大优势在于定制。假设公司要求接入一个国产大模型如智谱AI、文心一言或通义千问而TMS AI Studio官方并未提供该Provider。这时我们就可以自己动手丰衣足食。5.1 创建自定义Provider的步骤研究现有Provider打开TMS.AI.Provider.OpenAI.pas或TMS.AI.Provider.Ollama.pas这是最好的模板。你会发现它们都继承自一个基类例如TCustomAIProvider并实现了IAIProvider、IAIChat等核心接口。创建新单元在Source目录下或你自己的组件目录新建一个单元文件例如TMS.AI.Provider.ZhiPu.pas。定义Provider类unit TMS.AI.Provider.ZhiPu; interface uses System.Classes, System.SysUtils, TMS.AI.Core; // 引用核心单元 type TZhiPuAIProvider class(TCustomAIProvider, IAIProvider, IAIChat) private FApiKey: string; FBaseURL: string; // 其他私有字段如HTTP客户端 protected // 实现IAIChat接口的方法 function GetChatCompletion(const ARequest: TAIChatCompletionRequest): TAIChatCompletionResponse; override; procedure GetChatCompletionAsync(const ARequest: TAIChatCompletionRequest; const OnResponse: TProcTAIChatCompletionResponse; const OnError: TProcstring); override; // 可能还需要实现IAIImage, IAIEmbedding等接口的方法 public constructor Create(AOwner: TComponent); override; // 发布必要的属性如ApiKey, BaseURL property ApiKey: string read FApiKey write FApiKey; property BaseURL: string read FBaseURL write FBaseURL default https://open.bigmodel.cn/api/paas/v4/; end; implementation uses System.Net.HttpClient, System.Net.URLClient, System.JSON; // 可能需要HTTP和JSON单元 constructor TZhiPuAIProvider.Create(AOwner: TComponent); begin inherited; FBaseURL : https://open.bigmodel.cn/api/paas/v4/; end; function TZhiPuAIProvider.GetChatCompletion(const ARequest: TAIChatCompletionRequest): TAIChatCompletionResponse; var LHttpClient: THTTPClient; LRequestStream: TStringStream; LResponseStream: TStringStream; LUrl: string; LJsonReq, LJsonResp: TJSONObject; LMsgArray: TJSONArray; LMsg: TMessage; begin Result : TAIChatCompletionResponse.Create; LHttpClient : THTTPClient.Create; LRequestStream : TStringStream.Create(, TEncoding.UTF8); LResponseStream : TStringStream.Create(, TEncoding.UTF8); try // 1. 构建符合智谱API要求的JSON请求体 LJsonReq : TJSONObject.Create; try LJsonReq.AddPair(model, glm-4); // 指定模型 LMsgArray : TJSONArray.Create; for LMsg in ARequest.Messages do begin LMsgArray.AddElement(TJSONObject.Create .AddPair(role, LMsg.Role.ToString.ToLower) // 注意角色名称可能需转换 .AddPair(content, LMsg.Content)); end; LJsonReq.AddPair(messages, LMsgArray); LJsonReq.AddPair(stream, TJSONBool.Create(False)); LRequestStream.WriteString(LJsonReq.ToJSON); finally LJsonReq.Free; end; // 2. 配置HTTP请求 LUrl : FBaseURL chat/completions; LHttpClient.CustomHeaders[Authorization] : Bearer FApiKey; LHttpClient.ContentType : application/json; // 3. 发送同步请求 LHttpClient.Post(LUrl, LRequestStream, LResponseStream); // 4. 解析智谱API的响应并填充到通用的TAIChatCompletionResponse中 LJsonResp : TJSONObject.ParseJSONValue(LResponseStream.DataString) as TJSONObject; try if Assigned(LJsonResp) and LJsonResp.TryGetValue(choices, LMsgArray) and (LMsgArray.Count 0) then begin Result.Choices.Add(TMessage.Create); Result.Choices.Last.Role : TMessageRole.Assistant; Result.Choices.Last.Content : LMsgArray.Items[0].GetValuestring(message.content); end else begin raise Exception.Create(Invalid response from ZhiPu AI: LResponseStream.DataString); end; finally LJsonResp.Free; end; finally LRequestStream.Free; LResponseStream.Free; LHttpClient.Free; end; end; // GetChatCompletionAsync的实现类似但需使用异步HTTP调用这里省略... end.注册Provider为了让TMSAI控件能在设计时选择你的ZhiPu提供商你需要在Provider单元的最后调用RegisterProvider过程如果库提供了这样的机制或者在控件初始化时手动将你的Provider类添加到工厂中。具体方法需要参考源码中其他Provider是如何被注册的通常在一个TMS.AI.Providers.pas或TMS.AI.Register.pas的单元里。5.2 源码学习的要点通过这个自定义过程你能深入学习到网络层封装库是如何抽象HTTP客户端处理超时、重试和错误的。数据模型转换如何将通用的TAIRequest转换为特定厂商的API格式又如何将厂商的响应转换回来。这是适配器的经典应用。异步编程模型库是使用回调、事件还是Future/Promise来处理异步操作这对于编写响应式UI至关重要。配置与状态管理API密钥、端点URL等配置是如何在控件间传递和管理的。6. 常见问题、排查技巧与版本兼容性处理在实际使用和编译这类第三方源码时会遇到各种问题。以下是一些典型问题及其解决思路。6.1 编译与安装阶段问题问题现象可能原因排查与解决思路编译时提示“Unit xxx not found”1. 库路径未正确设置。2. 依赖的其他包如TMS Core库未安装或路径不对。3. 源代码包本身不完整。1. 检查并添加所有必要的源码路径到IDE库路径。2. 查看包文件.dpk的“Requires”列表确保其中列出的所有包都已安装或能找到。3. 对比网络上的其他资源确认文件是否齐全。安装时提示“Cannot load package xxx. It contains unit xxx, which is also contained in package yyy”单元冲突。同一个单元如TMS.AI.Core被编译进了多个不同的包中。1. 卸载所有已安装的TMS AI Studio旧版本包。2. 清理旧的DCU/BPL文件确保编译环境干净。3. 尝试只编译运行时包然后在项目中引用DCU放弃安装设计时包。控件安装成功但拖到表单上提示“Class TMSAI not found”设计时包包含控件注册信息与运行时包包含实际代码版本不匹配或未正确加载。1. 关闭所有Delphi IDE实例重新打开。2. 检查Component - Install Packages确保对应的设计时包已勾选且路径正确。3. 在系统搜索路径中确保运行时BPL文件的目录在PATH环境变量中或者将BPL复制到系统目录。6.2 运行时与API调用问题问题现象可能原因排查与解决思路调用AI功能时程序无响应或报网络错误。1. API密钥、BaseURL配置错误。2. 网络代理问题。3. 异步调用未正确处理导致主线程阻塞。1. 使用TMSAI控件的OnError事件捕获详细错误信息。2. 对于本地模型如Ollama用浏览器访问http://localhost:11434/api/tags测试服务是否正常。3. 检查防火墙和代理设置。在代码中为HTTP客户端显式配置代理。4. 确保异步调用的回调函数被正确执行避免在回调中做耗时操作。流式输出Streaming不工作必须等全部生成完才显示。1. 使用的Provider或模型不支持流式响应。2. 代码中未正确处理流式回调事件。1. 查阅对应AI服务的API文档确认是否支持流式如OpenAI的stream: true参数。2. 检查TMSAIChat控件是否有OnStreamingChunkReceived之类的事件并在该事件中实时更新UI。处理长文本时返回“context length exceeded”错误。输入的文本Prompt对话历史超过了模型的最大上下文长度Token限制。1. 对输入文本进行智能截断或分块总结。2. 使用“摘要-问答”链式调用先对长文档生成摘要再基于摘要提问。3. 考虑使用支持更长上下文的模型如GPT-4 Turbo 128K。6.3 关于“Delphi 13.1”与版本兼容性的特别说明项目标题中提到了“Delphi 13.1”但Embarcadero官方发布的版本序列中Delphi 11之后是Delphi 12 Athens。所谓的“13.1”或“Florence”很可能是发布前的内部开发代号或者是社区/资源分享者的一种误称或未来版本占位。在处理此类资源时版本兼容性是首要问题。向前兼容为Delphi 12编译的包通常无法直接在Delphi 11上安装因为DCU/BPL格式可能不兼容且可能使用了Delphi 12的新特性。向后兼容为Delphi 11编译的包在Delphi 12上可能可以安装但可能需要重新编译。最佳实践永远尝试用源代码重新编译。打开与你当前Delphi版本最接近的.dpk文件进行编译。如果版本号不匹配如只有D11的包但你在用D12直接打开D11的包Delphi IDE通常会提示进行转换转换后尝试编译。根据编译错误逐一调整例如替换过时的单元引用修改不兼容的语法。一个关键的技巧是如果包文件转换后编译困难可以放弃安装整个包。转而创建一个新的“Package”项目将Source目录下所有相关的.pas文件添加到这个新包中然后编译。这样可以排除原有包项目配置的干扰。本文还有配套的精品资源点击获取
返回列表