ASP.NET Core开发Chatbot API

在这里插入图片描述

本文介绍基于ASP.NET Core的Chatbot Restful API开发,通过调用大语言模型的SDK,完成一个简单的示例。并且通过容器化进行部署.

安装

首先需要安装.NET环境,笔者在Ubuntu 22.04通过二进制包进行安装,Windows和Mac下都有installer可以用. 选择的版本是.NET 8.

技术栈

我们分析一下要用到的技术栈,想要达到一个基本的demo需求,需要实现API,以及数据的查询存储,以及快速搭建运行环境.
因此我们选择postgresql存储数据,docker容器化实现快速部署. LLM服务选用了OpenAI.

Solution

首先创建一个solution,可以使用如下命令,或者使用IDE.

dotnet new sln

然后新建webapi工程并添加到solution中

mkdir WebApi
cd WebApi
dotnet new webapi
cd ..
dotnet sln add WebApi

完成创建后可以尝试restore并且简单build一下确认环境是否正常

dotnet restore
dotnet build

创建控制器

新建的webapi工程默认给了一个Program.cs

var builder = WebApplication.CreateBuilder(args);// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();var app = builder.Build();// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{app.UseSwagger();app.UseSwaggerUI();
}app.UseHttpsRedirection();var summaries = new[]
{"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};app.MapGet("/weatherforecast", () =>
{var forecast =  Enumerable.Range(1, 5).Select(index =>new WeatherForecast(DateOnly.FromDateTime(DateTime.Now.AddDays(index)),Random.Shared.Next(-20, 55),summaries[Random.Shared.Next(summaries.Length)])).ToArray();return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi();app.Run();record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

这个代码模板已经实现了一个简单的API,但不是我们需要的基于controller的模式,为了使用controller,我们还要安装一些依赖包.

dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet tool uninstall -g dotnet-aspnet-codegenerator
dotnet tool install -g dotnet-aspnet-codegenerator
dotnet tool update -g dotnet-aspnet-codegenerator

Microsoft官方tutorial中给出的是:

dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools
dotnet tool uninstall -g dotnet-aspnet-codegenerator
dotnet tool install -g dotnet-aspnet-codegenerator
dotnet tool update -g dotnet-aspnet-codegenerator

因为我们不使用EntityFrameworkCore,所以去掉了关于EntityFrameworkCore的引用.

然后是创建controller,例如我们命名为ChatController:

dotnet aspnet-codegenerator controller -name ChatController -api -outDir Controllers

创建后,我们可以得到ChatController.cs文件,稍作修改如下

using Microsoft.AspNetCore.Mvc;namespace WebApi.Controllers;[Route("api/[controller]")]
[ApiController]
public class ChatController(IChatService chatService) : ControllerBase
{[HttpPost][Route("[action]")]public ActionResult<ChatResponse> Completions([FromBody] ChatRequest request){var input = request.Text;var result = chatService.Complete(request);return Ok(result);}
}

这时,如果我们直接运行工程,会发现在swagger的页面中,找不到刚才添加的Chat endpoint,因为还需要一些配置
Program.cs中,我们需要让服务映射我们新增的controller.

builder.Services.AddControllers();
app.MapControllers();

上面是两行需要增加的代码,使整个Program.cs看起来这样

var builder = WebApplication.CreateBuilder(args);// Add services to the container.
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddControllers();var app = builder.Build();// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{app.UseSwagger();app.UseSwaggerUI();
}app.UseHttpsRedirection();
app.MapControllers();//entry point
app.Run();

这时,再运行就会发现swagger中已经有相关的endpoint。

OpenAI SDK

使用OpenAI SDK非常简单,直接安装依赖包

dotnet add package OpenAI-DotNet --version 8.3.0

准备好一个Open AI的key,配置到环境变量中,创建一个Factory获取ChatClient(这是和OpenAI交互的客户端). 笔者使用的模型是gpt-3.5-turbo,单纯是实惠,lol.

public abstract class OpenAiClientFactory
{public static ChatClient Create(){var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY")?? throw new InvalidOperationException("OpenAI API key not set");return new ChatClient("gpt-3.5-turbo", apiKey);}
}

有了ChatClient后,就可以进行交互了. 这里涉及到的知识有AI对话点角色问题,涉及到3个角色:

  1. system
  2. assistant
  3. user

相关的概念可以查看文档.
进行一次AI对话就很方便了,直接调用complete方法即可

var prompt = $"""You are an NLU expert help to do intent recognition, slot filling work. Now you are going to understand user input then give a proper result.""";
var systemChatMessage = new SystemChatMessage(prompt);
var userChatMessage = new UserChatMessage(input);
var response = chatClient.CompleteChat([systemChatMessage, userChatMessage]);

这是一个模板代码,可以按照自己的需求修改.

容器化

为了快速运行,可以在项目中增加一个Dockrfile

FROM mcr.microsoft.com/dotnet/sdk:8.0EXPOSE 5114COPY . /appWORKDIR /appRUN dotnet restore && dotnet buildCMD [ "dotnet","run","--project","./WebApi" ]

通过docker快速打包后就能在所有支持docker的平台上快速演示demo.
在容器化方面,我们还可以使用docker compose来把数据库也和主程序一起启动。

Docker Compose 是 Docker 官方编排工具,用于定义和运行多容器 Docker 应用程序。使用 Docker Compose,你可以通过一个 YAML 文件来配置你的应用服务,然后使用一个简单的命令来启动和停止所有服务。

Docker Compose 的主要特点包括:

  1. 多容器编排:可以定义多个容器服务,并管理它们之间的依赖关系。

  2. 服务隔离:每个服务运行在独立的容器中,可以单独配置环境变量、卷挂载、网络等。

  3. 一键部署:通过 docker-compose up 命令,可以一次性启动配置文件中定义的所有服务。

  4. 版本控制:Docker Compose 文件(通常是 docker-compose.yml)可以被版本控制系统跟踪,方便团队协作和持续集成。

  5. 环境一致性:在开发、测试和生产环境中使用相同的配置文件,确保环境一致性。

  6. 网络管理:可以定义服务之间的网络连接,使得服务之间可以通过服务名进行通信。

  7. 数据卷管理:可以定义数据卷,实现数据的持久化和共享。

  8. 扩展性:支持通过环境变量和扩展文件来扩展配置。

  9. 命令行工具:提供了丰富的命令行工具,用于管理服务的生命周期,如启动、停止、重建、日志查看等。

一个基本的 docker-compose.yml 文件示例如下:

version: '3'
services:web:image: "nginx:latest"ports:- "80:80"volumes:- "/var/www:/usr/share/nginx/html"depends_on:- dbdb:image: "postgres:latest"environment:POSTGRES_DB: "mydb"POSTGRES_USER: "user"POSTGRES_PASSWORD: "password"

在我们的例子中,还需要一个功能,就是在docker启动的时候,需要执行一段sql脚本初始化数据库,这个需求postgresql的image已经考虑到,只需要把要执行的脚本映射到一个特殊的路径即可。映射后,在container启动的时候,会执行sql.

- ./db.sql:/docker-entrypoint-initdb.d/init.sql

那么最终我们的docker-compose文件可能是这样:

version: '3'
services:web:build:context: .dockerfile: Dockerfileenvironment:- ConnectionStrings__DefaultConnection=Host=db;Port=5432;Database=db;Username=postgres;- ASPNETCORE_ENVIRONMENT=Development- OPENAI_API_KEY=sk-1234567890abcdef1234567890abcdef # REPLACE WITH YOUR OPENAI KEYports:- "5000:5000"depends_on:- dbdb:image: bitnami/postgresql:latestcontainer_name: pg-containerrestart: alwaysenvironment:POSTGRES_USER: postgresALLOW_EMPTY_PASSWORD: yesPOSTGRES_DB: dbvolumes:- ./db.sql:/docker-entrypoint-initdb.d/init.sqlports:- "5432:5432"

总结

使用ASP.NET Core开发restful api相当方便,而借助容器的强大功能,部署到云环境进行快速验证也得以实现.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/57879.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

终止,半成收入来自海外,收入可持续性被质疑

芬尼科技终止原因如下&#xff1a;芬尼科技4年期间经历了两次IPO失败&#xff0c;公司半成收入来自海外&#xff0c;然而公司泳池收入面临欧洲地区冲突冲击及德国新节能措施影响。交易所质疑其收入是否具有可持续性。 作者&#xff1a;Eric 来源&#xff1a;IPO魔女 9月25日&a…

使用HIP和OpenMP卸载的Jacobi求解器

Jacobi Solver with HIP and OpenMP offloading — ROCm Blogs (amd.com) 作者&#xff1a;Asitav Mishra, Rajat Arora, Justin Chang 发布日期&#xff1a;2023年9月15日 Jacobi方法作为求解偏微分方程&#xff08;PDE&#xff09;的基本迭代线性求解器在高性能计算&#xff…

Webserver(2)GCC

目录 安装GCCVScode远程连接到虚拟机编写代码gcc编译过程gcc与g的区别Xftp连接虚拟机上传文件 安装GCC sudo apt install gcc g查看版本是7.5 touch test.c创建代码 但是在虚拟机中写代码很不方便 VScode远程连接到虚拟机编写代码 gcc test.c -o app在虚拟机中用gcc编译的…

AtCoder ABC376A-D题解

个人觉得 ABC 变得越来越难了/kk/kk/kk 比赛链接:ABC376 Problem A: Code #include <bits/stdc.h> using namespace std; int main(){int N,C;cin>>N>>C;for(int i1;i<N;i)cin>>T[i];int ans0,pre-1e5;for(int i1;i<N;i){if(T[i]-pre>C){…

APP专项测试-冷启动-流量-电量-内存

1、响应时间 1.1怎么获取冷启动时间&#xff08;热启动&#xff0c;就是后台不关后台再次打开&#xff09; 方法一 1.2怎么获取包名 与 启动页 方法三soloPi&#xff1a;启动时间(用户角度出发&#xff0c;页面差异进行计算时间)&#xff1a; 然后默认配置。点击开始录制 1开…

未来汽车驾驶还会有趣吗?车辆动力学系统简史

未来汽车驾驶还会有趣吗&#xff1f;车辆动力学系统简史 本篇文章来源&#xff1a;Schmidt, F., Knig, L. (2020). Will driving still be fun in the future? Vehicle dynamics systems through the ages. In: Pfeffer, P. (eds) 10th International Munich Chassis Symposiu…

高边坡稳定安全监测预警系统解决方案

一、项目背景 高边坡的滑坡和崩塌是一种常见的自然地质灾害&#xff0c;一但发生而没有提前预告将给人民的生命财产和社会危害产生严重影响。对高边坡可能产生的灾害提前预警、必将有利于决策者采取应对措施、减少和降低灾害造成的损失。现有的高边坡监测技术有人工巡查和利用测…

python3的基本数据类型:字符串的其他操作

一. 简介 前面文章学习了 python3 中字符串的创建&#xff0c;连接与转化。文章如下&#xff1a; 本文继续来学习 python3 中字符串的其他操作。 二. python3 的基本数据类型&#xff1a;字符串的其他操作 1. 字符转义 python3 中使用反斜杠 \ 转义特殊字符&#xff0c;它…

Docker 搭建mysql

拉取mysql镜像 docker pull mysql # 拉取镜像 [rooteason ~]# docker pull mysql Using default tag: latest latest: Pulling from library/mysql 72a69066d2fe: Pull complete 93619dbc5b36: Pull complete 99da31dd6142: Pull complete 626033c43d70: Pull complete 37d…

JavaEE----多线程(二)

文章目录 1.进程的状态2.线程的安全引入3.线程安全的问题产生原因4.synchronized关键字的引入4.1修饰代码块4.2修饰实例方法4.3修饰静态方法4.4对象头介绍4.5死锁-可重入的特性 5.关于死锁的分析总结5.1死锁的分析5.2死锁成因的必要条件5.3死锁的解决方案 1.进程的状态 public…

网站被浏览器提示“不安全”,如何快速解决

当网站被浏览器提示“不安全”时&#xff0c;这通常意味着网站存在某些安全隐患&#xff0c;需要立即采取措施进行解决。 一、具体原因如下&#xff1a; 1.如果网站使用的是HTTP协议&#xff0c;应立即升级HTTPS。HTTPS通过使用SSL证书加密来保护数据传输&#xff0c;提高了网…

leetcode 504.七进制数

1.题目要求: 2.题目代码: class Solution { public:string convertToBase7(int num) {string s;int n abs(num);if(num 0){s.push_back(0);return s;}//采用迭代法&#xff0c;对基数进行求余while(n){s.push_back(n % 7 0);n / 7;}if(num < 0){s.push_back(-);}//反转字…

java对接U9C接口

使用java对接U9C的svn接口&#xff0c;说起来也不复杂&#xff0c;走过了路才敢这么说&#xff0c;大致步骤如下&#xff1a; 1.找到接口地址 http://U9地址/Services/***.svc,打开接口地址&#xff0c;如下显示为正常 2.确定需要的参数 接口开发前需要大致了解哪些是必须的…

Flux危,SD 3.5王者归来!个人可以免费商用!

StabilityAI最新发布了Stable Diffusion 3.5&#xff0c;这次公开发布包括多个模型&#xff0c;包括Stable Diffusion 3.5 Large和Stable Diffusion 3.5 Large Turbo。此外&#xff0c;Stable Diffusion 3.5 Medium将于10月29日发布。这些模型因其大小而具有高度的可定制性&…

状态栏黑底白字后如何实现圆角以及固定状态栏

如何实现如下效果: 上述是将状态栏实现黑底白字+圆角+状态栏固定的逻辑 具体代码patch如下: From 6a3b8ed5d3f49a38d8f9d3e488314a66ef5576b8 Mon Sep 17 00:00:00 2001 From: andrew.hu <andrew.hu@quectel.com> Date: Fri, 18 Oct 2024 16:43:49 +0800 Subject: [P…

跟《经济学人》学英文:2024年10月19日这期 Why the world is so animated about anime

Why the world is so animated about anime Japan’s cartoons have conquered its screens, and more 为什么世界对动漫如此热衷 animated&#xff1a;热衷的&#xff1b;生动的&#xff1b;活泼的&#xff1b;活跃的 anime&#xff1a;美 [ˈnɪmeɪ] 动漫 原文&#xff…

Java程序员如何获得高并发经验?

高并发编程 提到并发编程很多人就会头疼了&#xff1b;首先就是一些基础概念&#xff1a;并发&#xff0c;并行&#xff0c;同步&#xff0c;异步&#xff0c;临界区&#xff0c;阻塞&#xff0c;非阻塞还有各种锁全都砸你脸上&#xff0c;随之而来的就是要保证程序运行时关键…

海外著名新闻门户媒体软文发稿之华盛顿独立报-大舍传媒

在当今全球化的时代&#xff0c;信息传播的速度和范围达到了前所未有的程度。对于企业和个人而言&#xff0c;如何在国际舞台上有效地展示自己、传递信息&#xff0c;成为了一项至关重要的任务。而海外媒体发稿&#xff0c;特别是通过像华盛顿独立报这样的知名新闻门户&#xf…

宝塔安装RabbitMQ失败解决方法|宝塔安装RabbitMQ提示elang环境没有解决方法

目录 一、前言二、问题排查三、问题解决四、再次修改密码 一、前言 安装完宝塔&#xff0c;然后在软件商店安装RabbitMQ的时候&#xff0c;安装完一直显示RabbitMQ未启动 服务器&#xff1a;阿里云 系统&#xff1a;Alibaba Cloud Linux 3.2104 LTS 64位 二、问题排查 安装完…

雷池社区版那么火,为什么站长都使用雷池社区版??

雷池社区版是长亭科技开发的一款免费开源的 Web 应用防火墙&#xff08;WAF&#xff09;&#xff0c;具有诸多优势&#xff0c;因此值得使用。 防护效果强大。能够检测并防御各种网络攻击&#xff0c;包括 SQL 注入、跨站脚本&#xff08;XSS&#xff09;、跨站请求伪造&#x…