feat: 添加最核心的ai审查和吐槽功能
This commit is contained in:
parent
72591b7e2c
commit
ea70179075
BIN
aiComplain
Executable file
BIN
aiComplain
Executable file
Binary file not shown.
38
configs/configs.go
Normal file
38
configs/configs.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package configs
|
||||||
|
|
||||||
|
const (
|
||||||
|
DB_USERNAME = "aiCpmplain"
|
||||||
|
DB_PASSWORD = ""
|
||||||
|
DB_NAME = "aiComplain"
|
||||||
|
DB_PORT = 3306
|
||||||
|
OPEN_LIKE_URL = "http://127.0.0.1:11434/v1/chat/completions"
|
||||||
|
OPENAI_LIKE_API_KEY = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
LLM_MODEL_TINY = "qwen:4b" //用于内容审核的模型
|
||||||
|
LLM_MODEL_LARGE = "gemma3:12b" // 用于吐槽的模型
|
||||||
|
AUDIT_PROMPT_TEMPLATE = `
|
||||||
|
你是一名专业的网络内容审核员,负责审核用户发布的言论内容,确保其符合中国法律法规和社会道德规范。你的工作是公正、客观地判断内容是否可以发布。
|
||||||
|
审核标准包括但不限于:
|
||||||
|
|
||||||
|
违法违禁内容(如毒品、赌博、暴力、恐怖主义等)
|
||||||
|
色情低俗内容
|
||||||
|
族宗教歧视内容
|
||||||
|
人身攻击、侮辱诽谤内容
|
||||||
|
虚假信息或谣言
|
||||||
|
广告营销信息
|
||||||
|
暴露他人隐私的内容
|
||||||
|
请对用户输入的言论进行审核,返回JSON格式结果,包含:
|
||||||
|
|
||||||
|
"approved":布尔值(true表示通过,false表示未通过)
|
||||||
|
"reason":字符串(未通过时的原因,通过时为"无")
|
||||||
|
输出必须严格为JSON格式,不要包含其他任何内容。示例:
|
||||||
|
{
|
||||||
|
"approved": true,
|
||||||
|
"reason": "无"
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"approved": false,
|
||||||
|
"reason": "包含色情低俗内容"
|
||||||
|
}`
|
||||||
|
COMPLAIN_PROMPT_TEMPLATE = `
|
||||||
|
你是一名资深吐槽墙网站的顶级吐槽手,专精于"怼天怼地嘴强王者"的尖锐、"阴阳怪气十级学者"的表面客气实则刀刀致命等风格。用户传入任何言论,你必须创作20-50字的吐槽内容:戳肺管子、句句直击痛点、用网络热梗或方言脏话(避免直接脏话)、表面客气实则刀刀致命。输出必须严格为JSON格式,不要包含其他任何内容,尤其是反引号:{"taunt": "吐槽内容"}。吐槽内容必须精准在20-50字,不加任何其他说明。`
|
||||||
|
)
|
7
go.mod
Normal file
7
go.mod
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module git.mmeiblog.cn/mei/aiComplain
|
||||||
|
|
||||||
|
go 1.23.4
|
||||||
|
|
||||||
|
require github.com/go-dev-frame/sponge v1.15.1
|
||||||
|
|
||||||
|
require github.com/sashabaranov/go-openai v1.41.1 // indirect
|
4
go.sum
Normal file
4
go.sum
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
github.com/go-dev-frame/sponge v1.15.1 h1:I+2bWBQHqySkmG4d/K+KaYUeU37wjuiOaO6pT8dMSno=
|
||||||
|
github.com/go-dev-frame/sponge v1.15.1/go.mod h1:kTYWZQUSR5Iuu9Ur4tHC+v/1eP48W7hGxhvO6hVylNs=
|
||||||
|
github.com/sashabaranov/go-openai v1.41.1 h1:zf5tM+GuxpyiyD9XZg8nCqu52eYFQg9OOew0gnIuDy4=
|
||||||
|
github.com/sashabaranov/go-openai v1.41.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
4
internal/send.go
Normal file
4
internal/send.go
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
package internal
|
||||||
|
|
||||||
|
// func HandleSend(message string) (string, error) {
|
||||||
|
// }
|
32
internal/snedAndAudit.go
Normal file
32
internal/snedAndAudit.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package internal
|
||||||
|
|
||||||
|
import "git.mmeiblog.cn/mei/aiComplain/pkg/ai"
|
||||||
|
|
||||||
|
type SendAndAuditResponse struct {
|
||||||
|
Data string `json:"data"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendAndAudit(message string) (SendAndAuditResponse, error) {
|
||||||
|
AuditResponse, err := ai.SendAudit(message)
|
||||||
|
var ComplainResponse ai.ComplainMessage
|
||||||
|
if err != nil {
|
||||||
|
return SendAndAuditResponse{
|
||||||
|
Data: "",
|
||||||
|
Message: "审核失败",
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
if AuditResponse.Approved {
|
||||||
|
ComplainResponse, err = ai.SendComplain(message)
|
||||||
|
if err != nil {
|
||||||
|
return SendAndAuditResponse{
|
||||||
|
Data: "",
|
||||||
|
Message: "AI吐槽失败",
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SendAndAuditResponse{
|
||||||
|
Data: ComplainResponse.Taunt,
|
||||||
|
Message: "AI吐槽成功",
|
||||||
|
}, nil
|
||||||
|
}
|
13
main.go
Normal file
13
main.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.mmeiblog.cn/mei/aiComplain/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// 先写点数据测试
|
||||||
|
response, err := internal.SendAndAudit("2024级11班某女同学(🐭老鼠)于上周周五晚上在女生宿舍四处投毒,毒物为霉菌饼子,在霉菌里发现少量饼子。食用过的某同学说因为宿舍灯光暗,还以为是葱花饼。\r\n据说219(12班)宿舍三人受害严重,一人第二夜深夜直接被送回家,一人第三天下午回家,证物已上交老师,但该名女同学并无悔过之心,四处与他人就此事讲笑话,并单方面说受害同学原谅了她,事后还去各个宿舍索要食物。\r\n希望大家多加小心该名女同学,其外号在学校叫为老鼠🐭,可询问周围同学其真名,目前在2024级的11班")
|
||||||
|
fmt.Println(response.Data, err)
|
||||||
|
}
|
100
pkg/ai/api.go
Normal file
100
pkg/ai/api.go
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
package ai
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"git.mmeiblog.cn/mei/aiComplain/configs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 定义请求格式(兼容 OpenAI 格式)
|
||||||
|
type ChatMessage struct {
|
||||||
|
Role string `json:"role"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChatRequest struct {
|
||||||
|
Model string `json:"model"`
|
||||||
|
Messages []ChatMessage `json:"messages"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChatResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Object string `json:"object"`
|
||||||
|
Created int64 `json:"created"`
|
||||||
|
Choices []struct {
|
||||||
|
Index int `json:"index"`
|
||||||
|
Message struct {
|
||||||
|
Role string `json:"role"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
} `json:"message"`
|
||||||
|
} `json:"choices"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client 封装接口调用
|
||||||
|
type Client struct {
|
||||||
|
APIKey string
|
||||||
|
BaseURL string
|
||||||
|
Model string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send 发送对话请求
|
||||||
|
func (c *Client) Send(messages []ChatMessage) (string, error) {
|
||||||
|
reqBody := ChatRequest{
|
||||||
|
Model: c.Model,
|
||||||
|
Messages: messages,
|
||||||
|
}
|
||||||
|
data, err := json.Marshal(reqBody)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", c.BaseURL, bytes.NewBuffer(data))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
if c.APIKey != "" {
|
||||||
|
req.Header.Set("Authorization", "Bearer "+c.APIKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, _ := io.ReadAll(resp.Body)
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return "", fmt.Errorf("http error: %s, body: %s", resp.Status, string(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
var chatResp ChatResponse
|
||||||
|
if err := json.Unmarshal(body, &chatResp); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(chatResp.Choices) == 0 {
|
||||||
|
return "", fmt.Errorf("no response choices")
|
||||||
|
}
|
||||||
|
return chatResp.Choices[0].Message.Content, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClient(message string, prompt string, model string) (string, error) {
|
||||||
|
var c Client
|
||||||
|
c.BaseURL = configs.OPEN_LIKE_URL
|
||||||
|
c.Model = model
|
||||||
|
c.APIKey = configs.OPENAI_LIKE_API_KEY
|
||||||
|
msgs := []ChatMessage{
|
||||||
|
{Role: "system", Content: prompt},
|
||||||
|
{Role: "user", Content: message},
|
||||||
|
}
|
||||||
|
response, err := c.Send(msgs)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return response, nil
|
||||||
|
}
|
44
pkg/ai/format.go
Normal file
44
pkg/ai/format.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package ai
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"git.mmeiblog.cn/mei/aiComplain/configs"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ComplainMessage struct {
|
||||||
|
Taunt string `json:"Taunt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuditMessage struct {
|
||||||
|
Approved bool `json:"approved"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendComplain 发送返回一个ai的吐槽内容
|
||||||
|
func SendComplain(message string) (ComplainMessage, error) {
|
||||||
|
response, err := NewClient(message, configs.COMPLAIN_PROMPT_TEMPLATE, configs.LLM_MODEL_LARGE)
|
||||||
|
if err != nil {
|
||||||
|
return ComplainMessage{}, err
|
||||||
|
}
|
||||||
|
var format ComplainMessage
|
||||||
|
err = json.Unmarshal([]byte(response), &format)
|
||||||
|
if err != nil {
|
||||||
|
return ComplainMessage{}, err
|
||||||
|
}
|
||||||
|
return format, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendAudit 检测内容是否合规
|
||||||
|
func SendAudit(message string) (AuditMessage, error) {
|
||||||
|
response, err := NewClient(message, configs.AUDIT_PROMPT_TEMPLATE, configs.LLM_MODEL_TINY)
|
||||||
|
if err != nil {
|
||||||
|
return AuditMessage{}, err
|
||||||
|
}
|
||||||
|
var format AuditMessage
|
||||||
|
err = json.Unmarshal([]byte(response), &format)
|
||||||
|
if err != nil {
|
||||||
|
return AuditMessage{}, err
|
||||||
|
}
|
||||||
|
return format, nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user