feat: 新增知识库调用demo、段落输出demo
This commit is contained in:
parent
941827ce41
commit
e8061799b8
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"ai_scheduler/internal/tools"
|
"ai_scheduler/internal/tools"
|
||||||
"ai_scheduler/internal/tools/bbxt"
|
"ai_scheduler/internal/tools/bbxt"
|
||||||
"ai_scheduler/utils"
|
"ai_scheduler/utils"
|
||||||
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
@ -52,6 +53,7 @@ func NewGroupConfigBiz(
|
||||||
conf *config.Config,
|
conf *config.Config,
|
||||||
reportDailyCacheImpl *impl.ReportDailyCacheImpl,
|
reportDailyCacheImpl *impl.ReportDailyCacheImpl,
|
||||||
rdb *utils.Rdb,
|
rdb *utils.Rdb,
|
||||||
|
toolManager *tools.Manager,
|
||||||
) *GroupConfigBiz {
|
) *GroupConfigBiz {
|
||||||
return &GroupConfigBiz{
|
return &GroupConfigBiz{
|
||||||
botTools: tools.BootTools,
|
botTools: tools.BootTools,
|
||||||
|
|
@ -61,6 +63,7 @@ func NewGroupConfigBiz(
|
||||||
conf: conf,
|
conf: conf,
|
||||||
reportDailyCacheImpl: reportDailyCacheImpl,
|
reportDailyCacheImpl: reportDailyCacheImpl,
|
||||||
rdb: rdb,
|
rdb: rdb,
|
||||||
|
toolManager: toolManager,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,6 +258,9 @@ func (g *GroupConfigBiz) handleMatch(ctx context.Context, rec *entitys.Recognize
|
||||||
return g.handleReport(ctx, rec, pointTask, groupConfig)
|
return g.handleReport(ctx, rec, pointTask, groupConfig)
|
||||||
case constants.TaskTypeCozeWorkflow:
|
case constants.TaskTypeCozeWorkflow:
|
||||||
return g.handleCozeWorkflow(ctx, rec, pointTask)
|
return g.handleCozeWorkflow(ctx, rec, pointTask)
|
||||||
|
case constants.TaskTypeKnowle: // 知识库V2版本
|
||||||
|
return g.handleKnowledgeV2(ctx, rec, pointTask)
|
||||||
|
// return g.handleKnowledgeV3(ctx, rec, pointTask)
|
||||||
default:
|
default:
|
||||||
return g.otherTask(ctx, rec)
|
return g.otherTask(ctx, rec)
|
||||||
}
|
}
|
||||||
|
|
@ -459,3 +465,128 @@ func (g *GroupConfigBiz) GetReportCache(ctx context.Context, day time.Time, tota
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleKnowledgeV2 处理知识库V2版本
|
||||||
|
func (g *GroupConfigBiz) handleKnowledgeV2(ctx context.Context, rec *entitys.Recognize, pointTask *model.AiBotTool) (err error) {
|
||||||
|
req := l_request.Request{
|
||||||
|
Method: "POST",
|
||||||
|
Url: "http://127.0.0.1:9600/query",
|
||||||
|
Headers: map[string]string{
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Tenant-ID": "default",
|
||||||
|
},
|
||||||
|
Json: map[string]interface{}{
|
||||||
|
"query": rec.UserContent.Text,
|
||||||
|
"mode": "naive",
|
||||||
|
"stream": true,
|
||||||
|
"think": false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
resp, err := req.SendNoParseResponse()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("请求失败,err: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
err = g.connectAndReadSSE(resp, rec.Ch, true)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 连接 SSE 并读取数据
|
||||||
|
// event: thinking
|
||||||
|
// data: {"text": "1. 上下文检索中...\n"}
|
||||||
|
// event: answer
|
||||||
|
// data: {"text": "根据"}
|
||||||
|
func (g *GroupConfigBiz) connectAndReadSSE(resp *http.Response, channel chan entitys.Response, useParagraphMode bool) error {
|
||||||
|
scanner := bufio.NewScanner(resp.Body)
|
||||||
|
var buffer strings.Builder
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
|
||||||
|
// 解析 data 行
|
||||||
|
if strings.HasPrefix(line, "data:") {
|
||||||
|
dataStr := strings.TrimSpace(strings.TrimPrefix(line, "data:"))
|
||||||
|
if dataStr == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var data struct {
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal([]byte(dataStr), &data); err != nil {
|
||||||
|
log.Errorf("SSE数据解析失败: %v body: %s", err, dataStr)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.Text != "" {
|
||||||
|
if useParagraphMode {
|
||||||
|
// 存入缓冲区
|
||||||
|
buffer.WriteString(data.Text)
|
||||||
|
content := buffer.String()
|
||||||
|
|
||||||
|
// 检查是否有换行符,按段落输出
|
||||||
|
if idx := strings.LastIndex(content, "\n"); idx != -1 {
|
||||||
|
// 发送直到最后一个换行符的内容
|
||||||
|
toSend := content[:idx+1]
|
||||||
|
entitys.ResStream(channel, "", toSend)
|
||||||
|
|
||||||
|
// 重置缓冲区,保留剩余部分
|
||||||
|
remaining := content[idx+1:]
|
||||||
|
buffer.Reset()
|
||||||
|
buffer.WriteString(remaining)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 逐字输出模式:直接发送
|
||||||
|
entitys.ResStream(channel, "", data.Text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return fmt.Errorf("读取SSE流中断: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送缓冲区剩余内容(仅在段落模式下需要)
|
||||||
|
if useParagraphMode && buffer.Len() > 0 {
|
||||||
|
entitys.ResStream(channel, "", buffer.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleKnowledgeV3 处理知识库V3同步版本
|
||||||
|
func (g *GroupConfigBiz) handleKnowledgeV3(ctx context.Context, rec *entitys.Recognize, pointTask *model.AiBotTool) (err error) {
|
||||||
|
req := l_request.Request{
|
||||||
|
Method: "POST",
|
||||||
|
Url: "http://127.0.0.1:9600/query",
|
||||||
|
Headers: map[string]string{
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Tenant-ID": "default",
|
||||||
|
},
|
||||||
|
Json: map[string]interface{}{
|
||||||
|
"query": rec.UserContent.Text,
|
||||||
|
"mode": "naive",
|
||||||
|
"stream": false,
|
||||||
|
"think": false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
resp, err := req.Send()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("请求失败,err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
obj := make(map[string]string)
|
||||||
|
if err := json.Unmarshal([]byte(resp.Text), &obj); err != nil {
|
||||||
|
return fmt.Errorf("解析响应失败,err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
entitys.ResText(rec.Ch, "", obj["response"])
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const DefaultInterval = 100 * time.Millisecond
|
const DefaultInterval = 100 * time.Millisecond
|
||||||
const HeardBeatX = 100
|
const HeardBeatX = 1000
|
||||||
|
|
||||||
type SendCardClient struct {
|
type SendCardClient struct {
|
||||||
Auth *Auth
|
Auth *Auth
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue