开发个人Ollama-Chat--5 模型管理 (二)

2024-07-13 1478阅读

开发个人Ollama-Chat–5 模型管理 (二)

ChatGPT

这是该项目的最终效果,使用ollama的open-webui进行人与机器的对话功能,对话的后端服务则完全对接自己开发的Go项目。

开发个人Ollama-Chat--5 模型管理 (二)

如何实现呢?则通过这篇文章,一一给大家剖析后端的原理及功能实现。

ollama-go

开发个人Ollama-Chat--5 模型管理 (二)

根据上图结果,生成的stream响应,就可与open-webUI进行对话,实现ChatGPT的功能效果。

正片开始

文件目录:

├── chat
│   ├── api
│   │   ├── chat.api
│   │   ├── chat.go
│   │   ├── etc
│   │   │   └── chat.yaml
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── internal
│   │   │   ├── config
│   │   │   ├── handler
│   │   │   ├── logic
│   │   │   ├── svc
│   │   │   └── types
│   │   ├── logs
│   │   │   ├── access.log
│   │   │   ├── error.log
│   │   │   ├── severe.log
│   │   │   ├── slow.log
│   │   │   └── stat.log
│   │   └── web
│   │       └── static
│   └── rpc
│       ├── chat
│       │   ├── chat_grpc.pb.go
│       │   └── chat.pb.go
│       ├── chatclient
│       │   └── chat.go
│       ├── chat.go
│       ├── chat.proto
│       ├── etc
│       │   └── chat.yaml
│       ├── go.mod
│       ├── go.sum
│       ├── internal
│       │   ├── config
│       │   ├── logic
│       │   ├── server
│       │   └── svc
│       └── logs
│           ├── access.log
│           ├── error.log
│           ├── severe.log
│           ├── slow.log
│           └── stat.log

5.1 生成 chat model 模型

  • 创建 chat.sql,生成chat相关数据表。字段不可缺少任意一个,否则open-webui无法正常展示

    CREATE TABLE `chat` (
    	`id` bigint unsigned NOT NULL AUTO_INCREMENT,
        `user_id` varchar(255)  NOT NULL DEFAULT '' COMMENT '用户ID',
        `title` varchar(255)  NOT NULL DEFAULT '' COMMENT '标题',
    	`chat` longtext  NOT NULL COMMENT '',
    	`archived` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '',
        `share_id` varchar(255)  NOT NULL DEFAULT '' COMMENT '分享用户ID',
    	`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
    	`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    	PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4;
    
  • 创建prompt.sql,生成prompt相关数据表。字段不可缺少任意一个,否则open-webui无法正常展示

    drop table if exists prompt;
    CREATE TABLE `prompt` (
                              `id` bigint unsigned NOT NULL AUTO_INCREMENT,
                              `command` varchar(255)  NOT NULL DEFAULT '' COMMENT '命令',
                              `user_id` varchar(255)  NOT NULL DEFAULT '' COMMENT '用户ID',
                              `title` varchar(255)  NOT NULL DEFAULT '' COMMENT '标题',
                              `content` longtext  NOT NULL COMMENT '文本',
                              `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
                              `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                              PRIMARY KEY (`id`),
                              UNIQUE KEY `command` (`command`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4;
    
  • 运行模板生成命令 model文件放置在通用目录,和go-zero官方案例不同

    # chat model
    goctl model mysql ddl -src ./model/chat.sql -dir ./model -c
    # prompt model
    goctl model mysql ddl -src ./model/prompt.sql -dir ./model -c
    

    5.2 生成 chat api 服务

    前缀,路由,传参,响应不可变,否则 openui调用失败

    • 创建 chat.api 文件

      type (
      	// 产品创建
      	CreateRequest {
      		UserId   string `json:"userId"`
      		Title    string `json:"title"`
      		Chat     string `json:"chat"`
      		ShareId  string `json:"shareId"`
      		Archived int64  `json:"archived"`
      	}
      	CreateResponse {
      		Id int64 `json:"id"`
      	}
      	// 产品创建
      	// 产品修改
      	UpdateRequest {
      		Chat string `json:"chat"`
      	}
      	UpdateResponse  {}
      	// 产品修改
      	// 产品删除
      	RemoveRequest {
      		Id int64 `json:"id, optional"`
      	}
      	RemoveResponse  {}
      	// 产品删除
      	// 产品详情
      	DetailRequest {
      		Id int64 `json:"id, optional"`
      	}
      	DetailResponse {
      		Id       int64  `json:"id"`
      		UserId   string `json:"userId"`
      		Title    string `json:"title"`
      		Chat     string `json:"chat"`
      		ShareId  string `json:"shareId"`
      		Archived int64  `json:"archived"`
      	}
      	// 产品详情
      	ListRequest  {}
      	// 数组 产品详情
      	ListResponse {
      		Data []DetailResponse `json:"data"`
      	}
      	VersionResponse {
      		Version string `json:"version"`
      	}
      	ChangelogResponse {
      		Changelog string `json:"changelog"`
      	}
      	ConfigResponse {
      		Status                   bool                       `json:"status"`
      		Name                     string                     `json:"name"`
      		Version                  string                     `json:"version"`
      		DefaultLocale            string                     `json:"default_locale"`
      		Images                   bool                       `json:"images"`
      		DefaultModels            interface{}                `json:"default_models"`
      		DefaultPromptSuggestions []DefaultPromptSuggestions `json:"default_prompt_suggestions"`
      		TrustedHeaderAuth        bool                       `json:"trusted_header_auth"`
      	}
      	DefaultPromptSuggestions {
      		Title   []string `json:"title"`
      		Content string   `json:"content"`
      	}
      	ModelReponse {
      		Models []ModelDetail `json:"models"`
      	}
      	ModelDetail {
      		Id         string  `json:"id"`
      		Name       string  `json:"name"`
      		Model      string  `json:"model"`
      		ModifiedAt string  `json:"modified_at"`
      		Size       int64   `json:"size"`
      		Digest     string  `json:"digest"`
      		Details    Details `json:"details"`
      	}
      	Details {
      		Format            string      `json:"format"`
      		Family            string      `json:"family"`
      		Families          interface{} `json:"families"`
      		ParameterSize     string      `json:"parameter_size"`
      		QuantizationLevel string      `json:"quantization_level"`
      	}
      	Prompt {
      		Id      int64  `json:"id"`
      		Command string `json:"command"`
      		UserId  string `json:"user_id"`
      		Title   string `json:"title"`
      		Content string `json:"content"`
      	}
      	PromptResponse {
      		Prompts []Prompt `json:"prompts"`
      	}
      	DefaultModels {
      		Models string `json:"models"`
      	}
      	Chat {
      		ID        string `json:"id"`
      		Title     string `json:"title"`
      		UpdatedAt int    `json:"updated_at"`
      		CreatedAt int    `json:"created_at"`
      	}
      	ChatMessage {
      		Chats Chat `json:"chats"`
      	}
      	NewChatRequest {
      		Chat ChatEntity `json:"chat"`
      	}
      	ChatEntity {
      		Id        string                   `json:"id"`
      		Title     string                   `json:"title"`
      		Models    []string                 `json:"models"`
      		Options   map[string]interface{}   `json:"options,optional"`
      		Messages  []map[string]interface{} `json:"messages,optional"`
      		History   map[string]interface{}   `json:"history,optional"`
      		Tags      []map[string]interface{} `json:"tags,optional"`
      		Timestamp int64                    `json:"timestamp"`
      	}
      	// new chat
      	NewChatEntity {
      		Model    string           `json:"model"`
      		Messages []MessagesEntity `json:"messages"`
      		Options  OptionsEntity    `json:"options"`
      	}
      	MessagesEntity {
      		Role    string `json:"role"`
      		Content string `json:"content"`
      	}
      	OptionsEntity  {}
      	ChatRespone {
      		Text string `json:"text"`
      	}
      	UpdateChatRequest {
      		Chat UpdateChat `json:"chat"`
      	}
      	UpdateChat {
      		Messages []UpdateMessages `json:"messages, optional"`
      		History  UpdateHistory    `json:"history, optional"`
      	}
      	UpdateMessages {
      		Id          string   `json:"id"`
      		ChildrenIds []string `json:"childrenIds"`
      		Role        string   `json:"role"`
      		Content     string   `json:"content"`
      		Timestamp   int64    `json:"timestamp"`
      	}
      	UpdateHistory {
      		Messages  map[string]interface{} `json:"messages"`
      		CurrentId string                 `json:"currentId"`
      	}
      	CompleteRequest {
      		Model    string           `json:"model"`
      		Messages []MessagesEntity `json:"messages"`
      		Stream   bool             `json:"stream"`
      	}
      )
      @server (
      	jwt: Auth
      )
      service Chat {
      	@handler Version
      	get /ollama/api/version returns (VersionResponse)
      	@handler OllTags
      	get /ollama/api/tags returns (ModelReponse)
      	@handler Chat
      	post /ollama/api/chat (NewChatEntity) returns (ChatRespone)
      	@handler Complete
      	post /ollama/v1/chat/completions (CompleteRequest) returns (ChatRespone)
      }
      service Chat {
      	@handler Changelog
      	get /api/changelog returns (ChangelogResponse)
      	@handler Config
      	get /api/config returns (ConfigResponse)
      }
      @server (
      	jwt:    Auth
      	prefix: /api/v1
      )
      service Chat {
      	@handler GetPrompt
      	get /prompts returns (PromptResponse)
      	@handler GetDefaultModels
      	post /configs/default/models (DefaultModels) returns (DefaultModels)
      }
      @server (
      	jwt:    Auth
      	prefix: /api/v1
      )
      service Chat {
      	@handler Create
      	post /chats/new (NewChatRequest) returns (CreateResponse)
      	@handler Update
      	post /chats/:id (UpdateChatRequest) returns (UpdateResponse)
      	@handler Remove
      	delete /chats/:id (RemoveRequest) returns (RemoveResponse)
      	@handler List
      	get /chats (ListRequest) returns ([]Chat)
      	@handler Detail
      	get /chats/:id (DetailRequest) returns (DetailResponse)
      }
      
    • 运行模板生成命令

      goctl api go -api ./api/chat.api -dir ./api
      

      5.3 生成 user rpc 服务

      • 创建 chat.proto文件

        syntax = "proto3";
        package chat;
        option go_package = "./chat";
        message Empty {
        }
        // 产品创建
        message CreateRequest {
            string UserId = 1;
            string Title = 2;
            string Chat = 3;
            string ShareId = 4;
            int64 Archived = 5;
        }
        message CreateResponse {
            int64 Id = 1;
        }
        // 产品创建
        // 产品修改
        message UpdateRequest {
            int64 Id = 1;
            string UserId = 2;
            string Title = 3;
            string Chat = 4;
            string ShareId = 5;
            int64 Archived = 6;
        }
        message UpdateResponse {
        }
        // 产品修改
        // 产品删除
        message RemoveRequest {
            int64 Id = 1;
        }
        message RemoveResponse {
        }
        // 产品删除
        // 产品详情
        message DetailRequest {
            int64 Id = 1;
        }
        message DetailResponse {
            int64 Id = 1;
            string UserId = 2;
            string Title = 3;
            string Chat = 4;
            string ShareId = 5;
            int64 Archived = 6;
        }
        // 产品详情
        message ListChats {
            repeated DetailResponse List = 1;
        }
        // 调用ollama 大模型
        message CallRequest {
            string Name = 1;
            string Prompt = 2;
            string Role = 3;
        }
        message CallResponse {
            string Text = 1;
        }
        message Prompt {
            int64 Id = 1;
            string Command = 2;
            string Title = 3;
            string UserId = 4;
            string Content = 5;
        }
        message ListPrompts{
            repeated Prompt List = 1;
        }
        message NewChatEntity {
            string Model = 1;
            repeated MessagesEntity Messages = 2;
            OptionsEntity Options = 3;
        }
        message MessagesEntity {
            string Role = 1;
            string Content = 2;
        }
        message OptionsEntity {}
        service Chat {
            rpc Create(CreateRequest) returns(CreateResponse);
            rpc Update(UpdateRequest) returns(UpdateResponse);
            rpc Remove(RemoveRequest) returns(RemoveResponse);
            rpc Detail(DetailRequest) returns(DetailResponse);
            rpc ListChat(Empty) returns(ListChats);
            rpc ListPrompt(Empty) returns(ListPrompts);
            rpc Call(CallRequest) returns(CallResponse);
            rpc GenPrompt(NewChatEntity) returns(CallResponse);
        }
        
      • 运行模板生成命令

        goctl rpc protoc ./rpc/chat.proto --go_out=./rpc/types --go-grpc_out=./rpc/types --zrpc_out=./rpc
        

        5.4 配置文件

        • rpc/etc

          Name: chat.rpc
          ListenOn: 0.0.0.0:9002
          Etcd:
              Hosts:
                  - ******:2379
              Key: chat.rpc
          Timeout: 0
          Mysql:
              Host: ******
              Port: 3309
              DbName: openui
              User: root
              Password: "**********"
              DBZone: "TS"
              Charset: utf8mb4
              MaxIdle: 10
              MaxOpen: 100
              LogMode: true
              Loc: Asia/Shanghai
              Debug: true
              TablePrefix: "v1_"
              MaxLifetime: 300
          CacheRedis:
              Name: "openui"
              Nettype: "tcp"
              Address: "******:6379"
              Auth: ""
              DB: 0
          Salt: ******
          #日志配置
          LogConf:
              ServiceName: chat.rpc
              Mode: file
              TimeFormat: 2006-01-02 15:04:05.000
              Path: logs
              Level: info
              Compress: true
              Stat: false # 不记录CPU、内存等信息
              KeepDays: 10
              MaxBackups: 2
          
        • api/etc

          Name: Chat
          Host: 0.0.0.0
          Port: 8082
          Mysql:
              Host: **********
              Port: 3309
              DbName: openui
              User: root
              Password: "**********"
              DBZone: "TS"
              Charset: utf8mb4
              MaxIdle: 10
              MaxOpen: 100
              LogMode: true
              Loc: Asia/Shanghai
              Debug: true
              TablePrefix: "v1_"
              MaxLifetime: 300
          Timeout: 0
          CacheRedis:
              Name: "openui"
              Nettype: "tcp"
              Address: "**********:6379"
              Auth: ""
              DB: 0
          Auth:
              AccessSecret: **********
              AccessExpire: 86400
          #日志配置
          LogConf:
              ServiceName: chat.api
              Mode: file
              TimeFormat: 2006-01-02 15:04:05.000
              Path: logs
              Level: info
              Compress: true
              Stat: false # 不记录CPU、内存等信息
              KeepDays: 10
              MaxBackups: 2
          ChatRpc:
              Etcd:
                  Hosts:
                      - **********:2379
                  Key: chat.rpc
          OllUrl: http://**********:11434
          

          5.5 业务处理

          • 业务处理就不过多描述了,具体处理流程可以看相应文件的实现

            项目地址

            jackwillsmith/openui-svelte-build (github.com)

            GitHub - jackwillsmith/openui-backend-go: openui-backend-go

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]