当前位置: 首页 > article >正文

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.0

EXPOSE 5114

COPY . /app

WORKDIR /app

RUN dotnet restore && dotnet build

CMD [ "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:
      - db
  db:
    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: Dockerfile
    environment:
      - ConnectionStrings__DefaultConnection=Host=db;Port=5432;Database=db;Username=postgres;
      - ASPNETCORE_ENVIRONMENT=Development
      - OPENAI_API_KEY=sk-1234567890abcdef1234567890abcdef # REPLACE WITH YOUR OPENAI KEY
    ports:
      - "5000:5000"
    depends_on:
      - db
  db:
    image: bitnami/postgresql:latest
    container_name: pg-container
    restart: always
    environment:
      POSTGRES_USER: postgres
      ALLOW_EMPTY_PASSWORD: yes
      POSTGRES_DB: db
    volumes:
      - ./db.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "5432:5432"

总结

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


http://www.kler.cn/news/368246.html

相关文章:

  • 1通道10GSPS或2通道5G 14 bit数字化仪
  • 【数据库】数据操作语言DML MySQL函数介绍
  • C++线程池手写实现
  • 【Git 】Windows 系统下 Git 文件名大小写不敏感
  • Python4
  • Liunx权限概念及权限管理
  • 算法2—八大常用排序算法(下)
  • 深度探索C++对象模型
  • Unity编辑器制作多级下拉菜单
  • C++二级2023.9题及答案 -- 部分题
  • PHP短视频实训平台系统小程序源码
  • c# Solidworks二次开发---添加属性
  • 【mod分享】极品飞车10魔改模组,全新UI,全新道路,全新建筑,高清植被,全新的道路围栏,全新的天空,体验另一种速度与激情
  • DNS系统和ICMP协议
  • UVM初学篇 -(22)UVM field_automation 域的自动化机制
  • nfs服务器实验
  • 基于深度学习的语音情感识别与响应
  • C语言 - GNU C 和 ANSI C 之间的差异
  • spring boot 整合Knife4j
  • OpenStack将运行的系统导出 QCOW2 镜像并导入阿里云
  • D - Many Segments 2(AtCoder Beginner Contest 377)
  • 【Flask】二、Flask 路由机制
  • 三种SPI机制的了解及使用
  • linux创建自定义服务部署项目
  • 如何使用Golang的gomail库实现邮件发送功能
  • 将CSDN博客转换为PDF的Python Web应用开发--Flask实战