Skip to content

feat(llmobs): track prompt caching for openai chat completions #13755

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Jul 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
efd5f60
oai prompt-caching
lievan Jun 24, 2025
578049f
p cache test
lievan Jun 24, 2025
3755f38
refactor test
lievan Jun 24, 2025
4765bb4
rel note
lievan Jun 24, 2025
bd5d2b0
rel note
lievan Jun 24, 2025
2f1bf38
reword again
lievan Jun 24, 2025
2f3b185
oai p cache
lievan Jun 24, 2025
35e6b1b
merg cone
lievan Jun 24, 2025
fb85ddd
stream
lievan Jun 24, 2025
7e80fb2
bad cmt
lievan Jun 24, 2025
5d65a4e
clarify
lievan Jun 24, 2025
e3bc420
move over to test agent
lievan Jun 26, 2025
ffaa1d1
rename
lievan Jun 26, 2025
698f4eb
change agent url
lievan Jun 27, 2025
de79ca3
reword relnote
lievan Jun 27, 2025
85e881e
clarify chat compls
lievan Jun 27, 2025
1eaef0c
Merge branch 'main' into evan.li/openai-prompt-caching
lievan Jul 1, 2025
030c7c0
p cache
lievan Jul 2, 2025
e37cdd7
Merge branch 'evan.li/openai-prompt-caching' of github.com:DataDog/dd…
lievan Jul 2, 2025
3699ba4
mv back cassettes
lievan Jul 3, 2025
f24fde3
rel note
lievan Jul 3, 2025
e98584b
conf
lievan Jul 3, 2025
d622208
p cache'
lievan Jul 3, 2025
53c1577
fix tests'
lievan Jul 3, 2025
1d8ec53
Merge branch 'main' into evan.li/openai-prompt-caching
lievan Jul 3, 2025
a8c2c61
lint
lievan Jul 4, 2025
5eb80bf
Merge branch 'evan.li/openai-prompt-caching' of github.com:DataDog/dd…
lievan Jul 4, 2025
9788e5a
fix test
lievan Jul 7, 2025
4b43006
Merge branch 'main' into evan.li/openai-prompt-caching
lievan Jul 7, 2025
a71f04d
fix another one
lievan Jul 8, 2025
08497e3
Merge branch 'main' into evan.li/openai-prompt-caching
lievan Jul 8, 2025
5949ddc
Merge branch 'main' into evan.li/openai-prompt-caching
lievan Jul 8, 2025
0266942
Merge branch 'main' into evan.li/openai-prompt-caching
lievan Jul 8, 2025
749f06a
Merge branch 'main' into evan.li/openai-prompt-caching
lievan Jul 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions ddtrace/llmobs/_integrations/openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from ddtrace.internal.constants import COMPONENT
from ddtrace.internal.utils.version import parse_version
from ddtrace.llmobs._constants import CACHE_READ_INPUT_TOKENS_METRIC_KEY
from ddtrace.llmobs._constants import INPUT_DOCUMENTS
from ddtrace.llmobs._constants import INPUT_TOKENS_METRIC_KEY
from ddtrace.llmobs._constants import METADATA
Expand Down Expand Up @@ -166,7 +167,13 @@ def _llmobs_set_meta_tags_from_embedding(span: Span, kwargs: Dict[str, Any], res
@staticmethod
def _extract_llmobs_metrics_tags(span: Span, resp: Any, span_kind: str) -> Dict[str, Any]:
"""Extract metrics from a chat/completion and set them as a temporary "_ml_obs.metrics" tag."""
token_usage = _get_attr(resp, "usage", None)
token_usage = None

# in the streamed responses case, `resp` is a list with `usage` being stored in the first element
if resp and isinstance(resp, list) and _get_attr(resp[0], "usage", None):
token_usage = resp[0].get("usage", {})
elif resp and getattr(resp, "usage", None):
token_usage = resp.usage
if token_usage is not None and span_kind != "workflow":
prompt_tokens = _get_attr(token_usage, "prompt_tokens", 0)
completion_tokens = _get_attr(token_usage, "completion_tokens", 0)
Expand All @@ -176,11 +183,21 @@ def _extract_llmobs_metrics_tags(span: Span, resp: Any, span_kind: str) -> Dict[
input_tokens = prompt_tokens or input_tokens
output_tokens = completion_tokens or output_tokens

return {
metrics = {
INPUT_TOKENS_METRIC_KEY: input_tokens,
OUTPUT_TOKENS_METRIC_KEY: output_tokens,
TOTAL_TOKENS_METRIC_KEY: input_tokens + output_tokens,
}

# Chat completions returns `prompt_tokens_details` while responses api returns `input_tokens_details`
prompt_tokens_details = _get_attr(token_usage, "prompt_tokens_details", {}) or _get_attr(
token_usage, "input_tokens_details", {}
)
cached_tokens = _get_attr(prompt_tokens_details, "cached_tokens", None)
if cached_tokens is not None:
metrics[CACHE_READ_INPUT_TOKENS_METRIC_KEY] = cached_tokens

return metrics
return get_llmobs_metrics_tags("openai", span)

def _get_base_url(self, **kwargs: Dict[str, Any]) -> Optional[str]:
Expand Down
4 changes: 4 additions & 0 deletions releasenotes/notes/oai-p-cache-78c511f97709a357.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
features:
- |
LLM Observability: Introduces tracking cached input token counts for OpenAI chats/responses prompt caching.
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
interactions:
- request:
body: '{"messages": [{"role": "system", "content": "You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer You are an expert software engineer
You are an expert software engineer You are an expert software engineer You
are an expert software engineer You are an expert software engineer You are
an expert software engineer You are an expert software engineer You are an expert
software engineer You are an expert software engineer You are an expert software
engineer You are an expert software engineer "}, {"role": "user", "content":
"How should I structure my database schema?"}], "model": "gpt-4o", "max_tokens":
100, "temperature": 0.1}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '7382'
content-type:
- application/json
cookie:
- __cf_bm=L.6vPBT5JOAquFh5oqDsUZWIi6Y.5ybhwVhTgAPOYVQ-1751568116-1.0.1.1-AxrHzVxe3Xgq3X8MlkfhZmH82OJ9AWtYAi4Kf1J1S.aX8CdDwpHMzIbTNZ2BzpBdNc4IUkLWyqNfktbhzThvX7IC686a5l1K9k8KMNOuw44;
_cfuvid=ZNE8kE20HwdKQyDSDPEl44Ta8a8H_cstpKAXK9tlA.0-1751568116448-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.0.0
x-stainless-arch:
- arm64
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.0.0
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.10.13
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
H4sIAAAAAAAAAwAAAP//dFTbjts2EH33Vwz4lCxsw3L3Br9tECRtEQTYbNoC7QbGmBxJk1IkOxwl
VYP994Ky19ZumxdB4JlzeObGbzMAw85swNgW1XbJL16ln2/wdX/+8fXt7c3b2zvp3r37dbj88Nvv
H/Ng5oURd5/J6iNraWOXPCnHsIetECoV1erqorq4vK6qyxHooiNfaE3SxXlcrFfr88XqerG6PBDb
yJay2cAfMwCAb+O3WAyO/jYbWM0fTzrKGRsym2MQgJHoy4nBnDkrBjXzE2hjUAqj6zuV3movHBpA
cKi4w0yQbUsdAtU1WeUv5AfgDFZ6y+ihjgIU8p5VOMBBqRHWYQ6JpI7SYbA0BwwOskWPO/aswxJ+
JCFAIcixI2gokKCHpmdHngNl0Agt+QRD7MFR5iYAgsRdn/W5vc19uA/VEs7OfgmOpKTp4AP91bNQ
R0Hz5uzsPgDAAt6itiSA3oO2BDIJGj32J4GCjzkVB4HIFUtZo9DyIPaTo6BcD2No+VWmDC8Ud57y
y1FPyGOZgtxyyrAj/UoUSny3LKbXxfT7UiXP/4yBJ6s3KfkBwhQE6f2+NOS544BaUnB9cBjsMF44
toOeNePR8J2iKHxlbUfLNUvWww2llx28qN6/2RtPEi2Rm06LUN1nLMMaeu8nAIYQdZ9mmdNPB+Th
OJk+NkniLj+jmpoD53YrhDmGMoWeQqOtGfGHGcCncQf6J2NtksQu6VbjnzReWK3XhyUwp7WbwKtH
VKOinwA/HHlPJLeOFNnnySIZi7YlN+FWF+tjGtg7jidsNZtk/19L/ye/rwCHZqLyXfkTYC0lJbdN
Qo7t07RPYULlafpe2LHWo2GTSb6wpa0ySemIoxp7v381TB6yUretOTQkSXj/dNRpu7q6vqpoje7a
zB5m/wIAAP//AwDhe2k9QwUAAA==
headers:
CF-RAY:
- 959885181e8fa4a0-EWR
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 03 Jul 2025 18:41:59 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
cf-cache-status:
- DYNAMIC
openai-organization:
- datadog-staging
openai-processing-ms:
- '2807'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-envoy-upstream-service-time:
- '2811'
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29998186'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 3ms
x-request-id:
- req_c0f374d27da52b49fbc9e28b67f5496a
status:
code: 200
message: OK
version: 1
Loading
Loading