Skip to content

Commit f0682ca

Browse files
authored
Skip evaluations for tool calls llm and errored llm invocations #39 (#40)
1 parent 5661503 commit f0682ca

File tree

3 files changed

+41
-3
lines changed
  • instrumentation-genai/opentelemetry-instrumentation-langchain/src/opentelemetry/instrumentation/langchain
  • util
    • opentelemetry-util-genai-evals/src/opentelemetry/util/genai/evals
    • opentelemetry-util-genai/src/opentelemetry/util/genai

3 files changed

+41
-3
lines changed

instrumentation-genai/opentelemetry-instrumentation-langchain/src/opentelemetry/instrumentation/langchain/callback_handler.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -426,9 +426,24 @@ def on_llm_end(
426426
if generations and generations[0] and generations[0][0].message:
427427
content = getattr(generations[0][0].message, "content", None)
428428
if content is not None:
429-
inv.output_messages = [
430-
OutputMessage(role="assistant", parts=[Text(content=_safe_str(content))], finish_reason="stop")
431-
]
429+
finish_reason = generations[0][0].generation_info.get("finish_reason") if generations[0][
430+
0].generation_info else None
431+
if finish_reason == "tool_calls":
432+
inv.output_messages = [
433+
OutputMessage(
434+
role="assistant",
435+
parts=["ToolCall"],
436+
finish_reason=finish_reason or "tool_calls",
437+
)
438+
]
439+
else:
440+
inv.output_messages = [
441+
OutputMessage(
442+
role="assistant",
443+
parts=[Text(content=_safe_str(content))],
444+
finish_reason=finish_reason or "stop",
445+
)
446+
]
432447
llm_output = getattr(response, "llm_output", {}) or {}
433448
usage = llm_output.get("usage") or llm_output.get("token_usage") or {}
434449
inv.input_tokens = usage.get("prompt_tokens")

util/opentelemetry-util-genai-evals/src/opentelemetry/util/genai/evals/manager.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
)
3636
from .normalize import is_tool_only_llm
3737
from .registry import get_default_metrics, get_evaluator, list_evaluators
38+
from opentelemetry.semconv.attributes import (
39+
error_attributes as ErrorAttributes,
40+
)
3841

3942
_LOGGER = logging.getLogger(__name__)
4043

@@ -108,8 +111,24 @@ def on_completion(self, invocation: GenAI) -> None:
108111
if not self.has_evaluators:
109112
return
110113

114+
offer: bool = True
111115
if invocation.sample_for_evaluation:
112116
self.offer(invocation)
117+
# Do not evaluate if llm invocation is for tool invocation because it will not have output message for evaluations tests case.
118+
if isinstance(invocation, LLMInvocation):
119+
msgs = getattr(invocation, "output_messages", [])
120+
if msgs:
121+
first = msgs[0]
122+
if first.parts and first.parts[0] == "ToolCall" and first.finish_reason == "tool_calls":
123+
offer = False
124+
125+
# Do not evaluate if error
126+
error = invocation.attributes.get(ErrorAttributes.ERROR_TYPE)
127+
if error:
128+
offer = False
129+
130+
if offer:
131+
self.offer(invocation)
113132

114133
# Public API ---------------------------------------------------------
115134
def offer(self, invocation: GenAI) -> None:

util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ def genai_debug_log(*_args: Any, **_kwargs: Any) -> None: # type: ignore
113113
OTEL_INSTRUMENTATION_GENAI_DISABLE_DEFAULT_COMPLETION_CALLBACKS,
114114
)
115115
from opentelemetry.sdk.trace.sampling import Decision, TraceIdRatioBased
116+
from opentelemetry.semconv.attributes import (
117+
error_attributes as ErrorAttributes,
118+
)
116119

117120
_LOGGER = logging.getLogger(__name__)
118121

@@ -920,6 +923,7 @@ def fail_by_run_id(self, run_id: Any, error: Error) -> None:
920923
entity = self.get_entity(run_id)
921924
if entity is None:
922925
return
926+
entity.attributes.update({ErrorAttributes.ERROR_TYPE: getattr(error.type, "__qualname__", str(error.type))})
923927
if isinstance(entity, Workflow):
924928
self.fail_workflow(entity, error)
925929
elif isinstance(entity, (AgentCreation, AgentInvocation)):

0 commit comments

Comments
 (0)