feat(tenant): make monitoring parse & compliance judge models configurable
Replace the hardcoded doubao-lite model used for monitoring answer parsing and compliance LLM judging with configurable values, resolved from config with env overrides and a legacy default fallback. - Add llm.monitoring_answer_parse_model and compliance.llm_judge_model to config struct, env overrides, and all config files - Thread the resolved model through MonitoringCallbackService via a ConfigProvider and into parseMonitoringAnswerWithLLM - Pass compliance.llm_judge_model into the review-job LLM request Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
monitoringAnswerParseLLMModel = "doubao-seed-2-0-lite-260215"
|
||||
defaultMonitoringAnswerParseLLMModel = "doubao-seed-2-0-lite-260215"
|
||||
monitoringAnswerParseLLMTimeout = 30 * time.Second
|
||||
monitoringAnswerParseLLMMaxOutputTokens = 600
|
||||
)
|
||||
@@ -63,6 +63,7 @@ func parseMonitoringAnswerWithLLM(
|
||||
client sharedllm.Client,
|
||||
answer string,
|
||||
brandName string,
|
||||
model string,
|
||||
) (monitoringAnswerParseSummary, error) {
|
||||
answer = strings.TrimSpace(answer)
|
||||
brandName = strings.TrimSpace(brandName)
|
||||
@@ -72,9 +73,13 @@ func parseMonitoringAnswerWithLLM(
|
||||
if brandName == "" {
|
||||
return monitoringAnswerParseSummary{}, fmt.Errorf("brand name is empty")
|
||||
}
|
||||
model = strings.TrimSpace(model)
|
||||
if model == "" {
|
||||
model = defaultMonitoringAnswerParseLLMModel
|
||||
}
|
||||
|
||||
result, err := client.Generate(ctx, sharedllm.GenerateRequest{
|
||||
Model: monitoringAnswerParseLLMModel,
|
||||
Model: model,
|
||||
Prompt: buildMonitoringAnswerParsePrompt(answer, brandName),
|
||||
Timeout: monitoringAnswerParseLLMTimeout,
|
||||
MaxOutputTokens: monitoringAnswerParseLLMMaxOutputTokens,
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"golang.org/x/net/publicsuffix"
|
||||
|
||||
sharedauth "github.com/geo-platform/tenant-api/internal/shared/auth"
|
||||
"github.com/geo-platform/tenant-api/internal/shared/config"
|
||||
sharedllm "github.com/geo-platform/tenant-api/internal/shared/llm"
|
||||
"github.com/geo-platform/tenant-api/internal/shared/messaging/rabbitmq"
|
||||
"github.com/geo-platform/tenant-api/internal/shared/response"
|
||||
@@ -52,6 +53,7 @@ type MonitoringCallbackService struct {
|
||||
monitoringPool *pgxpool.Pool
|
||||
rabbitMQ *rabbitmq.Client
|
||||
llm sharedllm.Client
|
||||
cfg config.Provider
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
@@ -70,6 +72,13 @@ func NewMonitoringCallbackService(
|
||||
}
|
||||
}
|
||||
|
||||
func (s *MonitoringCallbackService) WithConfigProvider(provider config.Provider) *MonitoringCallbackService {
|
||||
if s != nil {
|
||||
s.cfg = provider
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
type MonitoringTaskResultRequest struct {
|
||||
LeaseToken string `json:"lease_token" binding:"required"`
|
||||
Status string `json:"status"`
|
||||
@@ -2732,7 +2741,7 @@ func (s *MonitoringCallbackService) enrichMonitoringParsePayload(ctx context.Con
|
||||
parseVersion := resolveMonitoringParseVersion(req)
|
||||
|
||||
if shouldUseMonitoringLLMParse(req) && strings.TrimSpace(answer) != "" && s.llm != nil && s.llm.Validate() == nil {
|
||||
llmSummary, llmErr := parseMonitoringAnswerWithLLM(ctx, s.llm, answer, brandName)
|
||||
llmSummary, llmErr := parseMonitoringAnswerWithLLM(ctx, s.llm, answer, brandName, s.monitoringAnswerParseModel())
|
||||
if llmErr != nil {
|
||||
if s.logger != nil {
|
||||
s.logger.Warn("monitoring answer llm parse failed",
|
||||
@@ -2782,6 +2791,17 @@ func shouldUseMonitoringLLMParse(req MonitoringTaskResultRequest) bool {
|
||||
return !hasCompleteMonitoringParsePayload(req)
|
||||
}
|
||||
|
||||
func (s *MonitoringCallbackService) monitoringAnswerParseModel() string {
|
||||
if s != nil && s.cfg != nil {
|
||||
if cfg := s.cfg.Current(); cfg != nil {
|
||||
if model := strings.TrimSpace(cfg.LLM.MonitoringAnswerParseModel); model != "" {
|
||||
return model
|
||||
}
|
||||
}
|
||||
}
|
||||
return defaultMonitoringAnswerParseLLMModel
|
||||
}
|
||||
|
||||
func (s *MonitoringCallbackService) buildCitationFacts(ctx context.Context, tx pgx.Tx, tenantID int64, platformID string, inputs []MonitoringSourceItem) ([]monitoringCitationFact, error) {
|
||||
if len(inputs) == 0 {
|
||||
return nil, nil
|
||||
|
||||
@@ -12,8 +12,26 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/geo-platform/tenant-api/internal/shared/config"
|
||||
)
|
||||
|
||||
func TestMonitoringAnswerParseModelUsesConfig(t *testing.T) {
|
||||
svc := (&MonitoringCallbackService{}).WithConfigProvider(config.NewStaticProvider(&config.Config{
|
||||
LLM: config.LLMConfig{MonitoringAnswerParseModel: " configured-monitoring-model "},
|
||||
}))
|
||||
|
||||
if got := svc.monitoringAnswerParseModel(); got != "configured-monitoring-model" {
|
||||
t.Fatalf("monitoringAnswerParseModel() = %q, want configured-monitoring-model", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMonitoringAnswerParseModelDefaultsToLegacyLite(t *testing.T) {
|
||||
if got := (&MonitoringCallbackService{}).monitoringAnswerParseModel(); got != defaultMonitoringAnswerParseLLMModel {
|
||||
t.Fatalf("monitoringAnswerParseModel() = %q, want %q", got, defaultMonitoringAnswerParseLLMModel)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecideHeartbeatPrimaryLease(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
@@ -1120,6 +1120,7 @@ func (s *Service) ProcessReviewJob(ctx context.Context, msg ReviewJobMessage) er
|
||||
return s.markReviewJobDone(ctx, job.ID)
|
||||
}
|
||||
result, err := s.llm.Generate(ctx, sharedllm.GenerateRequest{
|
||||
Model: strings.TrimSpace(cfg.LLMJudgeModel),
|
||||
Prompt: prompt,
|
||||
Timeout: cfg.ReviewWorkerTimeout,
|
||||
MaxOutputTokens: 900,
|
||||
|
||||
@@ -18,7 +18,8 @@ type DesktopMonitoringHandler struct {
|
||||
|
||||
func NewDesktopMonitoringHandler(a *bootstrap.App) *DesktopMonitoringHandler {
|
||||
return &DesktopMonitoringHandler{
|
||||
svc: app.NewMonitoringCallbackService(a.DB, a.MonitoringDB, a.RabbitMQ, a.LLM, a.Logger),
|
||||
svc: app.NewMonitoringCallbackService(a.DB, a.MonitoringDB, a.RabbitMQ, a.LLM, a.Logger).
|
||||
WithConfigProvider(a.ConfigStore),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user