Skip to main content

Agent Attribution & Tracing

PraisonAI provides built-in attribution and tracing support for multi-agent systems. This enables tracking which agent made which request, debugging complex workflows, and monitoring agent behavior.

Quick Start

import { Agent } from 'praisonai';

const agent = new Agent({
  instructions: 'You are a helpful assistant',
  llm: 'openai/gpt-4o-mini',
  name: 'helper-agent'  // Agent ID for attribution
});

// Attribution headers are automatically injected
const response = await agent.chat('Hello');

// Access attribution info
console.log('Agent:', agent.name);
console.log('Session:', agent.getSessionId());
console.log('Run:', agent.getRunId());

Attribution Headers

When using AI SDK backend, PraisonAI automatically injects attribution headers:
HeaderDescription
X-Agent-IdUnique identifier for the agent
X-Run-IdUnique identifier for the current run
X-Session-IdSession identifier for conversation continuity
X-Trace-IdTrace identifier for distributed tracing
X-Parent-Span-IdParent span for nested operations

Backend Resolution with Attribution

import { resolveBackend } from 'praisonai';

const { provider, source } = await resolveBackend('openai/gpt-4o-mini', {
  attribution: {
    agentId: 'my-agent',
    runId: 'run-123',
    sessionId: 'session-456',
    traceId: 'trace-789'
  }
});

// All requests through this provider include attribution headers
const result = await provider.generateText({
  messages: [{ role: 'user', content: 'Hello' }]
});

Multi-Agent Attribution

Each agent in a multi-agent system gets unique attribution:
import { Agent, Agents } from 'praisonai';

const researcher = new Agent({
  name: 'researcher',
  instructions: 'Research the topic'
});

const writer = new Agent({
  name: 'writer',
  instructions: 'Write based on research'
});

const agents = new Agents([researcher, writer]);

// Each agent's requests have different X-Agent-Id headers
await agents.start();

// Verify attribution
console.log('Researcher ID:', researcher.name);
console.log('Writer ID:', writer.name);
console.log('Researcher Session:', researcher.getSessionId());
console.log('Writer Session:', writer.getSessionId());

Parallel Agent Isolation

Attribution ensures parallel agents don’t interfere:
import { Agent, Agents } from 'praisonai';

const agent1 = new Agent({ name: 'agent-1', instructions: 'Task 1' });
const agent2 = new Agent({ name: 'agent-2', instructions: 'Task 2' });
const agent3 = new Agent({ name: 'agent-3', instructions: 'Task 3' });

const agents = new Agents({
  agents: [agent1, agent2, agent3],
  process: 'parallel'
});

// All three agents run in parallel with isolated attribution
const results = await agents.start();

// Each has unique run IDs
console.log('Agent 1 Run:', agent1.getRunId());
console.log('Agent 2 Run:', agent2.getRunId());
console.log('Agent 3 Run:', agent3.getRunId());

Custom Attribution Context

Provide custom attribution for advanced use cases:
import { Agent } from 'praisonai';

const agent = new Agent({
  instructions: 'You are helpful',
  llm: 'openai/gpt-4o-mini',
  name: 'custom-agent',
  sessionId: 'my-custom-session',
  runId: 'my-custom-run'
});

// Custom IDs are used in attribution headers
const response = await agent.chat('Hello');

Tracing Integration

OpenTelemetry Integration

import { Agent } from 'praisonai';
import { trace } from '@opentelemetry/api';

const tracer = trace.getTracer('my-app');

await tracer.startActiveSpan('agent-operation', async (span) => {
  const agent = new Agent({
    instructions: 'You are helpful',
    llm: 'openai/gpt-4o-mini',
    telemetry: true  // Enable telemetry
  });
  
  try {
    const response = await agent.chat('Hello');
    span.setStatus({ code: 0 });
  } catch (error) {
    span.setStatus({ code: 2, message: error.message });
    throw error;
  } finally {
    span.end();
  }
});

Custom Telemetry

import { resolveBackend } from 'praisonai';

const { provider } = await resolveBackend('openai/gpt-4o-mini', {
  telemetry: {
    isEnabled: true,
    functionId: 'my-function',
    metadata: {
      environment: 'production',
      version: '1.0.0'
    }
  }
});

Debugging with Attribution

Use attribution to debug multi-agent issues:
import { Agent, Agents } from 'praisonai';

const agents = new Agents([
  new Agent({ name: 'analyzer', instructions: 'Analyze data' }),
  new Agent({ name: 'processor', instructions: 'Process results' }),
  new Agent({ name: 'reporter', instructions: 'Generate report' })
]);

// Enable verbose logging to see attribution
process.env.PRAISON_VERBOSE = 'true';

await agents.start();

// Logs will show which agent made each request:
// [analyzer] Sending request with X-Agent-Id: analyzer, X-Run-Id: ...
// [processor] Sending request with X-Agent-Id: processor, X-Run-Id: ...
// [reporter] Sending request with X-Agent-Id: reporter, X-Run-Id: ...

Attribution in Workflows

import { Workflow, Agent } from 'praisonai';

const workflow = new Workflow({
  name: 'data-pipeline',
  steps: [
    {
      name: 'extract',
      agent: new Agent({ name: 'extractor', instructions: 'Extract data' })
    },
    {
      name: 'transform',
      agent: new Agent({ name: 'transformer', instructions: 'Transform data' })
    },
    {
      name: 'load',
      agent: new Agent({ name: 'loader', instructions: 'Load data' })
    }
  ]
});

// Each step has isolated attribution
const result = await workflow.run();

Accessing Attribution Data

const agent = new Agent({
  name: 'my-agent',
  instructions: 'You are helpful'
});

// Get attribution identifiers
const agentId = agent.name;
const sessionId = agent.getSessionId();
const runId = agent.getRunId();

// Get backend source
const backendSource = agent.getBackendSource();

console.log({
  agentId,
  sessionId,
  runId,
  backendSource
});

Best Practices

  1. Use meaningful agent names: Names appear in attribution headers
  2. Preserve session IDs: Reuse session IDs for conversation continuity
  3. Log run IDs: Store run IDs for debugging and auditing
  4. Enable telemetry in production: Track performance and errors
  5. Use trace IDs: Connect related operations across services

TypeScript Types

import type { AttributionContext } from 'praisonai';

const attribution: AttributionContext = {
  agentId: 'my-agent',
  runId: 'run-123',
  sessionId: 'session-456',
  traceId: 'trace-789',
  parentSpanId: 'span-abc'
};