开发个人Go-ChatGPT--5 模型管理 (二)
ChatGPT
这是该项目的最终效果,使用ollama
的open-webui
进行人与机器的对话功能,对话的后端服务则完全对接自己开发的Go
项目。
如何实现呢?则通过这篇文章,一一给大家剖析后端的原理及功能实现。
ollama-go
根据上图结果,生成的stream
响应,就可与open-webUI
进行对话,实现ChatGPT
的功能效果。
正片开始
文件目录:
bash
├── 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无法正常展示
sqlCREATE 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无法正常展示
sqldrop 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
官方案例不同bash# 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) }
-
运行模板生成命令
bashgoctl api go -api ./api/chat.api -dir ./api
5.3 生成 user rpc 服务
-
创建
chat.proto
文件protobufsyntax = "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); }
-
运行模板生成命令
bashgoctl rpc protoc ./rpc/chat.proto --go_out=./rpc/types --go-grpc_out=./rpc/types --zrpc_out=./rpc
5.4 配置文件
-
rpc/etc
yamlName: 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
yamlName: 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 业务处理
- 业务处理就不过多描述了,具体处理流程可以看相应文件的实现