前言

这是一篇ChatGPT插件开发教程,描述如何使用 ASP.NET Core Minimal API 开发 ChatGPT 插件,以最简单的 Todo List 指导示例作为入门教程。

这个Todo List插件主要功能是以自然语言的方式向ChatGPT发起指令,ChatGPT将根据合适的时机选择调用此插件。例如:我明天下午3点有一个会议,请帮我记录。此时 ChatGPT将会根据插件的元数据功能描述,然后选择调用插件,将明天下午3点有一个会议通过API记录到待办列表中。

环境准备

首先你需要有一个开通了 Plugins 模块的账号,然后你才能进行调试使用。如果你没有可以在这里申请加入等待列表。说明一下,我是Plus用户,我在提交了申请列表大概过了2-3周左右收到的开通邮件。

在提交申请的时候,最好选择 "I am a developer and want to build a plugin",然后填写较为充分的理由,这样更容易通过一些。

开通完成后,你可以在界面上看到列表中出现 Model 中可以选择 Plugins 选项。

概念说明

整体上,构建 ChatGPT 插件需要3个步骤,

  1. 构建服务端 API
  2. 启用 Swagger OpenApi 接口描述
  3. 创建一个插件清单文件,描述插件元数据信息

完成之后,你可以在界面上打开 Plugin Store,然后选择 Develop your own Plugin,填入本地 Api 地址即可。

使用 ASP.NET Core Minimal 开发服务端 API

为了简单起见,我们的接口不进行授权(No Auth),主要分为几个部分:

  1. 编写ai-plugin.json元数据文件
  2. 启用跨域
  3. 启用Swagger,并详细描述接口参数
  4. 编写接口代码

编写 ai-plugin.json元数据文件

每个插件都需要一个 ai-plugin.json 文件,该文件需要托管在API的域中。例如,一家名为 example.com 的公司将通过 https://example.com 域访问插件JSON文件,因为这是他们的API托管的地方。

当通过ChatGPT UI安装插件时,ChatGPT会查找位于 /.well-known/ai-plugin.json 的文件,以便和插件进行连接。如果找不到文件,则无法安装插件。对于本地开发,可以使用HTTP,要指向远程服务器,则需要HTTPS。

新建一个 ai-plugin.json 清单文件,填入以下内容:

{
"schema_version": "v1",
"name_for_human": "TODO Plugin (no auth)",
"name_for_model": "todo",
"description_for_human": "Plugin for managing a TODO list, you can add, remove and view your TODOs.",
"description_for_model": "Plugin for managing a TODO list, you can add, remove and view your TODOs.",
"auth": {
"type": "none"
},
"api": {
"type": "openapi",
"url": "http://localhost:5000/openapi.yaml",
"is_user_authenticated": false
},
"logo_url": "http://localhost:5000/logo.png",
"contact_email": "legal@example.com",
"legal_info_url": "http://example.com/legal"
}

内容很简单,需要说明的有2处。

  1. api:url 这个是指向 swagger 的 openapi描述文件,需要在服务端暴露出来。
  2. description_for_model 这个是当用户的指令可能有插件的潜在请求查询时,模型会查看该描述,您可能测试多个提示和描述,以查看哪些最有效。

description_for_model 属性让你可以自由地指导模型如何使用你的插件。总的来说,ChatGPT背后的语言模型非常能够理解自然语言并遵循指令。因此,这是一个很好的地方,可以放置关于插件功能以及模型应该如何正确使用它的一般说明。使用自然语言,最好使用简洁、描述性和客观的语气。您可以查看一些示例,以了解这应该是什么样子。我们建议以“Plugin for ...”,然后枚举API提供的所有功能。

启用跨域

由于是在网页前端调用的本地localhost接口,所以需要接口启用跨域以支持 chat.openai.com 的访问。

在 ASP.NET Core启用跨域很简单。

builder.Services.AddCors(x => x.AddDefaultPolicy(policyBuilder =>
policyBuilder.WithOrigins("https://chat.openai.com").AllowAnyHeader().AllowAnyMethod())); // 省略部分代码 app.UseCors();

启用Swagger,并详细描述接口参数

ChatGPT需要使用OpenAi V3版本,所以需要确保你引用了最新的 Swashbuckle.AspNetCore NuGet包。

builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("openapi", new OpenApiInfo
{
Description = "A plugin that allows the user to create and manage a TODO list using ChatGPT. If you do not know the user's username, ask them first before making queries to the plugin. Otherwise, use the username \"global\".",
Version = "v1",
Title = "TODO Plugin"
});
c.AddServer(new OpenApiServer() { Url = "http://localhost:5000" }); var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
}); //省略部分代码 if (app.Environment.IsDevelopment())
{
app.UseSwagger(x => x.RouteTemplate = "{documentName}.yaml");
app.UseSwaggerUI(x =>
{
x.RoutePrefix = "";
x.SwaggerEndpoint("/openapi.yaml", "TODO Plugin");
});
}

我们配置 RoutePrefix=""以使主页即为swagger默认地址,配置 x.SwaggerEndpoint("/openapi.yaml", "TODO Plugin") 为 OpenAPI文件的访问地址,该地址和 ai-plgion.json中的地址要对应。

API 接口代码

我们使用 Minimal Api 来构建,代码中需要使用 OpenApi规范对参数进行详细描述,这样ChatGPT才能识别的更加准确。


var todos = new Dictionary<string, List<string>>(); app.MapPost("/todos/{username}", (string username, [FromBody] AddTodoRequest request) =>
{
var todo = request.Todo;
if (!todos.ContainsKey(username))
{
todos[username] = new List<string>();
}
todos[username].Add(todo);
return todo;
})
.Produces<string>()
.WithOpenApi(operation =>
{
operation.OperationId = "addTodo";
operation.Summary = "Add a todo to the list";
var parameter = operation.Parameters[0];
parameter.Description = "The name of the user.";
return operation;
}); app.MapGet("/todos/{username}", (string username) =>
Results.Json(todos.TryGetValue(username, out var todo) ? todo : Array.Empty<string>())
)
.Produces<List<string>>()
.WithOpenApi(operation =>
{
operation.OperationId = "getTodos";
operation.Summary = "Get the list of todos"; var parameter = operation.Parameters[0];
parameter.Description = "The name of the user."; operation.Responses["200"].Description = "The list of todos";
return operation;
}); app.MapDelete("/todos/{username}", (string username, [FromBody] DeleteTodoRequest request) =>
{
var todoIdx = request.TodoIdx;
if (todos.ContainsKey(username) && 0 <= todoIdx && todoIdx < todos[username].Count)
{
todos[username].RemoveAt(todoIdx);
}
})
.Produces<List<string>>()
.WithOpenApi(operation =>
{
operation.OperationId = "getTodos";
operation.Summary = "Delete a todo from the list";
operation.Parameters[0].Description = "The name of the user.";
return operation;
}); app.MapGet("/logo.png", () => Results.File("logo.png", contentType: "image/png"))
.ExcludeFromDescription(); app.MapGet("/.well-known/ai-plugin.json", () => Results.File("ai-plugin.json", contentType: "text/json"))
.ExcludeFromDescription(); app.Run(); /// <summary>
/// AddTodoRequest Dto
/// </summary>
/// <param name="Todo">The todo to add to the list.</param>
internal record AddTodoRequest(string Todo); /// <summary>
/// DeleteTodoRequest Dto
/// </summary>
/// <param name="TodoIdx">The index of the todo to delete.</param>
internal record DeleteTodoRequest(int TodoIdx);

测试插件

总结

以上,就是简单的使用 ASP.NET Core minimal api 开发的一个 Todo List插件,功能比较简单,基本上看下代码就懂了。

完整的代码我已经上传到了Github,大家可自行查看。

https://github.com/yang-xiaodong/chatgpt-aspnetcore-plugin

如果你觉得本篇文章对您有帮助的话,感谢您的【推荐】。

ChatGPT Plugin 插件开发:基于 ASP.NET Core Minimal API的更多相关文章

  1. ASP.NET Core Web API下事件驱动型架构的实现(一):一个简单的实现

    很长一段时间以来,我都在思考如何在ASP.NET Core的框架下,实现一套完整的事件驱动型架构.这个问题看上去有点大,其实主要目标是为了实现一个基于ASP.NET Core的微服务,它能够非常简单地 ...

  2. 重温.NET下Assembly的加载过程 ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线

    重温.NET下Assembly的加载过程   最近在工作中牵涉到了.NET下的一个古老的问题:Assembly的加载过程.虽然网上有很多文章介绍这部分内容,很多文章也是很久以前就已经出现了,但阅读之后 ...

  3. ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线

    在上文中,我们讨论了事件处理器中对象生命周期的问题,在进入新的讨论之前,首先让我们总结一下,我们已经实现了哪些内容.下面的类图描述了我们已经实现的组件及其之间的关系,貌似系统已经变得越来越复杂了. 其 ...

  4. 用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(1)

    最近使用vscode比较多. 学习了一下如何在mac上使用vscode开发asp.netcore项目. 这里是我写的关于vscode的一篇文章: https://www.cnblogs.com/cgz ...

  5. 如何基于asp.net core的Identity框架在mysql上作身份验证处理

    首先了解这个概念,我一开始也是理解和掌握基本的概念,再去做程序的开发.Identity框架是微软自己提供,基于.net core平台,可拓展.轻量 级.面向多个数据库的身份验证框架.IdentityS ...

  6. 基于Asp.Net Core的简单社区项目源代码开源

    2019年3月27号 更新版本 本项目基于 ASP.NET CORE 3.0+EF CORE 3.0开发 使用vs2019 +sqlserver 2017(数据库脚本最低支持sql server 20 ...

  7. AServer - 基于Asp.net core Kestrel的超迷你http服务器

    AServer是基于ASP.NET Core Kestrel封装的一个超迷你http服务器.它可以集成进你的Core程序里,用来快速的响应Http请求,而不需要集成整个ASP.NET Core MVC ...

  8. 基于ASP.NET Core 创建 Web API

    使用 Visual Studio 创建项目. 文件->新建->项目,选择创建 ASP.NET Core Web 应用程序. 基于 ASP.NET Core 2.0 ,选择API,身份验证选 ...

  9. 基于ASP.Net Core开发的一套通用后台框架

    基于ASP.Net Core开发一套通用后台框架 写在前面 这是本人在学习的过程中搭建学习的框架,如果对你有所帮助那再好不过.如果您有发现错误,请告知我,我会第一时间修改. 知其然,知其所以然,并非重 ...

  10. 基于ASP.NET Core 3.0快速搭建Razor Pages Web应用

    前言 虽然说学习新的开发框架是一项巨大的投资,但是作为一个开发人员,不断学习新的技术并快速上手是我们应该掌握的技能,甚至是一个.NET Framework开发人员,学习.NET Core 新框架可以更 ...

随机推荐

  1. Python数据可视化,自适应浏览器

    pyecharts生成的html默认是靠左上显示的需要生成的文件居中显示,且能根据浏览器窗口大小自动调整需要修改html当然,如果你是熟悉html,且只是临时少量生成表格的话,每次生成完后手动修改ht ...

  2. C# DataTable操作,转载

    DataTable 排序   DataRow[] rows = dataTable1.Select("", "ord asc");   DataTable t ...

  3. 英码科技边缘计算智慧工地解决方案——给工地戴上AI“安全帽”

    据统计显示,2021年全国共发生房屋市政工程生产安全事故734起,死亡840人:且近3年来,工地事故数量.死亡人数连续攀升.这不仅仅是一个普通的数字,每个数字都代表一个独特.鲜活的生命.为什么每年会发 ...

  4. Adams-STEP函数

    1 给运动添加函数 例1: step(time,0,0,2,30d) 表示:当0秒时位移为0°,当2秒时位移为30°. 例2: step(time,0,0,0.6,1.7) +step(time,0. ...

  5. pytorch之科学计算

    一.简介 torch作为深度学习的主流框架,其根本在于1.具有强大的GPU加速的张量计算功能.2.包含自动求导系统的深度神经网络.自动求导功能由torch.Autograd模块实现,而科学计算部分则直 ...

  6. egret 根接受分发

    egret.MainContext.instance.addEventListener("firstEnter",this.torunGame,this); egret.MainC ...

  7. Linux部分文件管理类命令

    1.创建空文件和刷新时间 touch命令可以用来创建空文件或刷新文件的时间 touch [OPTION]... FILE... 选项: -a 仅改变atime和ctime -m 仅改变mtime和ct ...

  8. MyBatis详细代码来啦!

    家人们,改代码改到现在真的绝了,终于是改出来了,但是对于某些判断性的小问题还没写,细节性满满的增删改查终于实现啦! 目录结构 各个文件的代码: //SqlSessionFactoryUtils.jav ...

  9. diyudio 3886 功放机鉴赏

  10. kubernetes核心实战(八)--- service

    13.service 四层网络负载 创建 [root@k8s-master-node1 ~/yaml/test]# [root@k8s-master-node1 ~/yaml/test]# vim m ...