Automatically track function calls using Ops ↗
noSummary: Versioned functions that automatically log all calls in Weave
Original Documentation
Documentation Index#
Fetch the complete documentation index at: https://docs.wandb.ai/llms.txt Use this file to discover all available pages before exploring further.
Versioned functions that automatically log all calls in Weave
A Weave op is a versioned function that automatically logs all calls.
To create an op, decorate a python function with weave.op()
import weave
@weave.op()
def track_me(v):
return v + 5
weave.init('intro-example')
track_me(15)
```
Calling an op creates a new op version if the code has changed from the last call, and log the inputs and outputs of the function.
Functions decorated with `@weave.op()` will behave normally (without code versioning and tracking), if you don't call `weave.init('your-project-name')` before calling them.
Ops can be [served](/weave/guides/tools/serve) or [deployed](/weave/guides/tools/deploy) using the Weave toolbelt.
<span class="tab-end"></span>
<span class="tab-start" data-tab-title="TypeScript"></span>
To create an op, wrap a typescript function with `weave.op`
```typescript
import * as weave from 'weave'
function trackMe(v: number) {
return v + 5
}
const trackMeOp = weave.op(trackMe)
trackMeOp(15)
// You can also do this inline, which may be more convenient
const trackMeInline = weave.op((v: number) => v + 5)
trackMeInline(15)
```
<span class="tab-end"></span>
<span class="tab-group-end"></span>
## Customize display names
<span class="tab-group-start"></span>
<span class="tab-start" data-tab-title="Python"></span>
You can customize the op's display name by setting the `name` parameter in the `@weave.op` decorator:
```python
@weave.op(name="custom_name")
def func():
...
```
<span class="tab-end"></span>
<span class="tab-start" data-tab-title="TypeScript"></span>
```plaintext
This feature is not available in TypeScript yet.
```
<span class="tab-end"></span>
<span class="tab-group-end"></span>
## Apply kinds and colors
To better organize your ops in the Weave UI, you can apply custom kinds and colors to them by adding the `kind` and `color` arguments to the `@weave.op` decorators in your code. For example, the following code applies an `LLM` `kind` and a `blue` `color` to the parent function, and a `tool` `kind` and a `red` `color` to a nested function:
<span class="tab-group-start"></span>
<span class="tab-start" data-tab-title="Python"></span>
```python
import weave
weave.init("<your-team-name>/<your-project-name>")
@weave.op(kind="LLM", color="blue")
def llm_func():
@weave.op(kind="tool", color="red")
def tool_func():
return "tool result"
tool_result = tool_func()
return f"llm result with {tool_result}"
llm_func()
```
<span class="tab-end"></span>
<span class="tab-start" data-tab-title="TypeScript"></span>
```plaintext
This feature is not available in TypeScript yet.
```
<span class="tab-end"></span>
<span class="tab-group-end"></span>
This applies the colors and kinds to your ops in the Weave UI, like this:
<img src="https://mintcdn.com/wb-21fd5541/mYTjDOL9RmCf9f6G/images/weave/weave_colors_kinds.png?fit=max&auto=format&n=mYTjDOL9RmCf9f6G&q=85&s=1da0fd3625dbba102fa17c7d3b6c4f03" alt="The Weave UI, showing a parent call with a LLM kind and a blue color, and a nested call with a tool kind and a red color." data-og-width="1288" width="1288" data-og-height="605" height="605" data-path="images/weave/weave_colors_kinds.png" data-optimize="true" data-opv="3" srcset="https://mintcdn.com/wb-21fd5541/mYTjDOL9RmCf9f6G/images/weave/weave_colors_kinds.png?w=280&fit=max&auto=format&n=mYTjDOL9RmCf9f6G&q=85&s=cbd7981635c747d529f85ba4e14d2e12 280w, https://mintcdn.com/wb-21fd5541/mYTjDOL9RmCf9f6G/images/weave/weave_colors_kinds.png?w=560&fit=max&auto=format&n=mYTjDOL9RmCf9f6G&q=85&s=da3653525bc10cabce5273c9e3d24f30 560w, https://mintcdn.com/wb-21fd5541/mYTjDOL9RmCf9f6G/images/weave/weave_colors_kinds.png?w=840&fit=max&auto=format&n=mYTjDOL9RmCf9f6G&q=85&s=1b7b6dd252875417a688a7ca73fb33cb 840w, https://mintcdn.com/wb-21fd5541/mYTjDOL9RmCf9f6G/images/weave/weave_colors_kinds.png?w=1100&fit=max&auto=format&n=mYTjDOL9RmCf9f6G&q=85&s=5145011c8c09d49b3414b0f058139d24 1100w, https://mintcdn.com/wb-21fd5541/mYTjDOL9RmCf9f6G/images/weave/weave_colors_kinds.png?w=1650&fit=max&auto=format&n=mYTjDOL9RmCf9f6G&q=85&s=418cb924970da72f9bbb2559592ec717 1650w, https://mintcdn.com/wb-21fd5541/mYTjDOL9RmCf9f6G/images/weave/weave_colors_kinds.png?w=2500&fit=max&auto=format&n=mYTjDOL9RmCf9f6G&q=85&s=26ad2728f0557b648569d00ed0f27767 2500w" />
The available `kind` values are:
* `agent`
* `llm`
* `tool`
* `search`
The available `color` values are:
* `red`
* `orange`
* `yellow`
* `green`
* `blue`
* `purple`
## Customize logged inputs and outputs
<span class="tab-group-start"></span>
<span class="tab-start" data-tab-title="Python"></span>
If you want to change the data that is logged to weave without modifying the original function (e.g. to hide sensitive data), you can pass `postprocess_inputs` and `postprocess_output` to the op decorator.
`postprocess_inputs` takes in a dict where the keys are the argument names and the values are the argument values, and returns a dict with the transformed inputs.
`postprocess_output` takes in any value which would normally be returned by the function and returns the transformed output.
```python
from dataclasses import dataclass
from typing import Any
import weave
@dataclass
class CustomObject:
x: int
secret_password: str
def postprocess_inputs(inputs: dict[str, Any]) -> dict[str, Any]:
return {k:v for k,v in inputs.items() if k != "hide_me"}
def postprocess_output(output: CustomObject) -> CustomObject:
return CustomObject(x=output.x, secret_password="REDACTED")
@weave.op(
postprocess_inputs=postprocess_inputs,
postprocess_output=postprocess_output,
)
def func(a: int, hide_me: str) -> CustomObject:
return CustomObject(x=a, secret_password=hide_me)
weave.init('hide-data-example') # 🐝
func(a=1, hide_me="password123")
```
<span class="tab-end"></span>
<span class="tab-start" data-tab-title="TypeScript"></span>
```plaintext
This feature is not available in TypeScript yet.
```
<span class="tab-end"></span>
<span class="tab-group-end"></span>
## Control sampling rate
<span class="tab-group-start"></span>
<span class="tab-start" data-tab-title="Python"></span>
You can control how frequently an op's calls are traced by setting the `tracing_sample_rate` parameter in the `@weave.op` decorator. This is useful for high-frequency ops where you only need to trace a subset of calls.
Note that sampling rates are only applied to root calls. If an op has a sample rate, but is called by another op first, then that sampling rate will be ignored.
```python
@weave.op(tracing_sample_rate=0.1) # Only trace ~10% of calls
def high_frequency_op(x: int) -> int:
return x + 1
@weave.op(tracing_sample_rate=1.0) # Always trace (default)
def always_traced_op(x: int) -> int:
return x + 1
```
When an op's call is not sampled:
* The function executes normally
* No trace data is sent to Weave
* Child ops are also not traced for that call
The sampling rate must be between 0.0 and 1.0 inclusive.
<span class="tab-end"></span>
<span class="tab-start" data-tab-title="TypeScript"></span>
```plaintext
This feature is not available in TypeScript yet.
```
<span class="tab-end"></span>
<span class="tab-group-end"></span>
## Control call link output
If you want to suppress the printing of call links during logging, you can set the `WEAVE_PRINT_CALL_LINK` environment variable to `false`. This can be useful if you want to reduce output verbosity and reduce clutter in your logs.
```bash
export WEAVE_PRINT_CALL_LINK=falseDeleting an op#
To delete a version of an op, call .delete() on the op ref.
weave.init('intro-example')
my_op_ref = weave.ref('track_me:v1')
my_op_ref.delete()
```
Trying to access a deleted op will result in an error.
<span class="tab-end"></span>
<span class="tab-start" data-tab-title="TypeScript"></span>
```plaintext
This feature is not available in TypeScript yet.
```
<span class="tab-end"></span>
<span class="tab-group-end"></span>Link last verified
June 7, 2026.
View original ↗
Source: Weights & Biases Docs
Link last verified: 2026-03-04