feat: add rag answerability gate types
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
package executor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"cs-agent/internal/ai/runtime/internal/impl/callbacks"
|
||||
"cs-agent/internal/ai/runtime/internal/impl/factory"
|
||||
"cs-agent/internal/ai/runtime/internal/impl/retrievers"
|
||||
"cs-agent/internal/models"
|
||||
|
||||
"github.com/cloudwego/eino/components/model"
|
||||
"github.com/cloudwego/eino/schema"
|
||||
)
|
||||
|
||||
const (
|
||||
answerabilityNodeRetrieve = "retrieve_knowledge"
|
||||
answerabilityNodeGrade = "grade_answerability"
|
||||
answerabilityNodeAllow = "allow_agent"
|
||||
answerabilityNodeFallback = "fallback"
|
||||
|
||||
answerabilityStatusSkipped = "skipped"
|
||||
answerabilityStatusAnswerable = "answerable"
|
||||
answerabilityStatusUnanswerable = "unanswerable"
|
||||
)
|
||||
|
||||
type knowledgeContextRetriever interface {
|
||||
KnowledgeBaseIDs() []int64
|
||||
RetrieveContextByOptions(ctx context.Context, opts retrievers.KnowledgeRetrieveOptions, query string) (*retrievers.KnowledgeRetrieveResult, error)
|
||||
}
|
||||
|
||||
type answerabilityRetrieverFactory func(aiAgent models.AIAgent) knowledgeContextRetriever
|
||||
|
||||
type answerabilityChatModelFactory func(ctx context.Context, aiConfig models.AIConfig) (model.BaseChatModel, error)
|
||||
|
||||
type KnowledgeAnswerabilityGate struct {
|
||||
newRetriever answerabilityRetrieverFactory
|
||||
newChatModel answerabilityChatModelFactory
|
||||
now func() time.Time
|
||||
}
|
||||
|
||||
type answerabilityGateInput struct {
|
||||
Request RunInput
|
||||
Summary *RunResult
|
||||
Collector *callbacks.RuntimeTraceCollector
|
||||
Messages []*schema.Message
|
||||
}
|
||||
|
||||
type answerabilityGateState struct {
|
||||
Input answerabilityGateInput
|
||||
KnowledgeIDs []int64
|
||||
RetrieveResult *retrievers.KnowledgeRetrieveResult
|
||||
Decision knowledgeGuardDecision
|
||||
Grade answerabilityDecision
|
||||
SkipGate bool
|
||||
FallbackReply string
|
||||
ErrorMessage string
|
||||
}
|
||||
|
||||
type answerabilityDecision struct {
|
||||
Answerable bool `json:"answerable"`
|
||||
Reason string `json:"reason"`
|
||||
SupportingChunkIDs []string `json:"supportingChunkIds"`
|
||||
MissingInfo []string `json:"missingInfo"`
|
||||
}
|
||||
|
||||
func NewKnowledgeAnswerabilityGate() *KnowledgeAnswerabilityGate {
|
||||
chatModelFactory := factory.NewChatModelFactory()
|
||||
return &KnowledgeAnswerabilityGate{
|
||||
newRetriever: func(aiAgent models.AIAgent) knowledgeContextRetriever {
|
||||
return retrievers.NewKnowledgeRetriever(aiAgent)
|
||||
},
|
||||
newChatModel: func(ctx context.Context, aiConfig models.AIConfig) (model.BaseChatModel, error) {
|
||||
return chatModelFactory.Build(ctx, aiConfig)
|
||||
},
|
||||
now: time.Now,
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,18 @@ func resolveKnowledgeFallbackReply(aiAgent models.AIAgent) string {
|
||||
}
|
||||
}
|
||||
|
||||
func resolveKnowledgeHumanSupportFallback(aiAgent models.AIAgent) string {
|
||||
base := strings.TrimSpace(resolveKnowledgeFallbackReply(aiAgent))
|
||||
if base == "" {
|
||||
base = "当前知识库暂无明确信息。"
|
||||
}
|
||||
suggestion := "建议你联系人工客服进一步确认。"
|
||||
if strings.Contains(base, suggestion) {
|
||||
return base
|
||||
}
|
||||
return strings.TrimSpace(base + " " + suggestion)
|
||||
}
|
||||
|
||||
func buildKnowledgeRuntimeInstruction(answerMode enums.KnowledgeAnswerMode, fallbackReply string) string {
|
||||
fallbackReply = strings.TrimSpace(fallbackReply)
|
||||
if fallbackReply == "" {
|
||||
|
||||
@@ -100,6 +100,29 @@ func TestBuildKnowledgeUnavailableDecisionSkipsWhenAgentHasNoKnowledge(t *testin
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveKnowledgeHumanSupportFallbackUsesAgentMessage(t *testing.T) {
|
||||
agent := newKnowledgeGuardAgentFixture()
|
||||
agent.FallbackMessage = "我暂时没有找到足够准确的信息。"
|
||||
|
||||
got := resolveKnowledgeHumanSupportFallback(agent)
|
||||
|
||||
want := "我暂时没有找到足够准确的信息。 建议你联系人工客服进一步确认。"
|
||||
if got != want {
|
||||
t.Fatalf("unexpected fallback: %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveKnowledgeHumanSupportFallbackUsesDefault(t *testing.T) {
|
||||
agent := newKnowledgeGuardAgentFixture()
|
||||
|
||||
got := resolveKnowledgeHumanSupportFallback(agent)
|
||||
|
||||
want := "当前知识库暂无明确信息。 建议你联系人工客服进一步确认。"
|
||||
if got != want {
|
||||
t.Fatalf("unexpected fallback: %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func newKnowledgeGuardAgentFixture() models.AIAgent {
|
||||
return models.AIAgent{
|
||||
FallbackMode: enums.AIAgentFallbackModeNoAnswer,
|
||||
|
||||
Reference in New Issue
Block a user