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

# Instrument with traceAI Helpers

> Future AGI's traceAI library offers convenient abstractions to streamline your manual instrumentation process.

## traceAI OTEL Tracing

Learn how to leverage traceAI OTEL tracing decorators and methods to instrument your functions, chains, agents, and tools with OpenTelemetry.

These utilities complement or replace standard OpenTelemetry instrumentation code, making the process more straightforward and efficient.

## Installation

Ensure you have FI Instrumentation Library installed:

<CodeGroup>
  ```bash Python theme={null}
  pip install fi-instrumentation-otel
  ```

  ```bash JS/TS theme={null}
  npm install @traceai/fi-core
  ```
</CodeGroup>

## Setting Up Tracing

Initialize your tracing environment with the following setup:

<CodeGroup>
  ```python Python theme={null}
  from fi_instrumentation import register, FITracer
  from fi_instrumentation.fi_types import ProjectType

  # Setup OTel via our register function
  trace_provider = register(
      project_type=ProjectType.EXPERIMENT,
      project_name="FUTURE_AGI",
      project_version_name="openai-exp",
  )

  tracer = FITracer(trace_provider.get_tracer(__name__))
  ```

  ```javascript JS/TS theme={null}
  const { trace, context, SpanStatusCode, propagation } = require("@opentelemetry/api");
  const { AsyncLocalStorageContextManager } = require("@opentelemetry/context-async-hooks");
  const { register, ProjectType } = require("@traceai/fi-core");
  const { registerInstrumentations } = require("@opentelemetry/instrumentation");
  const { suppressTracing } = require("@opentelemetry/core");

  context.setGlobalContextManager(new AsyncLocalStorageContextManager());

  const tracerProvider = register({
      projectName: "manual-instrumentation-example",
      projectType: ProjectType.OBSERVE,
      sessionName: "manual-instrumentation-example-session"
  });

  const tracer = tracerProvider.getTracer("manual-instrumentation-example");
  ```
</CodeGroup>

## Using your Tracer

The tracer object provides two main approaches for instrumentation:

### 1. Function Decoration

Use decorators to trace complete functions:

```python Python theme={null}
@tracer.chain
def my_func(input: str) -> str:
    return "output"
```

When using this method, the entire function execution will be visible as a Span in Future AGI. Function parameters and return values automatically populate input and output attributes, while the status is set automatically.

### 2. Code Block Tracing

Utilize context managers to trace specific code segments:

```python Python theme={null}
from opentelemetry.trace.status import Status, StatusCode

with tracer.start_as_current_span(
    "my-span-name",
    fi_span_kind="chain",
) as span:
    span.set_input("input")
    span.set_output("output")
    span.set_status(Status(StatusCode.OK))
```

The code within this clause will be captured as a Span in Future AGI. Here the input, output, and status must be set manually.

This method is particularly useful when you need to monitor specific portions of your code rather than entire functions.

## FI Span Kinds

FI Span Kinds denote the possible types of spans you might capture, and will be rendered different in the Future AGI UI.

The possible values are:

| Span Kind | Use                                                              |
| --------- | ---------------------------------------------------------------- |
| CHAIN     | General logic operations, functions, or code blocks              |
| LLM       | Making LLM calls                                                 |
| TOOL      | Completing tool calls                                            |
| RETRIEVER | Retrieving documents                                             |
| EMBEDDING | Generating embeddings                                            |
| AGENT     | Agent invocations - typically a top level or near top level span |
| RERANKER  | Reranking retrieved context                                      |
| UNKNOWN   | Unknown                                                          |
| GUARDRAIL | Guardrail checks                                                 |
| EVALUATOR | Evaluators                                                       |

## Chains

### Using Context Managers

<CodeGroup>
  ```python Python theme={null}
  from opentelemetry.trace.status import Status, StatusCode

  with tracer.start_as_current_span(
      "my-span-name",
      fi_span_kind="chain",
  ) as span:
      span.set_input("input")
      span.set_output("output")
      span.set_status(Status(StatusCode.OK))
  ```

  ```javascript JS/TS theme={null}
  tracer.startActiveSpan("my-span-name", { attributes: { "fi.span.kind": "chain" } }, (span) => {
      span.setAttribute("input", "input");
      span.setAttribute("output", "output");
      span.setStatus({ code: SpanStatusCode.OK });
      span.end();
  });
  ```
</CodeGroup>

### Using Decorators

```python Python theme={null}
@tracer.chain
def decorated_chain_with_plain_text_output(input: str) -> str:
    return "output"

decorated_chain_with_plain_text_output("input")
```

### Using JSON Output

```python Python theme={null}
@tracer.chain
def decorated_chain_with_json_output(input: str) -> Dict[str, Any]:
    return {"output": "output"}

decorated_chain_with_json_output("input")
```

### Overriding Span Name

```python Python theme={null}
@tracer.chain(name="decorated-chain-with-overriden-name")
def this_name_should_be_overriden(input: str) -> Dict[str, Any]:
    return {"output": "output"}

this_name_should_be_overriden("input")
```

## Agents

### Using Context Managers

<CodeGroup>
  ```python Python theme={null}
  with tracer.start_as_current_span(
      "agent-span-with-plain-text-io",
      fi_span_kind="agent",
  ) as span:
      span.set_input("input")
      span.set_output("output")
      span.set_status(Status(StatusCode.OK))
  ```

  ```javascript JS/TS theme={null}
  tracer.startActiveSpan("agent-span-with-plain-text-io", { attributes: { "fi.span.kind": "agent" } }, (span) => {
      span.setAttribute("input", "input");
      span.setAttribute("output", "output");
      span.setStatus({ code: SpanStatusCode.OK });
      span.end();
  });
  ```
</CodeGroup>

### Using Decorators

```python Python theme={null}
@tracer.agent
def decorated_agent(input: str) -> str:
    return "output"

decorated_agent("input")
```

## Tools

### Using Context Managers

<CodeGroup>
  ```python Python theme={null}
  with tracer.start_as_current_span(
      "tool-span",
      fi_span_kind="tool",
  ) as span:
      span.set_input("input")
      span.set_output("output")
      span.set_tool(
          name="tool-name",
          description="tool-description",
          parameters={"input": "input"},
      )
      span.set_status(Status(StatusCode.OK))
  ```

  ```javascript JS/TS theme={null}
  tracer.startActiveSpan("tool-span", { attributes: { "fi.span.kind": "tool" } }, (span) => {
      span.setAttribute("input", "input");
      span.setAttribute("output", "output");
      span.setAttribute("tool.name", "tool-name");
      span.setAttribute("tool.description", "tool-description");
      span.setAttribute("tool.parameters", JSON.stringify({"input": "input"}));
      span.setStatus({ code: SpanStatusCode.OK });
      span.end();
  });
  ```
</CodeGroup>

### Using Decorators

```python Python theme={null}
@tracer.tool(
    name="tool-name",
    description="tool-description",
    parameters={"input": "input"},
)
def decorated_tool(input: str) -> str:
    return "output"

decorated_tool("input")
```

## LLM

### Using Context Managers

<CodeGroup>
  ```python Python theme={null}
  with tracer.start_as_current_span(
      "llm-span",
      fi_span_kind="llm",
  ) as span:
      span.set_input("input")
      span.set_output("output")
      span.set_status(Status(StatusCode.OK))
  ```

  ```javascript JS/TS theme={null}
  tracer.startActiveSpan("llm-span", { attributes: { "fi.span.kind": "llm" } }, (span) => {
      span.setAttribute("input", "input");
      span.setAttribute("output", "output");
      span.setStatus({ code: SpanStatusCode.OK });
      span.end();
  });
  ```
</CodeGroup>

### Using Decorators

```python Python theme={null}
@tracer.llm
def decorated_llm(input: str) -> str:
    return "output"

decorated_llm("input")
```

## Retriever

### Using Context Managers

<CodeGroup>
  ```python Python theme={null}
  with tracer.start_as_current_span(
      "retriever-span",
      fi_span_kind="retriever",
  ) as span:
      span.set_input("input")
      span.set_output("output")
      span.set_status(Status(StatusCode.OK))
  ```

  ```javascript JS/TS theme={null}
  tracer.startActiveSpan("retriever-span", { attributes: { "fi.span.kind": "retriever" } }, (span) => {
      span.setAttribute("input", "input");
      span.setAttribute("output", "output");
      span.setStatus({ code: SpanStatusCode.OK });
      span.end();
  });
  ```
</CodeGroup>

### Using Decorators

```python Python theme={null}
@tracer.retriever
def decorated_retriever(input: str) -> str:
    return "output"

decorated_retriever("input")
```
