Files
Cyrene/backend/ai-core/internal/subsession/knowledge_provider.go
T
AskaEth 71f0a1abdb feat: Go模块路径迁移 + Docker生产部署适配 + ethend Docker兼容
- 所有Go模块路径从 github.com/yourname/cyrene-ai 迁移到 git.yeij.top/AskaEth/Cyrene
- 5个Go Dockerfile添加 GOPROXY=https://goproxy.cn,direct 解决国内构建问题
- ai-core go.mod 添加 pkg/plugins replace 指令
- Caddyfile 简化为 http:// 通配 + handle 保留 /api 前缀
- ethend Dockerfile 适配 (npm install + 仅 COPY package.json)
- ethend 新增 RUNNING_IN_DOCKER 环境变量,健康检查改用Docker服务名
- ethend 数据库状态检查支持Docker hostname (postgres/redis/qdrant/minio)
- process-manager 新增 CONTAINER_SVC_MAP + Docker模式自动检测
- 统一 docker-compose.dev.db.yml 卷名 (pg_data/redis_data/qdrant_data/minio_data)
- docker-compose.yml ethend服务挂载docker.sock + 端口变量化
- 清理 .env 统一后的残留文件与提示信息

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 13:43:22 +08:00

97 lines
2.5 KiB
Go

package subsession
import (
"context"
"fmt"
"time"
"git.yeij.top/AskaEth/Cyrene/ai-core/internal/model"
"git.yeij.top/AskaEth/Cyrene/ai-core/internal/rag"
"git.yeij.top/AskaEth/Cyrene/pkg/logger"
)
// KnowledgeProvider searches the knowledge base for relevant information.
type KnowledgeProvider struct {
retriever *rag.Retriever
}
// NewKnowledgeProvider creates a knowledge subsession provider.
func NewKnowledgeProvider(retriever *rag.Retriever) *KnowledgeProvider {
return &KnowledgeProvider{retriever: retriever}
}
func (p *KnowledgeProvider) Type() model.SubSessionType {
return model.SubSessionKnowledge
}
func (p *KnowledgeProvider) CanHandle(_ context.Context, intent *model.IntentResult, _ string) bool {
if intent == nil {
return true
}
// Activate for technical questions, how-to queries, and factual questions
switch intent.Primary {
case "knowledge", "technical", "how_to", "factual", "research":
return true
case "chat":
// For general chat, only search if there might be relevant info
return false
}
return true
}
func (p *KnowledgeProvider) Priority() int {
return 3
}
func (p *KnowledgeProvider) Timeout() time.Duration {
return 15 * time.Second
}
func (p *KnowledgeProvider) CreateContext(ctx context.Context, params CreateContextParams) ([]model.LLMMessage, error) {
return []model.LLMMessage{
{Role: model.RoleSystem, Content: "知识库检索子会话"},
{Role: model.RoleUser, Content: params.UserMessage},
}, nil
}
func (p *KnowledgeProvider) Execute(ctx context.Context, subCtx []model.LLMMessage) (*model.SubSessionResult, error) {
userMessage := ""
for i := len(subCtx) - 1; i >= 0; i-- {
if subCtx[i].Role == model.RoleUser {
userMessage = subCtx[i].Content
break
}
}
if userMessage == "" {
return nil, fmt.Errorf("无法提取用户消息")
}
result := &model.SubSessionResult{
Type: model.SubSessionKnowledge,
Confidence: 0,
}
if p.retriever == nil {
result.Summary = "(知识库未就绪)"
return result, nil
}
retrieval, err := p.retriever.Retrieve(ctx, userMessage, 3)
if err != nil {
logger.Printf("[knowledge-subsession] 知识检索失败: %v", err)
result.Error = fmt.Sprintf("检索失败: %v", err)
result.Summary = "(知识库检索失败)"
return result, nil
}
if len(retrieval.Results) == 0 {
result.Summary = "(未找到相关知识)"
return result, nil
}
result.Summary = retrieval.Summary
result.Confidence = 0.6
logger.Printf("[knowledge-subsession] 完成: 找到 %d 条知识", len(retrieval.Results))
return result, nil
}