开发个人Ollama-Chat–5 模型管理 (二)
ChatGPT
这是该项目的最终效果,使用ollama
的open-webui
进行人与机器的对话功能,对话的后端服务则完全对接自己开发的Go
项目。
如何实现呢?则通过这篇文章,一一给大家剖析后端的原理及功能实现。
ollama-go
根据上图结果,生成的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 chatNewChatEntity {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 Versionget /ollama/api/version returns (VersionResponse)@handler OllTagsget /ollama/api/tags returns (ModelReponse)@handler Chatpost /ollama/api/chat (NewChatEntity) returns (ChatRespone)@handler Completepost /ollama/v1/chat/completions (CompleteRequest) returns (ChatRespone) }service Chat {@handler Changelogget /api/changelog returns (ChangelogResponse)@handler Configget /api/config returns (ConfigResponse) }@server (jwt: Authprefix: /api/v1 ) service Chat {@handler GetPromptget /prompts returns (PromptResponse)@handler GetDefaultModelspost /configs/default/models (DefaultModels) returns (DefaultModels) }@server (jwt: Authprefix: /api/v1 ) service Chat {@handler Createpost /chats/new (NewChatRequest) returns (CreateResponse)@handler Updatepost /chats/:id (UpdateChatRequest) returns (UpdateResponse)@handler Removedelete /chats/:id (RemoveRequest) returns (RemoveResponse)@handler Listget /chats (ListRequest) returns ([]Chat)@handler Detailget /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:9002Etcd:Hosts:- ******:2379Key: chat.rpcTimeout: 0Mysql:Host: ******Port: 3309DbName: openuiUser: rootPassword: "**********"DBZone: "TS"Charset: utf8mb4MaxIdle: 10MaxOpen: 100LogMode: trueLoc: Asia/ShanghaiDebug: trueTablePrefix: "v1_"MaxLifetime: 300CacheRedis:Name: "openui"Nettype: "tcp"Address: "******:6379"Auth: ""DB: 0Salt: ******#日志配置 LogConf:ServiceName: chat.rpcMode: fileTimeFormat: 2006-01-02 15:04:05.000Path: logsLevel: infoCompress: trueStat: false # 不记录CPU、内存等信息KeepDays: 10MaxBackups: 2
-
api/etc
Name: Chat Host: 0.0.0.0 Port: 8082Mysql:Host: **********Port: 3309DbName: openuiUser: rootPassword: "**********"DBZone: "TS"Charset: utf8mb4MaxIdle: 10MaxOpen: 100LogMode: trueLoc: Asia/ShanghaiDebug: trueTablePrefix: "v1_"MaxLifetime: 300Timeout: 0CacheRedis:Name: "openui"Nettype: "tcp"Address: "**********:6379"Auth: ""DB: 0Auth:AccessSecret: **********AccessExpire: 86400#日志配置 LogConf:ServiceName: chat.apiMode: fileTimeFormat: 2006-01-02 15:04:05.000Path: logsLevel: infoCompress: trueStat: false # 不记录CPU、内存等信息KeepDays: 10MaxBackups: 2ChatRpc:Etcd:Hosts:- **********:2379Key: chat.rpcOllUrl: http://**********:11434
5.5 业务处理
- 业务处理就不过多描述了,具体处理流程可以看相应文件的实现
项目地址
jackwillsmith/openui-svelte-build (github.com)
GitHub - jackwillsmith/openui-backend-go: openui-backend-go