Module: Datadog::AIGuard::Evaluation

Defined in:
lib/datadog/ai_guard/evaluation.rb,
lib/datadog/ai_guard/evaluation/client.rb,
lib/datadog/ai_guard/evaluation/result.rb,
lib/datadog/ai_guard/evaluation/message.rb,
lib/datadog/ai_guard/evaluation/outcome.rb,
lib/datadog/ai_guard/evaluation/request.rb,
lib/datadog/ai_guard/evaluation/response.rb,
lib/datadog/ai_guard/evaluation/tool_call.rb,
lib/datadog/ai_guard/evaluation/content_part.rb,
lib/datadog/ai_guard/evaluation/no_op_result.rb,
lib/datadog/ai_guard/evaluation/message_builder.rb,
sig/datadog/ai_guard/evaluation.rbs,
sig/datadog/ai_guard/evaluation/client.rbs,
sig/datadog/ai_guard/evaluation/result.rbs,
sig/datadog/ai_guard/evaluation/message.rbs,
sig/datadog/ai_guard/evaluation/outcome.rbs,
sig/datadog/ai_guard/evaluation/request.rbs,
sig/datadog/ai_guard/evaluation/response.rbs,
sig/datadog/ai_guard/evaluation/tool_call.rbs,
sig/datadog/ai_guard/evaluation/content_part.rbs,
sig/datadog/ai_guard/evaluation/no_op_result.rbs,
sig/datadog/ai_guard/evaluation/message_builder.rbs

Overview

module that contains a function for performing AI Guard Evaluation request and creating ai_guard span with required tags

Defined Under Namespace

Classes: MessageBuilder

Class Method Summary collapse

Class Method Details

.perform(messages, allow_raise: true) ⇒ Result

Parameters:

  • messages (Array[Message])
  • allow_raise: (Boolean) (defaults to: true)

Returns:

  • (Result)

Raises:

  • (ArgumentError)


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/datadog/ai_guard/evaluation.rb', line 9

def perform(messages, allow_raise: true)
  raise ArgumentError, "Messages must not be empty" if messages&.empty?

  Tracing.trace(Ext::SPAN_NAME) do |span, trace|
    trace.keep!
    trace.set_tag(
      Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER,
      Tracing::Sampling::Ext::Decision::AI_GUARD
    )
    trace.set_distributed_source(Ext::PRODUCT_BIT)
    trace.set_tag(Ext::EVENT_TAG, true)
    trace.set_tag(Ext::TRACE_EXECUTED_TAG, "1")

    Ext::TRACE_ANOMALY_DETECTION_TAGS.each do |tag|
      value = trace.get_tag(tag)
      span.set_tag(tag, value) if value
    end

    if (last_message = messages.last)
      if (tool_call = last_message.tool_calls.first)
        span.set_tag(Ext::TARGET_TAG, "tool")
        span.set_tag(Ext::TOOL_NAME_TAG, tool_call.tool_name)
      elsif last_message.tool_call_id
        span.set_tag(Ext::TARGET_TAG, "tool")

        messages.reverse_each do |message|
          # @type var tool_call: ToolCall?
          tool_call = message.tool_calls.find { |call| call.id == last_message.tool_call_id }
          break span.set_tag(Ext::TOOL_NAME_TAG, tool_call.tool_name) if tool_call
        end
      else
        span.set_tag(Ext::TARGET_TAG, "prompt")
      end
    end

    outcome =
      begin
        Client.evaluate(messages)
      rescue
        Metrics::Telemetry.report_error
        raise
      end

    result = outcome.result
    redaction = outcome.redaction

    span.set_tag(Ext::ACTION_TAG, result.action)
    span.set_tag(Ext::REASON_TAG, result.reason)
    span.set_tag(Ext::REDACTED_TAG, redaction.redacted?) if redaction.performed?

    span.set_metastruct_tag(
      Ext::METASTRUCT_TAG,
      {
        messages: truncate_content(truncate_messages(result.messages).map(&:to_h)),
        attack_categories: result.tags,
        sds: result.sds_findings,
        tag_probs: result.tag_probabilities,
      }
    )

    blocked = allow_raise && outcome.block?
    Metrics::Telemetry.report_evaluation(outcome, blocked: blocked)

    if blocked
      span.set_tag(Ext::BLOCKED_TAG, true)
      raise AIGuardAbortError.new(action: result.action, reason: result.reason, tags: result.tags)
    end

    result
  end
end

.perform_no_op(messages) ⇒ NoOpResult

Parameters:

  • messages (Array[Message])

Returns:

  • (NoOpResult)


81
82
83
84
85
# File 'lib/datadog/ai_guard/evaluation.rb', line 81

def perform_no_op(messages)
  AIGuard.logger&.warn("AI Guard is disabled, messages were not evaluated")

  NoOpResult.new(messages)
end