ai-week/moonshot/function.go

312 lines
8.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package moonshot
import (
"bytes"
"encoding/json"
"fmt"
"github.com/PuerkitoBio/goquery"
"github.com/tidwall/gjson"
"io"
"log"
"mime/multipart"
"net/http"
"os"
"strings"
"week/tools"
"week/udesk"
)
//请求月之暗面所需要的常量
const (
MoonshotFileApiUrl = "https://api.moonshot.cn/v1/files/"
moonshotApiKey = "sk-DwKNLIVfGFi5CUocISixedd2kLcNzYVRFShbScKtbxMNOPkQ"
)
// 上传文件
func ReqMoonShotFileSendApi() *string {
filePath := "./周报.xlsx"
// 打开文件
file, err := os.Open(filePath)
if err != nil {
log.Printf("打开周报excel失败错误是:%v", err)
}
defer file.Close()
// 创建一个缓冲区
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
// 创建一个文件表单字段
part, err := writer.CreateFormFile("file", filePath)
if err != nil {
log.Printf("写文件缓存失败,错误是%v", err)
}
// 将文件内容拷贝到表单字段
_, err = io.Copy(part, file)
if err != nil {
log.Printf("拷贝文件到缓存失败,错误是%v", err)
}
// 添加其他表单字段
writer.WriteField("purpose", "file-extract")
// 完成表单写入
writer.Close()
// 创建 HTTP 请求
req, err := http.NewRequest("POST", MoonshotFileApiUrl, body)
if err != nil {
log.Printf("请求月之暗面api过程创建http请求失败错误是%s", err)
}
// 设置请求头
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("Authorization", "Bearer "+moonshotApiKey)
// 发送请求
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Printf("请求月之暗面api过程请求失败错误是%s", err)
}
defer resp.Body.Close()
// 读取响应
responseBody, err := io.ReadAll(resp.Body)
if err != nil {
log.Printf("请求月之暗面api过程读取响应失败错误是%s", err)
}
// 打印响应内容
fileId := gjson.Get(string(responseBody), "id").String()
log.Printf("文件上传成功你上传的文件id是%s", fileId)
return &fileId
}
// 删除文件
func ReqMoonShotFileDeleteApi(fileID *string) {
// 设置 API endpoint
url := fmt.Sprintf(MoonshotFileApiUrl + *fileID)
// 创建 HTTP 请求
req, err := http.NewRequest("DELETE", url, nil)
if err != nil {
log.Printf("调用月之暗面删除文件api过程创建http请求失败错误是%v", err)
return
}
// 设置请求头(如果需要的话)
req.Header.Set("Authorization", "Bearer "+moonshotApiKey)
// 发送请求
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Printf("调用月之暗面删除文件api过程发送http请求失败错误是%v", err)
return
}
defer resp.Body.Close()
// 检查响应状态码
if resp.StatusCode == http.StatusOK {
log.Printf("请求月之暗面删除文件api成功~")
} else {
log.Println("请求月之暗面删除文件api失败>_<, http状态码是:", resp.StatusCode)
}
}
// 开启ai对话主函数
func AiChat() (string, error) {
fileId := ReqMoonShotFileSendApi()
contentStr := GetFileContent(fileId)
// 设置 API endpoint
url := "https://api.moonshot.cn/v1/chat/completions"
// 构造请求体
requestBody := map[string]interface{}{
"model": "moonshot-v1-128k",
"messages": []map[string]string{
{"role": "system", "content": contentStr},
{"role": "user", "content": "帮忙分析下工单中的错别字告诉我对应的工单id"},
},
"temperature": 0.2,
}
// 将请求体转换为 JSON 格式
jsonBody, err := json.Marshal(requestBody)
if err != nil {
log.Printf("开启会话过程将请求体转换为json格式失败错误是%v", err)
return "", err
}
// 创建 HTTP 请求
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBody))
if err != nil {
log.Printf("开启会话过程,创建请求失败,错误是:%v", err)
return "", err
}
// 设置请求头
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+moonshotApiKey)
// 发送请求
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Printf("开启会话过程,发送请求失败,错误是:%v:", err)
return "", err
}
defer resp.Body.Close()
// 读取响应
responseBody := new(bytes.Buffer)
_, err = responseBody.ReadFrom(resp.Body)
if err != nil {
log.Printf("开启会话过程,读取响应失败,错误是:%v:", err)
return "", err
}
defer ReqMoonShotFileDeleteApi(fileId) //对话后清空文件
// 打印响应内容
jsonData := responseBody.String()
repFromAi := gjson.Get(jsonData, "choices.#.message.content").String()
repFromAi = strings.Replace(repFromAi, "\\n", "\n", -1)
repFromAi = strings.Replace(repFromAi, "\\", "", -1)
repFromAi = strings.Replace(repFromAi, "[", "", -1)
repFromAi = strings.Replace(repFromAi, "]", "", -1)
repFromAi = strings.Replace(repFromAi, "\"", "", 1)
log.Println(repFromAi)
return repFromAi, nil
}
// 获取文件内容
func GetFileContent(fileID *string) string {
// 设置 API endpoint
url := fmt.Sprintf(MoonshotFileApiUrl + *fileID + "/content")
// 创建 HTTP 请求
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Printf("月之暗面api获取文件内容过程创建http请求错误是%v:", err)
}
// 设置请求头
req.Header.Set("Authorization", "Bearer "+moonshotApiKey)
// 发送请求
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Printf("月之暗面api获取文件内容过程发送请求错误是%v", err)
}
defer resp.Body.Close()
// 读取响应内容
content, err := io.ReadAll(resp.Body)
if err != nil {
log.Printf("月之暗面api获取文件内容过程读取响应失败错误是%v", err)
}
contentStr := string(content)
// 打印文件内容
fmt.Println(contentStr)
return contentStr
}
// 根据工单id循环获取工单回复内容
func CreateExcel() error {
totalPages, err := udesk.GetUdeskTicketId()
if err != nil {
return err
}
id, err := udesk.LoopGetTicketId(totalPages)
if err != nil {
return err
}
contentMap := make(map[string][]string)
j := 1
for _, v := range id {
idUrl := fmt.Sprintf("https://servicecenter-alauda.udesk.cn/open_api_v1/tickets/%v/replies?", v)
repliesUrl := udesk.Geturlstring(idUrl)
resp, err := http.Get(repliesUrl)
if err != nil {
// 处理错误
log.Printf("获取工单过滤器下的回复信息失败,发送请求过程,错误是:%v\n", err)
return err
}
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
}
}(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
// 处理错误
log.Printf("获取工单过滤器下的回复信息失败,读取返回体过程,错误是:%v\n", err)
return err
}
jsonData := string(body)
repliesContent := gjson.Get(jsonData, "replies.#.content").String()
repliesContent = strings.Trim(repliesContent, "[]")
//repliesContent = trimHtml(repliesContent)
//查找回复内容和配图
doc, err := goquery.NewDocumentFromReader(strings.NewReader(repliesContent))
var s = make([]string, 0)
doc.Find("p,img").Each(func(i int, selection *goquery.Selection) {
imgSrc, exists := selection.Attr("src")
if exists {
s = append(s, imgSrc)
s = append(s, "\n")
}
s = append(s, selection.Text())
s = append(s, "\n")
})
//跳过没有回复内容的工单,即运维服务,减少给模型的错误条件
if len(s) == 0 {
continue
}
repliesContentSlice := tools.ReverseSlice(s)
cloudId := udesk.Id2CloudId(v)
log.Printf("正在处理map中的第%v个数据,键是%v\n", j, v)
if cloudId == "" {
contentMap[v] = repliesContentSlice
} else {
contentMap[cloudId] = repliesContentSlice
}
log.Printf("第%v个数据数据处理完成\n", j)
j++
}
log.Printf("所有回复数据处理完成,map中键的数量%v\n", len(contentMap))
//fmt.Printf("map的值:%v\n", contentMap) //回复内容的map待办将这个map中的建存储第一列将这个map中的值作为第二列存储
// 生成excel表格内容为id --> 回复内容
// 保存到某地
tools.CreateNewExcel(contentMap) //创建了excel
//sk-DwKNLIVfGFi5CUocISixedd2kLcNzYVRFShbScKtbxMNOPkQ
//卡点,如何根据文件内容获取回复,目前这个结构只能开启单轮对话
return nil
}