跳到内容


那么你想向 CodeProject.AI 添加新模块

CodeProject.AI 允许开发人员轻松地将新的 AI 功能添加到现有系统中,而无需与工具和库进行斗争。

如果您乐于遵循一个缠绕扭曲的迷宫,即无穷无尽的库、工具、解释器、包管理器以及所有其他有趣的玩意儿,这些玩意儿有时会让编码的乐趣如同洗碗一样,那么为应用程序添加 AI 功能相对来说是比较直接的。

CodeProject.AI 通过提供一个框架来管理这些痛点,让这一切变得更容易,这样您就可以专注于您的代码,而不是工具。

聚合,而非添加

我们说“添加”,但“聚合”更准确。有大量的 AI 项目正在积极开发和改进中,我们希望允许开发人员将这些现有的、不断发展的 AI 模块或应用程序尽可能轻松地集成到 CodeProject.AI 生态系统中。这可能意味着集成一个控制台应用程序、一个 Python 模块或一个 .NET 项目。

对于开发,您只需要做:

  1. 查找或编写您想要包含的代码。这可能是在线找到的项目、您自己编写想包含的项目,或者您可以从一个新项目开始。
  2. 编写一个适配器,该适配器负责您编写或包含在模块中的 AI 代码与 CodeProject.AI 服务器本身之间的通信。
  3. 提供一个 modulesettings.json 文件,该文件描述了模块,并向 CodeProject.AI 提供有关如何启动模块的指令。
  4. 创建一个安装脚本(通常很短)来设置先决条件(下载模型,安装必要的运行时)。
  5. (可选但推荐)创建一个简单的 explore.html 文件来测试您的模块,并与 CodeProject.AI Explorer 集成。
  6. (可选但推荐)创建一个打包器,以便您的模块可以被打包并包含在主 CodeProject.AI 注册表中。

我只想写代码!

如果您想直奔主题,直接开始编写模块,请阅读 添加您自己的 Python 模块添加您自己的 .NET 模块

CodeProject.AI 架构(30 秒内了解)

CodeProject.AI 是一个基于 HTTP 的 REST API 服务器。它基本上就是一个 Web 服务器,您的应用程序向其发送请求。这些请求被放入一个队列,分析服务(又名模块)会从它们知道如何服务的队列中提取请求。每个请求随后被处理(基于请求执行 AI 操作),并将结果发送回 API 服务器,API 服务器再将其发送回发出初始调用的应用程序。

假设我们有 3 个分析模块:使用 Python 3.7 的人脸识别、使用 .NET 的物体检测和使用 Python 3.10 的文本分析。

CodeProject.AI Architecture

  1. 应用程序向 API 服务器发送请求
  2. API 服务器将请求放入相应的队列
  3. 后端模块轮询它们感兴趣的队列,抓取一个请求并进行处理
  4. 后端模块随后将结果发送回 API 服务器
  5. API 服务器然后将结果发送回调用应用程序

CodeProject.AI API 服务器独立于调用应用程序运行。

将 CodeProject.AI 视为数据库服务器或您正在运行的任何其他后台服务:它作为服务或守护进程运行,您向它发送命令,它会响应结果。您不必为它的业务细节烦恼,只需专注于您应用程序的核心业务。

模块如何工作

这是一张复杂的图,解释了模块

The Module System

从左到右

  1. CodeProject.AI 服务器启动并监控分析模块。
  2. 有一组分析模块,它们从 CodeProject.AI 服务器的队列中获取请求并进行处理。每个模块包含:

    1. 一个适配器,用于在模块和 CodeProject.AI 服务器之间进行通信;
    2. 模块本身。
  3. 有许多运行时(例如 Python 或 .NET),模块在这些运行时下运行。多个模块可以共享一个给定的运行时:我们(还没有)沙箱化。

每个模块的适配器通常与模块在相同的运行时(甚至经常在相同的进程)中运行,但这并非必需。您可以轻松编写一个简单的 Python 脚本作为适配器,从 .NET 模块发送和接收数据。

设置:模型和运行时

设置脚本应负责下载所需的 AI 模型以及安装任何必要的运行时。默认情况下,我们目前确保 Python 3.7 和 3.9,以及 .NET 7 已安装并可供所有人使用。

对于 Python 模块,设置脚本通常还会确保安装任何 Python 包。

应提供一个 Windows BAT 文件和一个 Linux/macOS bash 文件用于设置,具体取决于您支持的平台。

选择要添加的代码

在考虑哪些模块适合包含在 CodeProject.AI 中时,请考虑以下几点:

  • 代码是否自包含?模块需要的附带信息越少越好。
  • 模块是否提供简单易调用的 API?例如,Python 模块可以提供一个您调用的函数,或者 Go 应用程序可以提供一个简单的控制台应用程序体验,允许从命令行调用它。
  • 模块能否离线运行?需要互联网连接的模块在所有环境中可能无法正常工作,或者可能不被某些需要确保其数据保留在自己环境中的用户接受。
  • 如果模块更新了,集成更新后的代码有多难?对原始代码的修改越少,以后更新模块就越容易。如果可能,请将代码更改限制在您的适配器中。

编写适配器

模块的适配器有一个任务:在 CodeProject.AI 和模块之间传递通信。

一个例子可能是用 Python 编写的模块。您有一个 my_module.py 文件,其中包含您的 AI 推理代码,并且该模块中可能有一个 predict 方法。适配器将:

  • 通过查询环境变量或检查 modulesettings.json 文件中的值来设置模块。
  • 处理请求(在本例中,调用 my_module.py 文件中的 predict 方法)并返回结果。

如果可能,应避免修改模块代码。适配器将模块与 CodeProject.AI 隔离开来,因此如果模块更新了,可以轻松集成更新,适配器(希望)仍然可以工作。如果不行,调整适配器以适应更改的 API、数据格式或方法签名应该是一个快速而简单的修复。

modulesettings.json 文件

CodeProject.AI 服务器在启动时将加载模块目录中的 modulesettings.json 文件及其变体。这些文件由 NET 配置系统按以下顺序读取:

  • modulesettings.json - 通用和默认配置值。
  • modulesettings.<production|development>.json - 生产或开发值。
  • modulesettings.<platform>.json - 特定于运行时操作系统(platform)的值。目前支持:windowslinuxdockermacosmacos-arm
  • modulesettings.<platform>.<production|development>.json - 特定于平台和环境的值。

每个文件中的设置将覆盖任何先前加载的设置,允许您在每个变体中仅指定您需要为给定场景调整的设置。

modulesettings.json schema

modulesettings.json 文件在 Modules 部分定义了模块的通用元数据。这些元数据包括有关以下信息:

  • 模块的名称和描述;
  • 是否应在启动时运行;
  • 模块应如何启动。a. 指定一个 runtime 和一个 filePath。然后将使用给定的运行时启动 filepath 中指定的模块。目前支持的运行时包括 dotnetpython37python38python39。添加更多 Python 运行时非常简单。b. 或者,指定一个要运行的完整命令以启动模块。
  • 模块可以运行的平台列表。目前支持的有 windowslinuxdockermacosmacos-arm
  • 模块将处理的队列名称。这可以是模块希望使用的任何名称。
  • CodeProject.AI 服务器将为此模块公开的端点(RouteMaps)。例如,端点可以是 GET 调用 image/detect_animals,它将映射到 *GET: localhost:32168/v1/image/detect_animal*。此端点的输入和输出也包含在此处,但仅用于文档目的。

一个例子是

JSON
{
  "Modules": {
    "PortraitFilter": {
      "Name": "Portrait Filter",
      "Version": "1.0.0",

      "PublishingInfo" : {
        "Description": "Provides a depth-of-field (bokeh) effect on images. Great for selfies.", 
        "Category": "Image Processing"
      },

      "LaunchSettings": {
        "AutoStart": true,
        "FilePath": "PortraitFilter.exe",
        "Runtime": "dotnet"
      },

      "EnvironmentVariables": {
      },

      "GpuOptions" : {
        "InstallGPU": true,
        "EnableGPU": true
      },

      "InstallOptions" : {
        "Platforms": [ "windows" ],     // errors with Microsoft.ML.OnnxRuntime.NativeMethods in macOS, and System.Drawing issues in Linux
        "ModuleReleases": [             // Which server version is compatible with each version of this module.
          { "ModuleVersion": "1.0",   "ServerVersionRange": [ "2.5.0", "" ], "ReleaseDate": "2022-06-01" }
        ]
      },

      "RouteMaps": [
        {
          "Name": "Portrait Filter",
          "Route": "image/portraitfilter",
          "Method": "POST",
          "Command": "filter",
          "Description": "Blurs the background behind the main subjects in an image.",
          "Inputs": [
            {
              "Name": "image",
              "Type": "File",
              "Description": "The image to be filtered."
            },
            {
              "Name": "strength",
              "Type": "Float",
              "Description": "How much to blur the background (0.0 - 1.0).",
              "MinValue": 0.0,
              "MaxValue": 1.0,
              "DefaultValue": 0.5
            }
          ],
          "Outputs": [
            {
              "Name": "success",
              "Type": "Boolean",
              "Description": "True if successful."
            },
            {
              "Name": "filtered_image",
              "Type": "Base64ImageData",
              "Description": "The base64 encoded image that has had its background blurred."
            }
          ]
        }
      ]
    }
  }
}

© . All rights reserved.