本文将继续和大家介绍 SemanticKernel 神奇的魔法,将使用 LLM 大语言模型编写的自然语言函数和传统的编程语言编写的函数融合到一起的例子。通过本文的例子,大家可以看到 SemanticKernel 框架所推荐的一个工作模式,同时可以更好的理解 SemanticKernel 框架的用法

本文属于 SemanticKernel 入门系列博客,更多博客内容请参阅我的 博客导航博客园的合集

开始之前先来聊聊本文的背景,本文将给出一个使用 SemanticKernel 框架连接魔法的 LLM 和传统的编程语言编写的函数的应用例子。这个例子所解决的问题是:我拿到了多个不同的数据集,我需要编写代码将数据集里面所提到的日期提取出来

更具体一点的实现是我拿到的多个不同的数据集里面,每个数据集对于日期的定义可能是不相同的格式,如以下的两个数据例子。如果不依靠 LLM 魔法的话,那我只能写多个正则表达式去适配多个不同的数据集了。但在本文的设定里面,我是不擅长写正则表达式的

var data1 =
"""
在2023年9月1号开始上课
在2023年9月2号开始准备教材
在2023年9月3号完成作业
"""; var data2 =
"""
在9.1.2023开始上课
在9.2.2023开始准备教材
在9.3.2023完成作业
""";

那如果全部都给 LLM 处理呢?理论上是可以的,但是存在两个问题,第一个是 LLM 可能不够擅长做比较大的数据集的处理,无论是成本方面还是本身 Token 长度限制方面。第二个就是我选用的 GPT 3.5 模型本身难以完成这项任务,当前的执行效率也不够高,需要跑半天才能完成,且即使完成之后后续对接解析结果也需要额外的工作量

那是否有比较完美的方案,同时规避了传统编程函数和 LLM 的缺点,且拥有两者的优势?这是当然有的,通过 SemanticKernel 框架的辅助下,咱可以各取两者的优点,让传统编程难以完成的事情交给 LLM 去实现,将 LLM 不擅长做的交给传统编程语言去完成

总的技术实现是,先对每个数据集分别进行处理。编写传统 C# 函数,取出数据集里面的代表数据,也就是第一行的字符串。接着将取出的代表数据给到使用自然语言编程函数的 GPT 进行处理,让 GPT 给出正则表达式字符串。再根据 GPT 给出的正则表达式字符串,传入到 C# 的正则类里面,让 C# 代码高效稳定处理数据集

如此实现既可以让开发者不用编写复杂的正则表达式,同时也可以使用一套代码处理多个不同的数据格式的数据集

接下来让大家看看 SemanticKernel 将 LLM 自然语言函数和传统编程融合到一起的威力

在开始编写代码之前,期望大家已经对 SemanticKernel 和 C# 语言有了入门的了解

新建一个 .NET 7 的控制台应用,编辑 csproj 项目文件,按照 dotnet 的习俗安装好各个 NuGet 库,修改之后的 csproj 项目文件代码大概如下。放心,在本文末尾将给出本文所有代码的下载方法

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
<PackageReference Include="Microsoft.SemanticKernel" Version="0.20.230821.4-preview" />
</ItemGroup> </Project>

接着进行配置和初始化,本文这里用到了 AzureAI 的 GPT 3.5 模型,需要提前申请好。申请地址:https://aka.ms/oai/access

using System.Text.RegularExpressions;

using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Orchestration;
using Microsoft.SemanticKernel.SkillDefinition; var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Debug);
});
var logger = loggerFactory.CreateLogger("SemanticKernel"); // 这里的演示代码需要用到 AzureAI 的支持,需要提前申请好,申请地址:https://aka.ms/oai/access var endpoint = "https://lindexi.openai.azure.com/"; // 请换成你的地址
var apiKey = args[0]; // 请换成你的密钥 IKernel kernel = new KernelBuilder()
.WithLogger(logger)
.WithAzureChatCompletionService("GPT35", endpoint, apiKey)
.Build();

关于以上配置,详细请参阅 我的 SemanticKernel 合集博客

按照本文的技术实现设计,先编写 C# 函数,这里需要有两个函数,分别是取出数据集的第一行作为代表数据,以及使用 GPT 给到的正则表达式字符串进行处理数据集。根据 SemanticKernel 自定义技能 博客提供的方法,以下直接给出这两个 C# 函数编写的 TextSkill 技能代码

class TextSkill
{
[SKFunction]
public string TakeFirstLine(string input, SKContext context)
{
context.Variables["text"] = input;
var stringReader = new StringReader(input);
return stringReader.ReadLine() ?? string.Empty;
} [SKFunction]
public void RegexMatchText(string input, string text, SKContext context)
{
foreach (Match match in Regex.Matches(text,input))
{
Console.WriteLine(match.Value);
}
}
}

上面代码里面的 TakeFirstLine 就是取出数据集的第一行作为代表数据,其中一个细节就是将输入的内容放入到 text 变量里面,而不是丢掉。放入到变量里面就可以方便让后续的 RegexMatchText 函数使用

在 RegexMatchText 就是根据 GPT 给出的正则表达式字符串,也就是 input 变量对应的值,对 TakeFirstLine 放入的 text 变量,也就是原始数据集进行处理。处理之后直接打印

完成 C# 函数编写之后,将 TextSkill 技能导入到 SemanticKernel 里

kernel.ImportSkill(new TextSkill());

接下来请出百万炼丹师进行编写自然语言函数,让 GPT 可以可以从代表数据里面输出提取日期的正则表达式

const string FunctionDefinition =
"""
我有这样一段文本:
{ {$input} }
请你写一个正则表达式字符串,用来提取出日期 正则表达式字符串:
"""; kernel.CreateSemanticFunction(FunctionDefinition, maxTokens: 200, temperature: 0.5, functionName: "BuildRegexText");

调用 CreateSemanticFunction 时传入函数名,则可以自动注册到 SemanticKernel 框架里。现在咱拥有了三个函数,分别是两个 C# 代码编写的 TakeFirstLine 和 RegexMatchText 函数,以及使用自然语言编写的 BuildRegexText 魔法函数

按照 SemanticKernel 管道式调用函数 博客提供的方法,咱可以使用管道将以上几个函数排列组合放入到 SemanticKernel 执行

为了方便调用,这里编写了一个 C# 内部方法,方法的入参就是数据集

async Task RunAsync(string data)
{
await kernel.RunAsync
(
data,
kernel.Skills.GetFunction("TakeFirstLine"),
kernel.Skills.GetFunction("BuildRegexText"),
kernel.Skills.GetFunction("RegexMatchText")
);
}

以上代码就是按照本文开始的设计,先使用 TakeFirstLine 取出数据集里面的代码数据,接着调用 BuildRegexText 魔法函数让 GPT 生成正则表达式字符串,最后调用 RegexMatchText 函数使用 GPT 的正则表达式字符串处理数据集

这就是本文的实现的所有代码了,这个代码可以适配非常多的不同格式的数据,只要 GPT 魔法函数 BuildRegexText 能够正常输出正确的正则表达式的,那以上代码都能符合预期工作

接下来测试一下,看看以上代码能否符合预期工作

var data1 =
"""
在2023年9月1号开始上课
在2023年9月2号开始准备教材
在2023年9月3号完成作业
"""; var data2 =
"""
在9.1.2023开始上课
在9.2.2023开始准备教材
在9.3.2023完成作业
"""; Console.WriteLine($"开始执行解析 data1");
await RunAsync(data1);
Console.WriteLine($"开始执行解析 data2");
await RunAsync(data2);

可以看到,以上代码给出的是两个日期格式不相同的数据集,这时候就可以看到 LLM 的威力了。运行代码,可以看到控制台有以下输出

开始执行解析 data1
2023年9月1号
2023年9月2号
2023年9月3号 开始执行解析 data2
9.1.2023
9.2.2023
9.3.2023

可以看到正确输出了两个数据集的日期

也就是说尽管两个数据集采用不同的日期表达形式,但都在咱以上代码能工作的范围内,大家也可以试试更加奇怪的数据集,看是否能够符合预期工作

这就是 SemanticKernel 威力,使用 LLM 配合传统编程语言函数完成工作,发挥 LLM 和传统编程语言的优势

本文的代码放在githubgitee 欢迎访问

可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin db13740804d16b3c56e8c24ab5a9ddf40962ecec

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin db13740804d16b3c56e8c24ab5a9ddf40962ecec

获取代码之后,进入 WalhocebarkairQalbehoreho 文件夹

SemanticFunction 融合 LLM 和传统编程的更多相关文章

  1. 10Spring_AOP编程(传统编程)

    注意我写这篇文章的思路,要想做切面编程,包含两个部分,通知和切点,通知是你要做哪些增强,切点是指你要拦截哪些方法.先介绍通知的定义再去介绍切点的定义.这篇文章我取名叫做Spring_AOP编程(传统编 ...

  2. 传统编程和IoC的对比

    ref:http://www.importnew.com/13619.html 传统编程:决定使用哪个具体的实现类的控制权在调用类本身,在编译阶段就确定了. IoC模式:调用类只依赖接口,而不依赖具体 ...

  3. *nix下传统编程入门之GCC

    准备工作 注意:本文可能会让你失望,如果你有下列疑问的话:为什么要在终端输命令啊? GCC 是什么东西,怎么在菜单中找不到? GCC 不能有像 VC 那样的窗口吗?…… 那么你真正想要了解的可能是 a ...

  4. Python交互式编程导论----事件驱动编程

    传统的编程是如下线性模式的: 开始--->代码块A--->代码块B--->代码块C--->代码块D--->......--->结束 每一个代码块里是完成各种各样事情 ...

  5. Scalaz(43)- 总结 :FP就是实用的编程模式

    完成了对Free Monad这部分内容的学习了解后,心头豁然开朗,存在心里对FP的疑虑也一扫而光.之前也抱着跟大多数人一样的主观概念,认为FP只适合学术性探讨.缺乏实际应用.运行效率低,很难发展成现实 ...

  6. Scalaz(10)- Monad:就是一种函数式编程模式-a design pattern

    Monad typeclass不是一种类型,而是一种程序设计模式(design pattern),是泛函编程中最重要的编程概念,因而很多行内人把FP又称为Monadic Programming.这其中 ...

  7. Python装饰器与面向切面编程

    今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...

  8. iOS 并发编程指南

    iOS Concurrency Programming Guide iOS 和 Mac OS 传统的并发编程模型是线程,不过线程模型伸缩性不强,而且编写正确的线程代码也不容易.Mac OS 和 iOS ...

  9. NodeJS的异步编程风格

    NodeJS的异步编程风格 http://www.infoq.com/cn/news/2011/09/nodejs-async-code NodeJS运行环境因其支持Javascript语言和异步编程 ...

  10. 通过实例让你真正明白mapreduce---填空式、分布(分割)编程

    本文链接:http://www.aboutyun.com/thread-8303-1-1.html 问题导读: 1.如何在讲mapreduce函数中的字符串等信息,输出到eclipse控制台?2.除了 ...

随机推荐

  1. 基于VS Code的JSDoc的使用指南

    1. 引言 JSDoc是一个用于 JavaScript 的API文档生成器,可以将文档注释直接添加到源代码中,JSDoc 工具将扫描您的源代码并提供一些操作,例如,生成一个 API 文档 JSDoc官 ...

  2. rnacos v0.1.6版本发布

    rnacos是一个用 rust重新实现的nacos. rnacos比java实现的nacos更轻量.快速.稳定:合适在开发.测试.受资限服务等环境平替nacos服务使用. rnacos v0.1.6 ...

  3. FastJson反序列化3-1.2.25绕过

    在1.2.25中,主要添加了config.checkAutoType(typeName, null)函数,所以从这里开始查看检查逻辑: 为了方便,先看POC: public void byPass1( ...

  4. docker下载mongodb镜像并启动容器

    1.查找mongodb相关镜像 docker search mongo 找到相关的镜像进行拉取,如果不指定版本,默认下载最新的mongoDB.建议自己先查找需要那个版本后在进行拉取,因为mongoDB ...

  5. KingbaseES 使用百分比函数获取中位数

    客户从Oracle数据库迁移至KingbaseES数据库,应用中使用MEDIAN函数来求中位数.KingbaseES数据库中没有MEDIAN函数,但可以通过百分比函数来实现相应的功能. MEDIAN ...

  6. 【Java面试题】SpringMVC

    九.SpringMVC 63)SpringMVC 的流程 a.用户向服务器发送请求,请求被 SpringMVC 前端控制器 DispatchServlet 捕获: b.DispatcherServle ...

  7. #决策单调性dp,分治#LOJ 6039「雅礼集训 2017 Day5」珠宝

    题目传送门 分析 观察到这个0/1背包中单个物品的体积不超过300,考虑分体积考虑. 设 \(dp[i]\) 表示容量大小为 \(i\) 的背包能获得的最大价值, \(dp[i]=\max\{dp[i ...

  8. 使用 Debian、Docker 和 Nginx 部署 Web 应用

    前言 本文将介绍基于 Debian 的系统上使用 Docker 和 Nginx 进行 Web 应用部署的过程.着重介绍了 Debian.Docker 和 Nginx 的安装和配置. 第 1 步:更新和 ...

  9. 2024最新AIGC系统ChatGPT网站源码,GPTs应用,Ai绘画网站源码

    一.前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型+国内AI全模型.本期针对源码系统整体测试下来非常完美,那么 ...

  10. 从模型到部署,教你如何用Python构建机器学习API服务

    本文分享自华为云社区<Python构建机器学习API服务从模型到部署的完整指南>,作者: 柠檬味拥抱. 在当今数据驱动的世界中,机器学习模型在解决各种问题中扮演着重要角色.然而,将这些模型 ...