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:
2026-07-09 17:04:01 +08:00
parent fb142e4ca7
commit c8dceb43d7
13 changed files with 103 additions and 17 deletions
@@ -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