使用GORM搭建大模型工具栈后端| 豆包MarsCode AI 刷题

32 阅读4分钟

前言

需求来源于,需要快速配置大语言模型工具调用时所需要的工具。

ER图设计

实体与属性

  1. Agents

    • AgentID (主键)
    • ModelName
    • IsToolCapable
    • CreatedAt
    • UpdatedAt
  2. Tools

    • ToolID (主键)
    • ToolName
    • Description
    • ParameterDescription
    • Version
    • CreatedAt
    • UpdatedAt
  3. AgentToolUsages

    • UsageID (主键)
    • AgentID (外键)
    • ToolID (外键)
    • CalledAt
    • CompletionContent

关系

  • AgentsAgentToolUsages 之间存在一对多关系,即一个Agent可以有多次Tool使用记录。
  • ToolsAgentToolUsages 之间也是一对多关系,即一个Tool可以被多个Agents多次调用。
  • 综上 Agents 和 Tools 具备多对多关系。

ER图

这个ER图的布局大致如下:

  • Agents 实体有一个向 AgentToolUsages 的连接,表示一个Agent可以关联到多个使用记录。
  • Tools 实体也有一个向 AgentToolUsages 的连接,表示一个Tool可以被多次使用。
  • AgentToolUsages 通过包含 AgentIDToolID 作为外键,建立了与 AgentsTools 的多对一联系。

图示表示:

image.png

数据库建表

1. Agent 表设计

这张表用于存储具备工具调用能力的大模型的基本信息。

CREATE TABLE Agents (
    AgentID INT AUTO_INCREMENT PRIMARY KEY,
    ModelName VARCHAR(255) NOT NULL,
    IsToolCapable BOOLEAN NOT NULL DEFAULT FALSE,
    CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
    UpdatedAt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
  • ModelName:模型的名称。
  • IsToolCapable:标识该模型是否具备工具调用能力,使用布尔值。
  • CreatedAtUpdatedAt:记录创建和更新时间。

2. Tool 表设计

这张表用于存储可供选择的工具的详细信息。

CREATE TABLE Tools (
    ToolID INT AUTO_INCREMENT PRIMARY KEY,
    ToolName VARCHAR(255) NOT NULL,
    Description TEXT,
    ParameterDescription TEXT,
    Version VARCHAR(50),
    CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
    UpdatedAt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
  • ToolName:工具的名称。
  • Description:对工具的描述。
  • ParameterDescription:参数的描述,可能为JSON格式存储复杂的参数结构。
  • Version:工具的版本号。

3. AgentToolUsage 表设计

这张表用于记录大模型与工具之间的调用关系及详情。

CREATE TABLE AgentToolUsages (
    UsageID INT AUTO_INCREMENT PRIMARY KEY,
    AgentID INT NOT NULL,
    ToolID INT NOT NULL,
    CalledAt DATETIME DEFAULT CURRENT_TIMESTAMP,
    CompletionContent TEXT,
    FOREIGN KEY (AgentID) REFERENCES Agents(AgentID),
    FOREIGN KEY (ToolID) REFERENCES Tools(ToolID)
);
  • AgentIDToolID:分别引用AgentsTools表的主键。
  • CalledAt:记录调用的时间。
  • CompletionContent:调用补全的具体内容,可能包括请求和响应的详细数据。

额外的设计注意事项

  • 外键约束:通过外键确保数据的完整性,当删除Agent或Tool时,应考虑对应用关系的处理策略(例如使用ON DELETE CASCADE)。
  • 性能优化:为经常查询的字段(如ToolNameModelName)设置索引,优化查询效率。
  • 安全和权限管理:在应用层面确保只有授权用户可以访问或修改数据。

GORM的软删除机制

如果遇到软删除出错,可以修改表结构,添加DeletedAt字段

项目构建

基于你提供的表结构,我们可以调整后端服务以连接MySQL数据库并使用Go语言的GORM框架进行操作。这包括模型定义、数据库迁移和基本CRUD操作的实现。下面是具体的步骤:

1. 设置数据库连接

首先确保你的Go环境中已经安装了GORM和MySQL驱动。如果还没有安装,可以通过以下命令安装:

go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

然后创建一个main.go文件,并设置数据库连接:

package main

import (
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "log"
)

func main() {
    dsn := "username:password@tcp(localhost:3306)/your_database?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        log.Fatalf("Error connecting to database: %v", err)
    }

    log.Println("Connected to the database successfully.")
    
    // 这里可以添加模型迁移和CRUD操作代码
}

2. 定义模型

根据表结构,定义相应的Go结构体:

type Agent struct {
    gorm.Model
    ModelName    string
    IsToolCapable bool
}

type Tool struct {
    gorm.Model
    ToolName            string
    Description         string
    ParameterDescription string
    Version             string
}

type AgentToolUsage struct {
    gorm.Model
    AgentID         uint
    ToolID          uint
    CalledAt        time.Time
    CompletionContent string
    Agent           Agent `gorm:"foreignKey:AgentID"`
    Tool            Tool `gorm:"foreignKey:ToolID"`
}

3. 数据库迁移

使用GORM的自动迁移功能来创建或更新数据库表结构:

func main() {
    // 前面的数据库连接代码...

    // 迁移模式
    if err := db.AutoMigrate(&Agent{}, &Tool{}, &AgentToolUsage{}); err != nil {
        log.Fatalf("Error migrating database: %v", err)
    }

    log.Println("Database migrated successfully.")
}

4. CRUD操作

一旦模型和数据库连接设置完毕,你可以执行基本的CRUD操作:

  • 创建记录
func createAgent(db *gorm.DB, agent *Agent) {
    result := db.Create(agent)
    if result.Error != nil {
        log.Fatalf("Error creating agent: %v", result.Error)
    }
}

func createTool(db *gorm.DB, tool *Tool) {
    result := db.Create(tool)
    if result.Error != nil {
        log.Fatalf("Error creating tool: %v", result.Error)
    }
}
  • 查询记录
func getAgents(db *gorm.DB) {
    var agents []Agent
    result := db.Find(&agents)
    if result.Error != nil {
        log.Fatalf("Error finding agents: %v", result.Error)
    }
    for _, agent := range agents {
        log.Printf("Agent: %v\n", agent)
    }
}

5. 运行程序

将所有代码片段整合到main.go文件中,确保数据库配置正确,然后在终端运行:

go run main.go

Pasted image 20241127195842.png

成功运行且获得结果,其他的开发可在此基础上进行。