Skip to main content

Calls

Calls

Calls are the fundamental building block in Weave. They represent a single execution of a function, including:

  • Inputs (arguments)
  • Outputs (return value)
  • Metadata (duration, exceptions, LLM usage, etc.)

Calls are similar to spans in the OpenTelemetry data model. A Call can:

  • Belong to a Trace (a collection of calls in the same execution context)
  • Have parent and child Calls, forming a tree structure

Creating Calls

There are three main ways to create Calls in Weave:

1. Automatic Tracking of LLM Libraries

Weave automatically tracks calls to common LLM libraries like openai, anthropic, cohere, and mistral. Simply call weave.init('project_name') at the start of your program:

import weave

from openai import OpenAI
client = OpenAI()

# Initialize Weave Tracing
weave.init('intro-example')

response = client.chat.completions.create(
model="gpt-4",
messages=[
{
"role": "user",
"content": "How are you?"
}
],
temperature=0.8,
max_tokens=64,
top_p=1,
)

2. Decorating/Wrapping Functions

However, often LLM applications have additional logic (such as pre/post processing, prompts, etc.) that you want to track.

Weave allows you to manually track these calls using the @weave.op decorator. For example:

import weave

# Initialize Weave Tracing
weave.init('intro-example')

# Decorate your function
@weave.op
def my_function(name: str):
return f"Hello, {name}!"

# Call your function -- Weave will automatically track inputs and outputs
print(my_function("World"))

This works for both functions as well as methods on classes:

import weave

# Initialize Weave Tracing
weave.init("intro-example")

class MyClass:
# Decorate your method
@weave.op
def my_method(self, name: str):
return f"Hello, {name}!"

instance = MyClass()

# Call your method -- Weave will automatically track inputs and outputs
print(instance.my_method("World"))

Getting a handle to the Call object during execution

Sometimes it is useful to get a handle to the Call object itself. You can do this by calling the op.call method, which returns both the result and the Call object. For example:

result, call = my_function.call("World")

Then, call can be used to set / update / fetch additional properties (most commonly used to get the ID of the call to be used for feedback).

note

If your op is a method on a class, you need to pass the instance as the first argument to the op (see example below).

# Notice that we pass the `instance` as the first argument.
print(instance.my_method.call(instance, "World"))
import weave

# Initialize Weave Tracing
weave.init("intro-example")

class MyClass:
# Decorate your method
@weave.op
def my_method(self, name: str):
return f"Hello, {name}!"

instance = MyClass()

# Call your method -- Weave will automatically track inputs and outputs
instance.my_method.call(instance, "World")

Call Display Name

Sometimes you may want to override the display name of a call. You can achieve this in one of four ways:

  1. Change the display name at the time of calling the op:
result = my_function("World", __weave={"display_name": "My Custom Display Name"})
note

Using the __weave dictionary sets the call display name which will take precedence over the Op display name.

  1. Change the display name on a per-call basis. This uses the Op.call method to return a Call object, which you can then use to set the display name using Call.set_display_name.
result, call = my_function.call("World")
call.set_display_name("My Custom Display Name")
  1. Change the display name for all Calls of a given Op:
@weave.op(call_display_name="My Custom Display Name")
def my_function(name: str):
return f"Hello, {name}!"
  1. The call_display_name can also be a function that takes in a Call object and returns a string. The Call object will be passed automatically when the function is called, so you can use it to dynamically generate names based on the function's name, call inputs, attributes, etc.

  2. One common use case is just appending a timestamp to the function's name.

    from datetime import datetime

    @weave.op(call_display_name=lambda call: f"{call.func_name}__{datetime.now()}")
    def func():
    return ...
  3. You can also get creative with custom attributes

    def custom_attribute_name(call):
    model = call.attributes["model"]
    revision = call.attributes["revision"]
    now = call.attributes["date"]

    return f"{model}__{revision}__{now}"

    @weave.op(call_display_name=custom_attribute_name)
    def func():
    return ...

    with weave.attributes(
    {
    "model": "finetuned-llama-3.1-8b",
    "revision": "v0.1.2",
    "date": "2024-08-01",
    }
    ):
    func() # the display name will be "finetuned-llama-3.1-8b__v0.1.2__2024-08-01"


    with weave.attributes(
    {
    "model": "finetuned-gpt-4o",
    "revision": "v0.1.3",
    "date": "2024-08-02",
    }
    ):
    func() # the display name will be "finetuned-gpt-4o__v0.1.3__2024-08-02"

Technical Note: "Calls" are produced by "Ops". An Op is a function or method that is decorated with @weave.op. By default, the Op's name is the function name, and the associated calls will have the same display name. The above example shows how to override the display name for all Calls of a given Op. Sometimes, users wish to override the name of the Op itself. This can be achieved in one of two ways:

  1. Set the name property of the Op before any calls are logged
my_function.name = "My Custom Op Name"
  1. Set the name option on the op decorator
@weave.op(name="My Custom Op Name)

Attributes

When calling tracked functions, you can add additional metadata to the call by using the weave.attributes context manager. In the example below, we add an env attribute to the call specified as 'production'.

# ... continued from above ...

# Add additional "attributes" to the call
with weave.attributes({'env': 'production'}):
print(my_function.call("World"))

3. Manual Call Tracking

You can also manually create Calls using the API directly.

import weave

# Initialize Weave Tracing
weave.init('intro-example')

def my_function(name: str):
# Start a call
call = weave.create_call(op="my_function", inputs={"name": name})

# ... your function code ...

# End a call
weave.finish_call(call, output="Hello, World!")

# Call your function
print(my_function("World"))

Viewing Calls

To view a call in the web app:

  1. Navigate to your project's "Traces" tab
  2. Find the call you want to view in the list
  3. Click on the call to open its details page

The details page will show the call's inputs, outputs, runtime, and any additional attributes or metadata.

View Call in Web App

Updating Calls

Calls are mostly immutable once created, however, there are a few mutations which are supported:

All of these mutations can be performed from the UI by navigating to the call detail page:

Update Call in Web App

Set Display Name

In order to set the display name of a call, you can use the Call.set_display_name method.

import weave

# Initialize the client
client = weave.init("your-project-name")

# Get a specific call by its ID
call = client.get_call("call-uuid-here")

# Set the display name of the call
call.set_display_name("My Custom Display Name")

Add Feedback

Please see the Feedback Documentation for more details.

Delete a Call

To delete a call using the Python API, you can use the Call.delete method.

import weave

# Initialize the client
client = weave.init("your-project-name")

# Get a specific call by its ID
call = client.get_call("call-uuid-here")

# Delete the call
call.delete()

Querying & Exporting Calls

The /calls page of your project ("Traces" tab) contains a table view of all the Calls in your project. From there, you can:

  • Sort
  • Filter
  • Export

Calls Table View

The Export Modal (shown above) allows you to export your data in a number of formats, as well as shows the Python & CURL equivalents for the selected calls! The easiest way to get started is to construct a view in the UI, then learn more about the export API via the generated code snippets.

To fetch calls using the Python API, you can use the client.calls method:

import weave

# Initialize the client
client = weave.init("your-project-name")

# Fetch calls
calls = client.get_calls(filter=...)
Notice: Evolving APIs

Currently, it is easier to use the lower-level calls_query_stream API as it is more flexible and powerful. In the near future, we will move all functionality to the above client API.

import weave

# Initialize the client
client = weave.init("your-project-name")

calls = client.server.calls_query_stream({
"project_id": "",
"filter": {},
"query": {},
"sort_by": [],
})

Call FAQ

Call Schema

Please see the schema for a complete list of fields.

PropertyTypeDescription
idstring (uuid)Unique identifier for the call
project_idstring (optional)Associated project identifier
op_namestringName of the operation (can be a reference)
display_namestring (optional)User-friendly name for the call
trace_idstring (uuid)Identifier for the trace this call belongs to
parent_idstring (uuid)Identifier of the parent call
started_atdatetimeTimestamp when the call started
attributesDict[str, Any]User-defined metadata about the call
inputsDict[str, Any]Input parameters for the call
ended_atdatetime (optional)Timestamp when the call ended
exceptionstring (optional)Error message if the call failed
outputAny (optional)Result of the call
summaryOptional[SummaryMap]Post-execution summary information
wb_user_idOptional[str]Associated Weights & Biases user ID
wb_run_idOptional[str]Associated Weights & Biases run ID
deleted_atdatetime (optional)Timestamp of call deletion, if applicable

The table above outlines the key properties of a Call in Weave. Each property plays a crucial role in tracking and managing function calls:

  • The id, trace_id, and parent_id fields help in organizing and relating calls within the system.
  • Timing information (started_at, ended_at) allows for performance analysis.
  • The attributes and inputs fields provide context for the call, while output and summary capture the results.
  • Integration with Weights & Biases is facilitated through wb_user_id and wb_run_id.

This comprehensive set of properties enables detailed tracking and analysis of function calls throughout your project.

Calculated Fields:

  • Cost
  • Duration
  • Status