> ## Documentation Index
> Fetch the complete documentation index at: https://docs.seekr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Context attribution

Context attribution identifies which retrieved sources influenced each statement in an agent's response. It traces outputs back to vector database content, web search results, tool outputs, and conversation context.

## Attribute a response from an agent run

Use this method to attribute a response from a completed SeekrFlow agent thread. The SDK automatically extracts the context, query, and response from the thread.

<CodeGroup>
  ```python Python theme={null}
  import os
  from seekrai import SeekrFlow

  client = SeekrFlow(api_key=os.environ["SEEKR_API_KEY"])

  attribution = client.explainability.get_context_attribution_from_run(
      thread_id="<your-thread-id>",
  )
  print(attribution)
  ```
</CodeGroup>

To target a specific run rather than the latest:

<CodeGroup>
  ```python Python theme={null}
  attribution = client.explainability.get_context_attribution_from_run(
      thread_id="<your-thread-id>",
      run_id="<your-run-id>",
      granularity="sentence",
      top_k=5,
  )
  ```
</CodeGroup>

## Parameters

| Parameter       | Type   | Default      | Description                                                                                                                                   |
| --------------- | ------ | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `thread_id`     | string | Required     | ID of the agent thread to analyze.                                                                                                            |
| `run_id`        | string | Latest       | ID of the specific run to analyze. Defaults to the most recent completed run in the thread.                                                   |
| `granularity`   | string | `"sentence"` | How to split context into sources: `"sentence"` or `"chunk"`. Sentence-level is more precise; chunk-level is faster for large contexts.       |
| `top_k`         | int    | `5`          | Number of top sources returned per response segment.                                                                                          |
| `highlight`     | string | —            | A specific portion of the response text to attribute. When set, returns sources for that text only rather than attributing the full response. |
| `num_ablations` | int    | Auto         | Number of ablation experiments to run. Auto-computed based on context size if not set. Must be 32–256 if specified.                           |

## Attribute raw context

Use this method when you have context, query, and response as text strings—for example, when running attribution outside of SeekrFlow agents or in a custom pipeline.

<CodeGroup>
  ```python Python theme={null}
  attribution = client.explainability.get_context_attribution(
      context="France is a country in Western Europe with Paris as its capital. "
              "The Eiffel Tower is a wrought-iron lattice tower in Paris...",
      query="What is the capital of France and what is it known for?",
      response="Paris is the capital of France. It is known for the Eiffel Tower.",
      granularity="sentence",
      top_k=5,
  )
  print(attribution)
  ```
</CodeGroup>

## Parameters

| Parameter       | Type   | Default      | Description                                                                                    |
| --------------- | ------ | ------------ | ---------------------------------------------------------------------------------------------- |
| `context`       | string | Required     | The context text provided to the model.                                                        |
| `query`         | string | Required     | The user's query.                                                                              |
| `response`      | string | Required     | The model's response to attribute.                                                             |
| `granularity`   | string | `"sentence"` | How to split context into sources: `"sentence"` or `"paragraph"`.                              |
| `top_k`         | int    | `5`          | Number of top sources returned per response segment.                                           |
| `highlight`     | string | —            | A specific portion of the response to attribute. When set, returns sources for that text only. |
| `num_ablations` | int    | Auto         | Number of ablation experiments. Auto-computed if not set. Must be 32–256 if specified.         |

## Response structure

Both methods return the same structure:

<CodeGroup>
  ```json JSON expandable theme={null}
  {
    "response_text": "Paris is the capital of France. It is known for the Eiffel Tower.",
    "segments": [
      {
        "segment_index": 0,
        "segment_text": "Paris is the capital of France.",
        "char_offset": 0,
        "sources": [
          {
            "source_type": "tool_response",
            "id": 0,
            "text": "France is a country in Western Europe with Paris as its capital.",
            "attribution": 0.87,
            "offset": 0,
            "tool_name": "file_search",
            "tool_call_id": "call_abc123",
            "tool": {
              "type": "file_search",
              "file_path": "europe_facts.txt",
              "file_id": "file-xyz789",
              "query": "capital of France"
            }
          }
        ]
      },
      {
        "segment_index": 1,
        "segment_text": "It is known for the Eiffel Tower.",
        "char_offset": 31,
        "sources": [
          {
            "source_type": "tool_response",
            "id": 2,
            "text": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris.",
            "attribution": 0.91,
            "offset": 312,
            "tool_name": "web_search",
            "tool_call_id": "call_def456",
            "tool": {
              "type": "web_search",
              "url": "https://en.wikipedia.org/wiki/Eiffel_Tower",
              "title": "Eiffel Tower - Wikipedia",
              "search_query": "Eiffel Tower Paris landmark"
            }
          }
        ]
      }
    ],
    "highlight": null
  }
  ```
</CodeGroup>

### Fields

* **`response_text`** *(string)*: The full response text that was attributed.
* **`segments`** *(list)*: Per-segment attribution results. Populated when `highlight` is not provided. Each item contains:
  * **`segment_index`** *(int)*: 0-based position of the segment in the response.
  * **`segment_text`** *(string)*: The text of this segment.
  * **`char_offset`** *(int)*: Character offset of this segment within `response_text`.
  * **`sources`** *(list)*: Sources attributed to this segment, each with:
    * **`source_type`** *(string)*: Either `"raw"` (plain context text) or `"tool_response"` (output from a tool call).
    * **`id`** *(int)*: Index of this source in the partitioned context.
    * **`text`** *(string)*: The source text content.
    * **`attribution`** *(float)*: Attribution score. See [Attribution scores](#attribution-scores).
    * **`offset`** *(int)*: Character offset of this source in the original context.
    * **`tool_name`**, **`tool_call_id`**, **`tool`** *(tool\_response only)*: The tool name, call ID, and tool-specific metadata. The `tool` object varies by type: `file_search` includes `file_path`, `file_id`, and `query`; `web_search` includes `url`, `title`, and `search_query`; `code_interpreter` includes `code`; `custom` includes `tool_name`.
* **`sources`** *(list)*: Only populated when `highlight` is provided. Contains sources for the highlighted text instead of per-segment results.
* **`highlight`** *(string)*: The highlighted text echoed back, if provided in the request.

### Attribution scores

Each source has an `attribution` value between -1 and 1. Positive values indicate the source supported the response—removing it would have caused the output to change. Values near 0 indicate little influence. Negative values are uncommon and indicate the source may have had a conflicting effect on the output.

### Attribute a specific portion of the response

Pass `highlight` to focus attribution on one sentence or phrase. When `highlight` is set, `segments` is empty and sources are returned in the top-level `sources` field:

<CodeGroup>
  ```python Python theme={null}
  attribution = client.explainability.get_context_attribution_from_run(
      thread_id="<your-thread-id>",
      highlight="It is known for the Eiffel Tower.",
  )

  for source in attribution.sources:
      print(source.attribution, source.text)
  ```
</CodeGroup>

## Common errors

* **400 Bad request** – A required parameter is missing or invalid.
* **404 Not found** – The thread or run ID does not exist.
* **422 Unprocessable entity** – The thread has no assistant response. This occurs if response generation is still in progress or the agent run failed.
* **503 Service unavailable** – The request timed out. Retry, or reduce context size.
* **500 Internal server error** – Unexpected server error. Retry the request.

## Best practices

* **Granularity:** Sentence-level gives the most interpretable results. When context is large and speed matters more than precision, use `"chunk"` with `get_context_attribution_from_run` or `"paragraph"` with `get_context_attribution`.
* **top\_k:** Values of 3–5 work well for most use cases. Increase toward 10 when debugging multi-hop answers where many sources contribute.
* **num\_ablations:** Leave unset in production. Override only when benchmarking or reproducing a specific result.
* **Segments with no strong sources:** This indicates the model generated that content from prior knowledge rather than retrieved context. It is expected behavior, not an error.
