Langfuse JS/TS SDKs
    Preparing search index...

    Function observe

    • Decorator function that automatically wraps any function with Langfuse observability.

      This higher-order function creates a traced version of your function that automatically handles observation lifecycle, input/output capture, and error tracking. It's perfect for instrumenting existing functions without modifying their internal logic.

      • Zero Code Changes: Wrap existing functions without modifying their implementation
      • Automatic I/O Capture: Optionally captures function arguments and return values
      • Error Tracking: Automatically captures exceptions and sets error status
      • Type Preservation: Maintains original function signature and return types
      • Async Support: Works seamlessly with both sync and async functions
      • Flexible Configuration: Control observation type, naming, and capture behavior
      • Instrumenting business logic functions
      • Wrapping API calls and external service interactions
      • Adding observability to utility functions
      • Creating traced versions of third-party functions
      • Decorating class methods for observability

      Type Parameters

      • T extends (...args: any[]) => any

      Parameters

      • fn: T

        The function to wrap with observability (preserves original signature)

      • options: ObserveOptions = {}

        Configuration for observation behavior and capture settings

      Returns T

      An instrumented version of the function with identical behavior plus tracing

      import { observe } from '@langfuse/tracing';

      // Basic function wrapping with automatic I/O capture
      const processOrder = observe(
      async (orderId: string, items: CartItem[]) => {
      const validation = await validateOrder(orderId, items);
      const payment = await processPayment(validation);
      const shipping = await scheduleShipping(payment);
      return { orderId, status: 'confirmed', trackingId: shipping.id };
      },
      {
      name: 'process-order',
      asType: 'span',
      captureInput: true,
      captureOutput: true
      }
      );

      // LLM function with generation tracking
      const generateSummary = observe(
      async (document: string, maxWords: number = 100) => {
      const response = await openai.chat.completions.create({
      model: 'gpt-4-turbo',
      messages: [
      { role: 'system', content: `Summarize in ${maxWords} words or less` },
      { role: 'user', content: document }
      ],
      max_tokens: maxWords * 2
      });
      return response.choices[0].message.content;
      },
      {
      name: 'document-summarizer',
      asType: 'generation',
      captureInput: true,
      captureOutput: true
      }
      );

      // Database query with automatic error tracking
      const fetchUserProfile = observe(
      async (userId: string) => {
      const user = await db.users.findUnique({ where: { id: userId } });
      if (!user) throw new Error(`User ${userId} not found`);

      const preferences = await db.preferences.findMany({
      where: { userId }
      });

      return { ...user, preferences };
      },
      {
      name: 'fetch-user-profile',
      asType: 'span',
      captureInput: false, // Don't capture sensitive user IDs
      captureOutput: true
      }
      );

      // Vector search with retriever semantics
      const searchDocuments = observe(
      async (query: string, topK: number = 5) => {
      const embedding = await embedText(query);
      const results = await vectorDb.search(embedding, topK);
      return results.map(r => ({
      content: r.metadata.content,
      score: r.score,
      source: r.metadata.source
      }));
      },
      {
      name: 'document-search',
      asType: 'retriever',
      captureInput: true,
      captureOutput: true
      }
      );

      // Quality evaluation function
      const evaluateResponse = observe(
      (response: string, reference: string, metric: string = 'similarity') => {
      let score: number;

      switch (metric) {
      case 'similarity':
      score = calculateCosineSimilarity(response, reference);
      break;
      case 'bleu':
      score = calculateBleuScore(response, reference);
      break;
      default:
      throw new Error(`Unknown metric: ${metric}`);
      }

      return {
      score,
      passed: score > 0.8,
      metric,
      grade: score > 0.9 ? 'excellent' : score > 0.7 ? 'good' : 'needs_improvement'
      };
      },
      {
      name: 'response-evaluator',
      asType: 'evaluator',
      captureInput: true,
      captureOutput: true
      }
      );

      // Content moderation with guardrails
      const moderateContent = observe(
      async (text: string, policies: string[] = ['profanity', 'spam']) => {
      const violations = [];

      for (const policy of policies) {
      const result = await checkPolicy(text, policy);
      if (result.violation) {
      violations.push({ policy, severity: result.severity });
      }
      }

      return {
      allowed: violations.length === 0,
      violations,
      confidence: 0.95
      };
      },
      {
      name: 'content-moderator',
      asType: 'guardrail',
      captureInput: true,
      captureOutput: true
      }
      );

      // AI agent function with tool usage
      const researchAgent = observe(
      async (query: string, maxSources: number = 3) => {
      // Search for relevant documents
      const documents = await searchDocuments(query, maxSources * 2);

      // Filter and rank results
      const topDocs = documents
      .filter(d => d.score > 0.7)
      .slice(0, maxSources);

      // Generate comprehensive answer
      const context = topDocs.map(d => d.content).join('\n\n');
      const answer = await generateSummary(
      `Based on: ${context}\n\nQuestion: ${query}`,
      200
      );

      return {
      answer,
      sources: topDocs.map(d => d.source),
      confidence: Math.min(...topDocs.map(d => d.score))
      };
      },
      {
      name: 'research-agent',
      asType: 'agent',
      captureInput: true,
      captureOutput: true
      }
      );

      // Class method decoration
      class UserService {
      private db: Database;

      // Wrap methods during class construction
      constructor(database: Database) {
      this.db = database;
      this.createUser = observe(this.createUser.bind(this), {
      name: 'create-user',
      asType: 'span',
      captureInput: false, // Sensitive data
      captureOutput: true
      });
      }

      async createUser(userData: UserData) {
      // Implementation automatically traced
      return await this.db.users.create(userData);
      }
      }

      // Chain composition - functions remain composable
      const processDocument = observe(
      async (document: string) => {
      const summary = await generateSummary(document, 150);
      const moderation = await moderateContent(summary);
      const evaluation = evaluateResponse(summary, document, 'similarity');

      return {
      summary: moderation.allowed ? summary : '[Content Filtered]',
      safe: moderation.allowed,
      quality: evaluation.score
      };
      },
      {
      name: 'document-processor',
      asType: 'chain',
      captureInput: true,
      captureOutput: true
      }
      );

      // Usage - functions work exactly as before, just with observability
      const order = await processOrder('ord_123', cartItems);
      const profile = await fetchUserProfile('user_456');
      const research = await researchAgent('What is quantum computing?');
      const processed = await processDocument(documentText);