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

# Features

> Documentation for the Goodfire Features API

## Accessing Features

Before using the Features API, you'll need a [model variant](/sdk-reference/variants):

```python theme={null}
variant = Variant("meta-llama/Llama-3.1-8B-Instruct")
```

You can then access features through the client's features interface. For example, to search for features:

<CodeGroup name="Searching for features">
  ```python Search for features theme={null}
  # Search for features related to a concept
  features = client.features.search(
      "angry",
      model=variant,
      top_k=5
  )

  # Print the found features
  print(features)
  ```

  ```output Features theme={null}
  FeatureGroup([
     0: "Descriptions of anger, indignation, and frustration",
     1: "Negative emotional states, particularly anger and frustration",
     2: "Angry declarations that something is a scam or worthless",
     3: "Explicit references to anger and angry emotions",
     4: "Words that build tension or express defiance in confrontational dialogue"
  ])
  ```
</CodeGroup>

Or inspect feature activations in text:

<CodeGroup name="Inspecting feature activations">
  ```python Inspect feature activations theme={null}
  # Analyze how features activate in text
  inspector = client.features.inspect(
      [
          {"role": "user", "content": "What do you think about pirates and whales"},
          {"role": "assistant", "content": "I think pirates are cool and whales are cool"}
      ],
      model=variant
  )

  # Get top activated features
  for activation in inspector.top(k=5):
      print(f"{activation.feature.label}: {activation.activation}")
  ```

  ```output Features activated in text theme={null}
  Text describing experimental or hypothetical configurations and setups: 7
  The assistant should engage with pirate-themed content or roleplay as a pirate: 7
  The assistant deflects personal preference questions by explaining its AI nature then providing objective information: 7
  Detailed personification and attribute description in formal writing: 7
  Offensive or inappropriate content that should be filtered: 6
  ```
</CodeGroup>

The Features API provides methods for working with interpretable features of language models. Features represent learned patterns in model behavior that can be analyzed and modified.

## Methods

### neighbors()

Get the nearest neighbors of a feature or group of features.

**Parameters:**

<ResponseField name="features" type="Feature | FeatureGroup" required>
  Feature or group of features to find neighbors for
</ResponseField>

<ResponseField name="model" type="str | VariantInterface" required>
  Model identifier or variant interface
</ResponseField>

<ResponseField name="top_k" type="int" default={10}>
  Number of neighbors to return
</ResponseField>

**Returns:** `FeatureGroup`

**Example:**

<CodeGroup name="Getting neighbors of a feature">
  ```python Getting neighbors of a feature theme={null}
  # Get neighbors of a feature
  neighbors =  client.features.neighbors(
      feature,
      model="meta-llama/Llama-3.1-8B-Instruct",
      top_k=10
  )

  # Print neighbor labels
  for neighbor in neighbors:
      print(neighbor.label)
  ```
</CodeGroup>

### search()

Search for features based on semantic similarity to a query string.

**Parameters:**

<ResponseField name="query" type="str" required>
  Search string to compare against feature labels
</ResponseField>

<ResponseField name="model" type="str | VariantInterface" required>
  Model identifier or variant interface
</ResponseField>

<ResponseField name="top_k" type="int" default={10}>
  Number of features to return
</ResponseField>

**Returns:** `FeatureGroup` - Collection of matching features

**Example:**

```python Search features theme={null}
# Search for features related to writing style
features = client.features.search(
    "formal writing style",
    model="meta-llama/Llama-3.1-8B-Instruct",
    top_k=10
)

# Print features
for feature in features:
    print(feature.label)
```

### inspect()

Analyzes how features are activated across the input messages.

**Parameters:**

<ResponseField name="messages" type="list[ChatMessage]" required>
  Messages to analyze
</ResponseField>

<ResponseField name="model" type="str | VariantInterface" required>
  Model identifier or variant interface
</ResponseField>

<ResponseField name="features" type="Feature | FeatureGroup | None">
  Optional specific features to analyze. If None, inspects all features.
</ResponseField>

<ResponseField name="aggregate_by" type="str" default="frequency">
  Method to aggregate feature activations across tokens: - "frequency": Count of
  tokens where feature is active - "mean": Mean activation value across tokens -
  "max": Maximum activation value across tokens - "sum": Sum of activation
  values across tokens
</ResponseField>

**Returns:** `ContextInspector` - An inspector object that provides methods for analyzing and visualizing how features are activated in the given context.

**Example:**

```python Inspect feature activations theme={null}
# Analyze how features activate in text
inspector = client.features.inspect(
    [
        {"role": "user", "content": "What do you think about pirates and whales"},
        {"role": "assistant", "content": "I think pirates are cool and whales are cool"}
    ],
    model=variant
)

# Get top activated features
for activation in inspector.top(k=5):
    print(f"{activation.feature.label}: {activation.activation}")
```

### contrast()

Identify features that differentiate between two conversation datasets.

**Parameters:**

<ResponseField name="dataset_1" type="list[list[ChatMessage]]" required>
  First dataset of conversations
</ResponseField>

<ResponseField name="dataset_2" type="list[list[ChatMessage]]" required>
  Second dataset of conversations
</ResponseField>

<ResponseField name="model" type="str | VariantInterface" required>
  Model identifier or variant interface
</ResponseField>

<ResponseField name="top_k" type="int" default={5}>
  Number of top features to return for each dataset
</ResponseField>

**Returns:** `tuple[FeatureGroup, FeatureGroup]` - Two FeatureGroups containing:

* Features steering towards dataset\_1
* Features steering towards dataset\_2

**Example:**

```python Get constrast features theme={null}
# Compare formal vs informal conversations
dataset_1 = [[
    {"role": "user", "content": "Hi how are you?"},
    {"role": "assistant", "content": "I'm doing well..."}
]]
dataset_2 = [[
    {"role": "user", "content": "Hi how are you?"},
    {"role": "assistant", "content": "Arr my spirits be high..."}
]]

formal_features, informal_features =  client.features.contrast(
    dataset_1=dataset_1,
    dataset_2=dataset_2,
    model="meta-llama/Llama-3.1-8B-Instruct",
    top_k=5
)
```

### rerank()

Rerank a set of features based on a query.

**Parameters:**

<ResponseField name="features" type="FeatureGroup" required>
  Features to rerank
</ResponseField>

<ResponseField name="query" type="str" required>
  Query to rerank features by
</ResponseField>

<ResponseField name="model" type="str | VariantInterface" required>
  Model identifier or variant interface
</ResponseField>

<ResponseField name="top_k" type="int" default={10}>
  Number of top features to return
</ResponseField>

**Returns:** `FeatureGroup`

**Example:**

```python Rerank theme={null}
# Rerank features based on relevance to "writing style"
reranked = client.features.rerank(
    features=formal_features,
    query="writing style",
    model="meta-llama/Llama-3.1-8B-Instruct",
    top_k=10
)
```

### activations()

Retrieves feature activation values for each token in the input messages.

**Parameters:**

<ResponseField name="messages" type="list[ChatMessage]" required>
  Messages to analyze
</ResponseField>

<ResponseField name="model" type="str | VariantInterface" required>
  Model identifier or variant interface
</ResponseField>

<ResponseField name="features" type="Feature | FeatureGroup | None">
  Optional specific features to analyze. If None, analyzes all features.
</ResponseField>

**Returns:** `NDArray[np.float64]` - Sparse activation matrix of shape \[n\_tokens, n\_features] where each element represents the activation strength of a feature at a specific token. Most values are zero due to sparsity.

**Example:**

```python Get activation matrix theme={null}
# Get activation matrix for a conversation
matrix =  client.features.activations(
    messages=[{"role": "user", "content": "Hello world"}],
    model="meta-llama/Llama-3.1-8B-Instruct"
)
```

### lookup()

Retrieves details for a list of features by their indices.

**Parameters:**

<ResponseField name="indices" type="list[int]" required>
  List of feature indices to fetch
</ResponseField>

<ResponseField name="model" type="str | VariantInterface" required>
  Model identifier or variant interface
</ResponseField>

**Returns:** `dict[int, Feature]` - Mapping of feature index to Feature object

### list()

Retrieves details for a list of features by their UUIDs.

**Parameters:**

<ResponseField name="ids" type="list[str]" required>
  List of feature UUIDs to fetch
</ResponseField>

**Returns:** `FeatureGroup` - Collection of Feature objects

## Classes

### Feature

A class representing a human-interpretable "feature" - a model's conceptual neural unit. Features can be combined into groups and compared using standard operators.

<Expandable title="Properties">
  <ParamField body="uuid" type="UUID">
    Unique identifier for the feature
  </ParamField>

  <ParamField body="label" type="str">
    Human-readable label describing the feature
  </ParamField>

  <ParamField body="max_activation_strength" type="float">
    Maximum activation strength of the feature in the training dataset
  </ParamField>

  <ParamField body="index_in_sae" type="int">
    Feature index relative to all features in a given model
  </ParamField>

  <ParamField body="Methods">
    * `json()`: Convert feature to JSON format
    * `from_json(data)`: Create feature from JSON data
    * Supports comparison operators (`==`, `!=`, `<=`, `<`, `>=`, `>`)
  </ParamField>
</Expandable>

### FeatureGroup

A collection of Feature instances with group operations.

<Expandable title="Properties">
  <ParamField body="Methods">
    * `add(feature)`: Add a feature to the group - `pop(index)`: Remove and
      return feature at specified index - `union(feature_group)`: Combine this
      group with another feature group - `intersection(feature_group)`: Create new
      group with features common to both groups - Supports indexing and slicing
      operations
  </ParamField>
</Expandable>

### ConditionalGroup

Groups multiple conditions with logical operators.

<Expandable title="Properties">
  <ParamField body="conditionals" type="list[Conditional]">
    List of Conditional instances to group
  </ParamField>

  <ParamField body="operator" type="str">
    Logical operator to join conditions ("AND" or "OR")
  </ParamField>

  <ParamField body="Methods">
    * Supports logical operations (`&` for AND, `|` for OR)
    * `json()`: Convert to JSON format
    * `from_json()`: Create from JSON data
  </ParamField>
</Expandable>

### FeatureActivation

Represents the activation of a feature.

<Expandable title="Properties">
  <ParamField body="feature" type="Feature">
    The activated feature
  </ParamField>

  <ParamField body="activation" type="float">
    Activation strength
  </ParamField>
</Expandable>

### ContextInspector

Analyzes feature activations in text.

<Expandable title="Properties">
  <ParamField body="Methods">
    * `top(k)`: Get top activated features
  </ParamField>

  <ParamField body="Example">
    ```python theme={null}
    # Get top 5 activated features
    top_features = inspector.top(k=5)
    ```
  </ParamField>
</Expandable>
