Roc il y a 2 jours
Parent
commit
deca0fa25c

+ 68 - 3
controllers/rag/wechat_platform_controller.go → controllers/rag/wechat_platform.go

@@ -394,6 +394,62 @@ func (c *WechatPlatformController) Op() {
 	br.Msg = "修改成功"
 }
 
+// Refresh
+// @Title 公共列表
+// @Description 公共列表
+// @Success 200 {object} models.WechatPlatformListResp
+// @router /wechat_platform/refresh [post]
+func (c *WechatPlatformController) Refresh() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		return
+	}
+
+	var req request.RefreshWechatPlatformReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.WechatPlatformId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+
+	obj := rag.WechatPlatform{}
+	wechatPlatform, err := obj.GetByID(req.WechatPlatformId)
+	if err != nil {
+		br.Msg = "修改失败"
+		br.ErrMsg = "修改失败,Err:" + err.Error()
+		if utils.IsErrNoRow(err) {
+			br.Msg = "公众号不存在"
+			br.IsSendEmail = false
+		}
+		return
+	}
+	if wechatPlatform.FakeId != `` {
+		br.Msg = "公众号已添加成功"
+		br.ErrMsg = "公众号已添加成功"
+		br.IsSendEmail = false
+		return
+	}
+
+	go cache.AddWechatArticleOpToCache(wechatPlatform.WechatPlatformId, `add`)
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "刷新成功"
+}
+
 // ArticleList
 // @Title 我关注的接口
 // @Description 我关注的接口
@@ -581,7 +637,16 @@ func (c *WechatPlatformController) ArticleDel() {
 }
 
 //func init() {
-//	obj := rag.WechatPlatform{}
-//	item, _ := obj.GetByID(2)
-//	fmt.Println(llm.BeachAddWechatPlatform(item))
+//	//obj := rag.WechatPlatform{}
+//	//item, _ := obj.GetByID(2)
+//	//fmt.Println(llm.BeachAddWechatPlatform(item))
+//
+//	obj := rag.WechatArticle{}
+//	//item, _ := obj.GetById(30)
+//	list, _ := obj.GetListByCondition(``, ` `, []interface{}{}, 0, 1)
+//	//llm.ArticleToTmpFile(item.TextContent)
+//	for _, item := range list {
+//		//llm.ArticleToKnowledge(item)
+//		llm.GenerateArticleAbstract(item)
+//	}
 //}

+ 21 - 2
models/business_conf.go

@@ -1,6 +1,7 @@
 package models
 
 import (
+	"encoding/json"
 	"eta/eta_api/global"
 	"eta/eta_api/utils"
 	"fmt"
@@ -56,7 +57,9 @@ const (
 	BusinessConfReportViewUrl                = "ReportViewUrl"                // 报告详情地址
 	BusinessConfEsIndexNameExcel             = "EsIndexNameExcel"             // ES索引名称-表格
 	BusinessConfEsIndexNameDataSource        = "EsIndexNameDataSource"        // ES索引名称-数据源
-	LLMInitConfig="llmInitConfig"
+	LLMInitConfig                            = "llmInitConfig"
+	KnowledgeBaseName                        = "KnowledgeBaseName"    // 摘要库
+	KnowledgeArticleName                     = "KnowledgeArticleName" // 原文库
 )
 
 const (
@@ -65,7 +68,6 @@ const (
 	BusinessConfClientFlagNanHua       = "nhqh" // 南华标记
 	BusinessConfEmailClientSmtp        = "smtp" // 普通邮箱标记
 
-
 )
 
 // FromSceneMap 数据源名称与数据源ID的对应关系
@@ -244,6 +246,11 @@ func InitUseMongoConf() {
 	}
 }
 
+type LLMConfig struct {
+	LlmAddress string `json:"llm_server"`
+	LlmModel   string `json:"llm_model"`
+}
+
 func InitBusinessConf() {
 	var e error
 	BusinessConfMap, e = GetBusinessConf()
@@ -257,4 +264,16 @@ func InitBusinessConf() {
 	if BusinessConfMap[BusinessConfEsIndexNameDataSource] != "" {
 		utils.EsDataSourceIndexName = BusinessConfMap[BusinessConfEsIndexNameDataSource]
 	}
+	confStr := BusinessConfMap[LLMInitConfig]
+	if confStr != "" {
+		var config LLMConfig
+		err := json.Unmarshal([]byte(confStr), &config)
+		if err != nil {
+			utils.FileLog.Error("LLM配置错误")
+		}
+
+		utils.LLM_MODEL = config.LlmModel
+		utils.LLM_SERVER = config.LlmAddress
+	}
+
 }

+ 4 - 0
models/rag/request/wechat_platform.go

@@ -11,6 +11,10 @@ type OpWechatPlatformReq struct {
 	WechatPlatformId int `description:"公众号id"`
 }
 
+type RefreshWechatPlatformReq struct {
+	WechatPlatformId int `description:"公众号id"`
+}
+
 type AddQuestionReq struct {
 	Content string `description:"公众号名称"`
 }

+ 1 - 0
models/rag/wechat_article.go

@@ -23,6 +23,7 @@ type WechatArticle struct {
 	Province          string    `gorm:"column:province;type:varchar(255);comment:省;" description:"省"`
 	City              string    `gorm:"column:city;type:varchar(255);comment:市;" description:"市"`
 	ArticleCreateTime time.Time `gorm:"column:article_create_time;type:datetime;comment:报告创建时间;default:NULL;" description:"报告创建时间"`
+	VectorKey         string    `gorm:"column:vector_key;type:varchar(255);comment:向量key标识;" description:"向量key标识"`
 	IsDeleted         int       `gorm:"column:is_deleted;type:tinyint(4);comment:是否删除,0:未删除,1: 已删除;default:0;" description:"是否删除,0:未删除,1: 已删除"`
 	ModifyTime        time.Time `gorm:"column:modify_time;type:datetime;comment:修改时间;default:NULL;" description:"修改时间"`
 	CreateTime        time.Time `gorm:"column:create_time;type:datetime;comment:入库时间;default:NULL;" description:"入库时间"`

+ 8 - 2
models/rag/wechat_article_chat_record.go

@@ -8,8 +8,8 @@ import (
 )
 
 type WechatArticleChatRecord struct {
-	WechatArticleChatRecordId int32     `gorm:"column:wechat_article_chat_record_id;type:int(11);comment:主键;primaryKey;not null;" json:"wechat_article_chat_record_id"` // 主键
-	WechatArticleId           int32     `gorm:"column:wechat_article_id;type:int(11);comment:文章id;default:NULL;" json:"wechat_article_id"`                              // 文章id
+	WechatArticleChatRecordId int       `gorm:"column:wechat_article_chat_record_id;type:int(11);comment:主键;primaryKey;not null;" json:"wechat_article_chat_record_id"` // 主键
+	WechatArticleId           int       `gorm:"column:wechat_article_id;type:int(11);comment:文章id;default:NULL;" json:"wechat_article_id"`                              // 文章id
 	ChatUserType              string    `gorm:"column:chat_user_type;type:enum('user', 'assistant');comment:用户方;default:NULL;" json:"chat_user_type"`                   // 用户方
 	Content                   string    `gorm:"column:content;type:longtext;comment:对话内容;" json:"content"`                                                              // 对话内容
 	SendTime                  time.Time `gorm:"column:send_time;type:datetime;comment:发送时间;default:NULL;" json:"send_time"`                                             // 发送时间
@@ -47,6 +47,12 @@ func (m *WechatArticleChatRecord) Create() (err error) {
 	return
 }
 
+func (m *WechatArticleChatRecord) CreateInBatches(items []*WechatArticleChatRecord) (err error) {
+	err = global.DbMap[utils.DbNameAI].CreateInBatches(items, utils.MultiAddNum).Error
+
+	return
+}
+
 func (m *WechatArticleChatRecord) Update(updateCols []string) (err error) {
 	err = global.DbMap[utils.DbNameAI].Select(updateCols).Updates(&m).Error
 

+ 147 - 9
services/llm/chat.go

@@ -2,7 +2,9 @@ package llm
 
 import (
 	"bytes"
+	"encoding/json"
 	"eta/eta_api/utils"
+	"eta/eta_api/utils/llm/eta_llm"
 	"fmt"
 	"io"
 	"mime/multipart"
@@ -10,16 +12,29 @@ import (
 	"os"
 )
 
-type UpdateTempDocsResp struct {
-	Code int    `json:"code"`
-	Msg  string `json:"msg"`
-	Data struct {
-		Id          string        `json:"id"`
-		FailedFiles []interface{} `json:"failed_files"`
-	} `json:"data"`
+var (
+	llmService = eta_llm.GetInstance()
+)
+
+type UploadTempDocsResp struct {
+	Code int                   `json:"code"`
+	Msg  string                `json:"msg"`
+	Data UploadTempDocDataResp `json:"data"`
+}
+
+type UploadTempDocDataResp struct {
+	Id          string        `json:"id"`
+	FailedFiles []interface{} `json:"failed_files"`
 }
 
-func UpdateTempDocs(filePath string) {
+// UploadTempDocs
+// @Description: 上传到临时知识库
+// @author: Roc
+// @datetime 2025-03-10 14:42:18
+// @param filePath string
+// @return resp UploadDocsResp
+// @return err error
+func UploadTempDocs(filePath string) (resp UploadTempDocsResp, err error) {
 	postUrl := utils.LLM_SERVER + "/knowledge_base/upload_temp_docs"
 
 	params := make(map[string]string)
@@ -39,14 +54,136 @@ func UpdateTempDocs(filePath string) {
 	str := string(result)
 	fmt.Println(str)
 
+	err = json.Unmarshal(result, &resp)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+type UploadDocsResp struct {
+	Code int               `json:"code"`
+	Msg  string            `json:"msg"`
+	Data UploadDocDataResp `json:"data"`
+}
+
+type UploadDocDataResp struct {
+	Id          string            `json:"id"`
+	FailedFiles map[string]string `json:"failed_files"`
+}
+
+// UploadDocsToKnowledge
+// @Description: 上传文章到知识库
+// @author: Roc
+// @datetime 2025-03-10 14:40:44
+// @param filePath string
+// @param knowledgeName string
+// @return resp UploadTempDocsResp
+// @return err error
+func UploadDocsToKnowledge(filePath, knowledgeName string) (updateResp UploadDocDataResp, err error) {
+	postUrl := utils.LLM_SERVER + "/knowledge_base/upload_docs"
+
+	params := make(map[string]string)
+	params[`knowledge_base_name`] = knowledgeName
+	params[`override`] = `true`              // 覆盖已有文件
+	params[`to_vector_store`] = `true`       // 上传文件后是否进行向量化
+	params[`chunk_size`] = `750`             // 知识库中单段文本最大长度
+	params[`chunk_overlap`] = `150`          // 知识库中相邻文本重合长度
+	params[`zh_title_enhance`] = `true`      // 是否开启中文标题加强
+	params[`docs`] = ``                      // 自定义的docs,需要转为json字符串
+	params[`not_refresh_vs_cache`] = `false` // 暂不保存向量库(用于FAISS)
+
+	files := make(map[string]string)
+	files[`files`] = filePath
+
+	result, err := PostFormData(postUrl, params, files)
+	if err != nil {
+		return
+	}
+
+	str := string(result)
+	fmt.Println(str)
+
+	var resp UploadDocsResp
+	err = json.Unmarshal(result, &resp)
+	if err != nil {
+		return
+	}
+
+	if resp.Code != 200 {
+		err = fmt.Errorf(`上传文件失败: %s`, resp.Msg)
+		return
+	}
+	updateResp = resp.Data
+
 	return
 }
 
-func ChatByFile(question string) {
+// ChatResp 问答响应
+type ChatResp struct {
+	Answer string   `json:"answer"`
+	Docs   []string `json:"docs"`
+}
+
+type HistoryContent struct {
+	Content string `json:"content"`
+	Role    string `json:"role"`
+}
+
+func ChatByFile(knowledgeId, question string, historyList []HistoryContent) (answerStr string, answer ChatResp, err error) {
 	// 没有问题那就直接返回
 	if question == `` {
 		return
 	}
+
+	history := make([]json.RawMessage, 0)
+	for _, v := range historyList {
+		tmpHistory, tmpErr := json.Marshal(v)
+		if tmpErr != nil {
+			return
+		}
+		history = append(history, json.RawMessage(string(tmpHistory)))
+	}
+
+	resp, err := llmService.DocumentChat(question, knowledgeId, history, false)
+	if err != nil {
+		return
+	}
+	defer func() {
+		if resp != nil && resp.Body != nil {
+			_ = resp.Body.Close()
+		}
+	}()
+	if resp == nil {
+		err = fmt.Errorf(`知识库问答失败: 无应答`)
+		return
+	}
+	result, err := io.ReadAll(resp.Body)
+	if err != nil {
+		err = fmt.Errorf(`知识库问答数据解析失败: %s`, err.Error())
+		return
+	}
+
+	answerStr = string(result)
+	// 找到"data:"关键字的位置
+	dataIndex := bytes.Index([]byte(answerStr), []byte("data: "))
+	if dataIndex == -1 {
+		err = fmt.Errorf(`未找到"data:"关键字`)
+		return
+	}
+
+	// 提取"data:"关键字之后的部分
+	answerStr = answerStr[dataIndex+len("data: "):]
+
+	// 解析JSON数据
+	err = json.Unmarshal([]byte(answerStr), &answer)
+	if err != nil {
+		err = fmt.Errorf(`解析JSON数据失败: %s`, err.Error())
+		return
+	}
+
+	return
 }
 
 // PostFormData sends a POST request with form-data
@@ -87,6 +224,7 @@ func PostFormData(url string, params map[string]string, files map[string]string)
 	if err != nil {
 		return nil, err
 	}
+	//req.Header.Set("accept", `application/json`)
 	req.Header.Set("Content-Type", writer.FormDataContentType())
 
 	client := &http.Client{}

+ 285 - 3
services/llm/wechat_platform.go

@@ -1,16 +1,18 @@
 package llm
 
 import (
+	"eta/eta_api/models"
 	"eta/eta_api/models/rag"
 	"eta/eta_api/utils"
 	"fmt"
 	"html"
+	"os"
+	"regexp"
 	"strconv"
+	"strings"
 	"time"
 )
 
-// TODO 改成走队列,避免并发
-
 type WechatArticleOp struct {
 	Source           string
 	WechatPlatformId int
@@ -168,7 +170,7 @@ func AddWechatArticle(item *rag.WechatPlatform, articleLink string, articleDetai
 func BeachAddWechatArticle(item *rag.WechatPlatform, num int) {
 	var err error
 	defer func() {
-		fmt.Println("公众号文章批量入库完成")
+		//fmt.Println("公众号文章批量入库完成")
 		if err != nil {
 			utils.FileLog.Error("公众号文章批量入库失败,err:%v", err)
 			fmt.Println("公众号文章批量入库失败,err:", err)
@@ -210,3 +212,283 @@ func BeachAddWechatArticle(item *rag.WechatPlatform, num int) {
 	}
 	return
 }
+
+// GenerateArticleAbstract
+// @Description: 文章摘要生成
+// @author: Roc
+// @datetime 2025-03-10 16:17:53
+// @param item *rag.WechatArticle
+func GenerateArticleAbstract(item *rag.WechatArticle) {
+	var err error
+	defer func() {
+		if err != nil {
+			utils.FileLog.Error("文章转临时文件失败,err:%v", err)
+			fmt.Println("文章转临时文件失败,err:", err)
+		}
+	}()
+
+	abstractObj := rag.WechatArticleAbstract{}
+	_, err = abstractObj.GetByWechatArticleId(item.WechatArticleId)
+	if err == nil {
+		// 摘要已经生成,不需要重复生成
+		return
+	}
+	if !utils.IsErrNoRow(err) {
+		return
+	}
+
+	// 生成临时文件
+	dateDir := time.Now().Format("20060102")
+	uploadDir := utils.STATIC_DIR + "ai/" + dateDir
+	err = os.MkdirAll(uploadDir, utils.DIR_MOD)
+	if err != nil {
+		err = fmt.Errorf("存储目录创建失败,Err:" + err.Error())
+		return
+	}
+	randStr := utils.GetRandStringNoSpecialChar(28)
+	fileName := randStr + `.md`
+	tmpFilePath := uploadDir + "/" + fileName
+	err = utils.SaveToFile(item.TextContent, tmpFilePath)
+	if err != nil {
+		err = fmt.Errorf("生成临时文件失败,Err:" + err.Error())
+		return
+	}
+	defer func() {
+		os.Remove(tmpFilePath)
+	}()
+
+	// 上传临时文件到LLM
+	tmpFileResp, err := UploadTempDocs(tmpFilePath)
+	if err != nil {
+		err = fmt.Errorf("上传临时文件到LLM失败,Err:" + err.Error())
+		return
+	}
+
+	if tmpFileResp.Data.Id == `` {
+		err = fmt.Errorf("上传临时文件到LLM失败,Err:上传失败")
+		return
+	}
+	tmpDocId := tmpFileResp.Data.Id
+
+	//tmpDocId := `c4d2ee902808408c8b8ed398b33be103` // 钢材
+	//tmpDocId := `2dde8afe62d24525a814e74e0a5e35e4` // 钢材
+	//tmpDocId := `7634cc1086c04b3687682220a2cf1a48` //
+
+	historyList := make([]HistoryContent, 0)
+
+	questionObj := rag.Question{}
+	questionList, err := questionObj.GetListByCondition(``, []interface{}{}, 0, 100)
+	if err != nil {
+		err = fmt.Errorf("获取问题列表失败,Err:" + err.Error())
+		return
+	}
+
+	addArticleChatRecordList := make([]*rag.WechatArticleChatRecord, 0)
+
+	var abstract string
+	//开始对话
+	for _, question := range questionList {
+		originalAnswer, tmpAnswer, tmpErr := getAnswerByContent(tmpDocId, question.QuestionContent, historyList)
+		if tmpErr != nil {
+			err = fmt.Errorf("LLM对话失败,Err:" + tmpErr.Error())
+			return
+		}
+		abstract = tmpAnswer
+
+		historyList = append(historyList, HistoryContent{
+			Role:    `user`,
+			Content: question.QuestionContent,
+		}, HistoryContent{
+			Role:    `assistant`,
+			Content: tmpAnswer,
+		})
+
+		// 待入库的数据
+		addArticleChatRecordList = append(addArticleChatRecordList, &rag.WechatArticleChatRecord{
+			WechatArticleChatRecordId: 0,
+			WechatArticleId:           item.WechatArticleId,
+			ChatUserType:              "user",
+			Content:                   question.QuestionContent,
+			SendTime:                  time.Now(),
+			CreatedTime:               time.Now(),
+			UpdateTime:                time.Now(),
+		}, &rag.WechatArticleChatRecord{
+			WechatArticleChatRecordId: 0,
+			WechatArticleId:           item.WechatArticleId,
+			ChatUserType:              "assistant",
+			Content:                   originalAnswer,
+			SendTime:                  time.Now(),
+			CreatedTime:               time.Now(),
+			UpdateTime:                time.Now(),
+		})
+	}
+
+	// 添加问答记录
+	if len(addArticleChatRecordList) > 0 {
+		recordObj := rag.WechatArticleChatRecord{}
+		err = recordObj.CreateInBatches(addArticleChatRecordList)
+		if err != nil {
+			return
+		}
+	}
+
+	if abstract != `` {
+		abstractItem := &rag.WechatArticleAbstract{
+			WechatArticleAbstractId: 0,
+			WechatArticleId:         item.WechatArticleId,
+			Content:                 abstract,
+			Version:                 0,
+			VectorKey:               "",
+			ModifyTime:              time.Now(),
+			CreateTime:              time.Now(),
+		}
+		err = abstractItem.Create()
+		if err != nil {
+			return
+		}
+
+		AbstractToKnowledge(item, abstractItem)
+	}
+}
+
+func getAnswerByContent(docId, question string, historyList []HistoryContent) (originalAnswer, answer string, err error) {
+	originalAnswer, result, err := ChatByFile(docId, question, historyList)
+	fmt.Println(result)
+	if err != nil {
+		err = fmt.Errorf("LLM对话失败,Err:" + err.Error())
+		return
+	}
+
+	// 提取 </think> 后面的内容
+	thinkEndIndex := strings.Index(result.Answer, "</think>")
+	if thinkEndIndex != -1 {
+		answer = strings.TrimSpace(result.Answer[thinkEndIndex+len("</think>"):])
+	} else {
+		answer = result.Answer
+	}
+
+	answer = strings.TrimSpace(answer)
+
+	return
+}
+
+// ArticleToKnowledge
+// @Description: 原文入向量库
+// @author: Roc
+// @datetime 2025-03-10 16:13:16
+// @param item *rag.WechatArticle
+func ArticleToKnowledge(item *rag.WechatArticle) {
+	if item.TextContent == `` {
+		return
+	}
+	var err error
+	defer func() {
+		if err != nil {
+			utils.FileLog.Error("上传文章原文到知识库失败,err:%v", err)
+			fmt.Println("上传文章原文到知识库失败,err:", err)
+		}
+	}()
+
+	// 生成临时文件
+	//dateDir := time.Now().Format("20060102")
+	//uploadDir := utils.STATIC_DIR + "ai/article/" + dateDir
+	uploadDir := utils.STATIC_DIR + "ai/article"
+	err = os.MkdirAll(uploadDir, utils.DIR_MOD)
+	if err != nil {
+		err = fmt.Errorf("存储目录创建失败,Err:" + err.Error())
+		return
+	}
+	fileName := RemoveSpecialChars(item.Title) + `.md`
+	tmpFilePath := uploadDir + "/" + fileName
+	err = utils.SaveToFile(item.TextContent, tmpFilePath)
+	if err != nil {
+		err = fmt.Errorf("生成临时文件失败,Err:" + err.Error())
+		return
+	}
+	defer func() {
+		os.Remove(tmpFilePath)
+	}()
+
+	knowledgeArticleName := models.BusinessConfMap[models.KnowledgeArticleName]
+	// 上传临时文件到LLM
+	uploadFileResp, err := UploadDocsToKnowledge(tmpFilePath, knowledgeArticleName)
+	if err != nil {
+		err = fmt.Errorf("上传文章原文到知识库失败,Err:" + err.Error())
+		return
+	}
+
+	if len(uploadFileResp.FailedFiles) > 0 {
+		for _, v := range uploadFileResp.FailedFiles {
+			err = fmt.Errorf("上传文章原文到知识库失败,Err:" + v)
+		}
+	}
+
+	item.VectorKey = tmpFilePath
+	item.ModifyTime = time.Now()
+	err = item.Update([]string{"vector_key", "modify_time"})
+
+}
+
+// AbstractToKnowledge
+// @Description: 摘要入向量库
+// @author: Roc
+// @datetime 2025-03-10 16:14:59
+// @param wechatArticleItem *rag.WechatArticle
+// @param item *rag.WechatArticleAbstract
+func AbstractToKnowledge(wechatArticleItem *rag.WechatArticle, item *rag.WechatArticleAbstract) {
+	if item.Content == `` {
+		return
+	}
+	var err error
+	defer func() {
+		if err != nil {
+			utils.FileLog.Error("摘要入向量库失败,err:%v", err)
+			fmt.Println("摘要入向量库失败,err:", err)
+		}
+	}()
+
+	// 生成临时文件
+	//dateDir := time.Now().Format("20060102")
+	//uploadDir := utils.STATIC_DIR + "ai/article/" + dateDir
+	uploadDir := utils.STATIC_DIR + "ai/abstract"
+	err = os.MkdirAll(uploadDir, utils.DIR_MOD)
+	if err != nil {
+		err = fmt.Errorf("存储目录创建失败,Err:" + err.Error())
+		return
+	}
+	fileName := RemoveSpecialChars(wechatArticleItem.Title) + `.md`
+	tmpFilePath := uploadDir + "/" + fileName
+	err = utils.SaveToFile(item.Content, tmpFilePath)
+	if err != nil {
+		err = fmt.Errorf("生成临时文件失败,Err:" + err.Error())
+		return
+	}
+	defer func() {
+		os.Remove(tmpFilePath)
+	}()
+
+	knowledgeArticleName := models.BusinessConfMap[models.KnowledgeBaseName]
+	// 上传临时文件到LLM
+	uploadFileResp, err := UploadDocsToKnowledge(tmpFilePath, knowledgeArticleName)
+	if err != nil {
+		err = fmt.Errorf("上传文章原文到知识库失败,Err:" + err.Error())
+		return
+	}
+
+	if len(uploadFileResp.FailedFiles) > 0 {
+		for _, v := range uploadFileResp.FailedFiles {
+			err = fmt.Errorf("上传文章原文到知识库失败,Err:" + v)
+		}
+	}
+
+	item.VectorKey = tmpFilePath
+	item.ModifyTime = time.Now()
+	err = item.Update([]string{"vector_key", "modify_time"})
+
+}
+
+func RemoveSpecialChars(text string) string {
+	// 匹配非中文、非字母、非数字、非中文标点的字符
+	reg := regexp.MustCompile(`[^\p{Han}\p{L}\p{N}\x{3000}-\x{303F}]`)
+	return reg.ReplaceAllString(text, "")
+}

+ 0 - 3
utils/config.go

@@ -644,9 +644,6 @@ func init() {
 	// chrome配置
 	ChromePath = config["chrome_path"]
 
-	//模型服务器地址
-	LLM_SERVER = config["llm_server"]
-	LLM_MODEL = config["llm_model"]
 	// 初始化ES
 	initEs()
 

+ 12 - 9
utils/llm/eta_llm/eta_llm_client.go

@@ -80,19 +80,22 @@ func (ds *ETALLMClient) DocumentChat(query string, KnowledgeId string, history [
 		ChatHistory = append(ChatHistory, historyItem)
 	}
 	kbReq := eta_llm_http.DocumentChatRequest{
-		Query:          query,
-		KnowledgeId:    KnowledgeId,
-		History:        ChatHistory,
-		TopK:           3,
-		ScoreThreshold: 0.5,
+		Query:       query,
+		KnowledgeId: KnowledgeId,
+		History:     ChatHistory,
+		TopK:        3,
+		//ScoreThreshold: 0.5,
+		ScoreThreshold: 2,
 		Stream:         stream,
 		ModelName:      ds.LlmModel,
-		Temperature:    0.7,
-		MaxTokens:      0,
-		PromptName:     DEFALUT_PROMPT_NAME,
+		//Temperature:    0.7,
+		Temperature: 0.01,
+		MaxTokens:   0,
+		//PromptName:  DEFALUT_PROMPT_NAME,
 	}
-	fmt.Printf("%v", kbReq.History)
+	//fmt.Printf("%v", kbReq.History)
 	body, err := json.Marshal(kbReq)
+	fmt.Println(string(body))
 	if err != nil {
 		return
 	}