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

> ## Agent Instructions
> To act on Atlan objects, use the Atlan MCP server at https://api.atlan.com/mcp or the atlanai CLI; `atlanai --map json` prints its command map. Run a read-only identity check before any write.
> The docs MCP server at /mcp searches these docs only. It cannot read or change Atlan objects.
> SDK packages: Python `atlanai` (PyPI) and TypeScript `@atlanai/sdk` (npm). Show Python first, then TypeScript.

# Wrap functions with observe

> Trace sync functions, async functions, and generators with observe in atlanai SDK, without restructuring code.

<Badge color="blue">SDK 0.4.0</Badge>

`observe` in atlanai SDK traces a function without restructuring it, and handles sync functions, async functions, and generators. Use it when you want a span per function call with input and output captured automatically. To control the span yourself, use [Create spans for agent run](/tools/sdk/how-tos/tracing).

## Before you begin

Before you start, make sure you have:

* **SDK**: atlanai SDK installed with tracing, as in [Install atlanai SDK](/tools/sdk/how-tos/install).
* **Tracing**: `init` configured and exporting, as in [Trace first agent run](/tools/sdk/tutorials/quickstart).

<Steps>
  <Step title="Wrap function">
    Decorate a function in Python, or wrap it in TypeScript. The span name comes from the function unless you set `name`, and the observation type defaults to `task`.

    <Tabs>
      <Tab title="Python">
        ```python theme={null}
        from atlanai.tracing import observe

        @observe(as_type="tool")
        def search_docs(query: str) -> list[str]:
            return index.search(query)

        @observe  # bare form: as_type is "task", name is the function name
        async def plan(goal: str) -> str:
            ...
        ```
      </Tab>

      <Tab title="TypeScript">
        ```typescript theme={null}
        import { observe } from "@atlanai/sdk/tracing";

        const searchDocs = observe(
          (query: string) => index.search(query),
          { asType: "tool", name: "search_docs" },
        );
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Limit captured payload">
    Input and output are captured by default. Turn either off per function when the payload is large or sensitive.

    <Tabs>
      <Tab title="Python">
        ```python theme={null}
        @observe(as_type="tool", capture_input=False, capture_output=False)
        def lookup_customer(email: str) -> dict:
            ...
        ```
      </Tab>

      <Tab title="TypeScript">
        ```typescript theme={null}
        const lookupCustomer = observe(fetchCustomer, {
          asType: "tool",
          captureInput: false,
          captureOutput: false,
        });
        ```
      </Tab>
    </Tabs>

    For one rule across every span, use `trace_content` instead, as in [Control trace privacy](/tools/sdk/how-tos/privacy).
  </Step>

  <Step title="Verify span">
    Call the function, flush, and open the trace in Agent Registry. Confirm a span named for the function with the expected type, and input and output present unless you turned them off.

    If no trace appears, see [`init()` disables tracing and no traces are exported](/tools/sdk/troubleshooting/install-and-setup-errors#init-disables-tracing-and-no-traces-are-exported).
  </Step>
</Steps>

## Troubleshooting

If traces do not appear, see [Install and setup errors](/tools/sdk/troubleshooting/install-and-setup-errors).

## Next steps

* [Group runs into sessions](/tools/sdk/how-tos/group-runs-by-session): tie spans to a session, user, and tags.

## See also

* [Create spans for agent run](/tools/sdk/how-tos/tracing)
* [Control trace privacy](/tools/sdk/how-tos/privacy)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.