赞
踩
这是该项目的最终效果,使用ollama
的open-webui
进行人与机器的对话功能,对话的后端服务则完全对接自己开发的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
创建 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
前缀,路由,传参,响应不可变,否则 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
创建 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
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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。