Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -329,3 +329,76 @@ curl -X POST "https://api.openai.com/v1/chat/completions" \
</Step>

</Steps>

## Logging Prompts in Traces

<Steps>

<Step title="Setup tracing">

Attach the `@observe` decorator to functions/methods that make up your agent, and specify type `llm` for your LLM-calling functions.

```python main.py {4}
from deepeval.tracing import observe

@observe(type="llm", model="gpt-4.1")
def your_llm_component():
...
```

<Tip>
Specifying the type is necessary because logging prompts is only available for
LLM spans.
</Tip>

</Step>

<Step title="Pull and interpolate prompt">

Pull and interpolate the prompt version to use it for LLM generation.

```python main.py {8,9}
from deepeval.tracing import observe
from deepeval.prompt import Prompt
from openai import OpenAI

@observe(type="llm", model="gpt-4.1")
def your_llm_component():
prompt = Prompt(alias="YOUR-PROMPT-ALIAS")
prompt.pull()
interpolated_prompt = prompt.interpolate(name="Joe")
response = OpenAI().chat.completions.create(model="gpt-4o-mini", messages=interpolated_prompt)
return response.choices[0].message.content
```

</Step>

<Step title="Execute your function">

Then simply provide the prompt to the `update_llm_span` function.

```python main.py {11}
from deepeval.tracing import observe, update_llm_span
from deepeval.prompt import Prompt
from openai import OpenAI

@observe(type="llm", model="gpt-4.1")
def your_llm_component():
prompt = Prompt(alias="YOUR-PROMPT-ALIAS")
prompt.pull()
interpolated_prompt = prompt.interpolate(name="Joe")
response = OpenAI().chat.completions.create(model="gpt-4o-mini", messages=interpolated_prompt)
update_llm_span(prompt=prompt)
return response.choices[0].message.content
```

<Info>
Remember to pull the prompt before updating the span, otherwise the prompt
will not be logged.
</Info>

This will automatically attribute the prompt used to the LLM span.

</Step>

</Steps>
45 changes: 25 additions & 20 deletions fern/docs/pages/llm-tracing/advanced-features/attributes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ slug: llm-tracing/advanced-features/attributes
Attributes are like [`metadata`](/docs/llm-tracing/advanced-features/metadata) but specific to different span `type`s.

<Tip>
Setting attributes will make the tracing UI easier to navigate on Confident AI, but is by no means required. You also cannot set attributes for custom [span types](/docs/llm-tracing/advanced-features/span-types).
Setting attributes will make the tracing UI easier to navigate on Confident
AI, but is by no means required. You also cannot set attributes for custom
[span types](/docs/llm-tracing/advanced-features/span-types).
</Tip>

## Set Attributes At Runtime

Attributes are set at runtime using update functions specific to each span type:

<Tabs>
<Tab title="Python" language="python">
- `update_llm_span`
- `update_retriever_span`
</Tab>
<Tab title="TypeScript" language="typescript">
- `updateLlmSpan`
- `updateRetrieverSpan`
</Tab>
<Tab title="Python" language="python">
- `update_llm_span` - `update_retriever_span`
</Tab>
<Tab title="TypeScript" language="typescript">
- `updateLlmSpan` - `updateRetrieverSpan`
</Tab>
</Tabs>

These functions update the attributes for the **CURRENT** span of the component to which the `@observe` decorator is applied. For example, `update_retriever_span` will update the attributes for `inner_function`.
Expand Down Expand Up @@ -81,13 +81,16 @@ LLM attributes track the model, prompt, and token usage and costs of language mo

<Tabs>
<Tab title="Python" language="python">
```python title="main.py" {6}
```python title="main.py" {8}
from deepeval.tracing import observe, update_llm_span

@observe(type="llm", model="gpt-4.1")
def generate_response(prompt):
output = "Generated response to: " + prompt
def generate_response(input):
prompt = Prompt(alias="My Prompt")
prompt.pull("00.00.01")
output = "Generated response to: " + input
update_llm_span(
prompt=prompt,
input_token_count=10,
output_token_count=25,
cost_per_input_token=0.01,
Expand All @@ -99,6 +102,7 @@ LLM attributes track the model, prompt, and token usage and costs of language mo
There are **SIX** optional parameters for `update_llm_span`:

- [Optional] `model`: The model used, of type `str`.
- [Optional] `prompt`: The prompt of type `Prompt`, which must be pulled prior to updating the span.
- [Optional] `input_token_count`: The number of tokens of type `float` in the input.
- [Optional] `output_token_count`: The number of tokens of type `float` in the generated response.
- [Optional] `cost_per_input_token`: The cost per input token of type `float`.
Expand Down Expand Up @@ -135,9 +139,9 @@ LLM attributes track the model, prompt, and token usage and costs of language mo

</Tabs>


<Note>
The model and per-token costs can be set in the `@observe` decorator, but will be overridden if set in `update_llm_span`.
The model and per-token costs can be set in the `@observe` decorator, but will
be overridden if set in `update_llm_span`.
</Note>

### Retriever attributes
Expand Down Expand Up @@ -170,17 +174,17 @@ Retriever attributes track the `embedder`, `top_k`, and `chunk_size` in RAG pipe
<Tab title="TypeScript" language="typescript">
```typescript title="index.ts" {5}
import { observe, updateRetrieverSpan } from '@deepeval-ts/tracing';

const retrieveDocuments = (query: string): string[] => {
const fetchedDocuments = ["doc1", "doc2"];
updateRetrieverSpan({
embedder: "text-embedding-ada-002",
chunkSize: 10,
topK: 5
updateRetrieverSpan({
embedder: "text-embedding-ada-002",
chunkSize: 10,
topK: 5
});
return fetchedDocuments;
};

const observeDocuments = observe({ type: "retriever", embedder: "text-embedding-ada-002", fn: retrieveDocuments });
```

Expand All @@ -191,4 +195,5 @@ Retriever attributes track the `embedder`, `top_k`, and `chunk_size` in RAG pipe
- [Optional] `topK`: The number of text chunks retrieved of type `int` from the vector store.

</Tab>

</Tabs>
15 changes: 15 additions & 0 deletions fern/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2124,6 +2124,11 @@ components:
model:
type: string
description: This is the LLM model used in the span.
prompt:
type: object
additionalProperties: false
$ref: "#/components/schemas/PromptApi"
description: This is the prompt object used in the span.
costPerInputToken:
type: number
format: float
Expand All @@ -2141,6 +2146,16 @@ components:
required:
- model

PromptApi:
type: object
properties:
alias:
type: string
description: This is the alias of the prompt.
version:
type: string
description: This is the version of the prompt.

RetrieverSpan:
type: object
properties:
Expand Down
Loading