package oci import ( "context" "fmt" "github.com/oracle/oci-go-sdk/v65/common" "github.com/oracle/oci-go-sdk/v65/generativeaiinference" ) // RerankRank 是重排结果的一项:index 指向入参 documents 下标。 type RerankRank struct { Index int Score float64 } // GuardrailCategory 是内容审核分类得分(OVERALL / BLOCKLIST)。 type GuardrailCategory struct { Name string Score float64 } // GuardrailPiiHit 是一处 PII 命中(片段原文与位置)。 type GuardrailPiiHit struct { Text string Label string Score float64 Offset int Length int } // GuardrailsOutcome 汇总 ApplyGuardrails 三能力结果。 type GuardrailsOutcome struct { Categories []GuardrailCategory Pii []GuardrailPiiHit PromptInjectionScore *float64 } // GenAiRerank 实现 Client:文档重排(on-demand serving),返回按相关度排序的下标与得分。 func (c *RealClient) GenAiRerank(ctx context.Context, cred Credentials, region, modelOcid, query string, documents []string, topN *int) ([]RerankRank, error) { ic, err := c.genAiInferenceClient(cred, region) if err != nil { return nil, err } resp, err := ic.RerankText(ctx, generativeaiinference.RerankTextRequest{ RerankTextDetails: generativeaiinference.RerankTextDetails{ CompartmentId: &cred.TenancyOCID, ServingMode: generativeaiinference.OnDemandServingMode{ModelId: &modelOcid}, Input: &query, Documents: documents, TopN: topN, }, }) if err != nil { return nil, fmt.Errorf("genai rerank: %w", err) } ranks := make([]RerankRank, 0, len(resp.DocumentRanks)) for _, r := range resp.DocumentRanks { if r.Index == nil || r.RelevanceScore == nil { continue } ranks = append(ranks, RerankRank{Index: *r.Index, Score: *r.RelevanceScore}) } return ranks, nil } // GenAiApplyGuardrails 实现 Client:对单条文本执行内容审核 / PII / 提示注入三检测。 func (c *RealClient) GenAiApplyGuardrails(ctx context.Context, cred Credentials, region, text string) (*GuardrailsOutcome, error) { ic, err := c.genAiInferenceClient(cred, region) if err != nil { return nil, err } resp, err := ic.ApplyGuardrails(ctx, generativeaiinference.ApplyGuardrailsRequest{ ApplyGuardrailsDetails: generativeaiinference.ApplyGuardrailsDetails{ CompartmentId: &cred.TenancyOCID, Input: generativeaiinference.GuardrailsTextInput{Content: common.String(text)}, GuardrailConfigs: &generativeaiinference.GuardrailConfigs{ ContentModerationConfig: &generativeaiinference.ContentModerationConfiguration{Categories: []string{"OVERALL"}}, PersonallyIdentifiableInformationConfig: &generativeaiinference.PersonallyIdentifiableInformationConfiguration{Types: []string{}}, PromptInjectionConfig: &generativeaiinference.PromptInjectionConfiguration{}, }, }, }) if err != nil { return nil, fmt.Errorf("genai guardrails: %w", err) } return guardrailsOutcome(resp.Results), nil } // guardrailsOutcome 把 SDK 结果换算为 IR;空段置空切片,得分缺失跳过。 func guardrailsOutcome(r *generativeaiinference.GuardrailsResults) *GuardrailsOutcome { out := &GuardrailsOutcome{} if r == nil { return out } if r.ContentModeration != nil { for _, cat := range r.ContentModeration.Categories { if cat.Name == nil || cat.Score == nil { continue } out.Categories = append(out.Categories, GuardrailCategory{Name: *cat.Name, Score: *cat.Score}) } } for _, hit := range r.PersonallyIdentifiableInformation { h := GuardrailPiiHit{} if hit.Text != nil { h.Text = *hit.Text } if hit.Label != nil { h.Label = *hit.Label } if hit.Score != nil { h.Score = *hit.Score } if hit.Offset != nil { h.Offset = *hit.Offset } if hit.Length != nil { h.Length = *hit.Length } out.Pii = append(out.Pii, h) } if r.PromptInjection != nil && r.PromptInjection.Score != nil { out.PromptInjectionScore = r.PromptInjection.Score } return out }