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

# Langfuse Setup

> Step-by-step guide to deploying Langfuse and connecting it to all CRAFT solutions for LLM observability.

# Langfuse Setup Guide

This guide walks through deploying Langfuse and connecting it to your CRAFT solutions. Langfuse provides LLM call tracing, evaluation, and prompt management for Data Insights, Data Governance, and Semiconductor solutions.

## Prerequisites

* A running CRAFT deployment (any version)
* Docker and Docker Compose (for Docker deployment) or a Kubernetes cluster
* Domain name for the Langfuse instance (recommended for production)

## Step 1: Deploy Langfuse

<Tabs>
  <Tab title="Docker Compose">
    ```bash theme={null}
    # Clone the Langfuse repository (provided in your deployment kit)
    git clone <langfuse-repo-url>
    cd langfuse
    cp .env .env.local  # Edit .env.local with your configuration
    ```

    Edit `.env.local` with your configuration:

    ```env theme={null}
    # Required
    NEXTAUTH_URL=https://langfuse.your-domain.com
    NEXTAUTH_SECRET=<run: openssl rand -hex 32>
    SALT=<run: openssl rand -hex 32>

    # Database (auto-provisioned by compose)
    DATABASE_URL=postgresql://postgres:postgres@langfuse-db:5432/langfuse

    # Encryption
    ENCRYPTION_KEY=<run: openssl rand -hex 32>
    ```

    Start the services:

    ```bash theme={null}
    docker compose up -d
    docker compose ps   # verify all services are healthy
    ```

    Langfuse is now available at `http://localhost:3000` (or your configured domain).
  </Tab>

  <Tab title="Kubernetes (Helm)">
    ```bash theme={null}
    helm repo add langfuse https://langfuse.github.io/langfuse-k8s
    helm repo update

    # Create secrets
    kubectl create secret generic langfuse-secrets \
      --namespace langfuse \
      --from-literal=nextauth-secret=$(openssl rand -hex 32) \
      --from-literal=salt=$(openssl rand -hex 32) \
      --from-literal=encryption-key=$(openssl rand -hex 32) \
      --from-literal=pg-password=<your-pg-password>

    # Install
    helm install langfuse langfuse/langfuse \
      --namespace langfuse \
      --create-namespace \
      --set langfuse.nextauth.url="https://langfuse.example.com" \
      --set langfuse.nextauth.existingSecret=langfuse-secrets \
      --set langfuse.nextauth.existingSecretKey=nextauth-secret \
      --set langfuse.salt.existingSecret=langfuse-secrets \
      --set langfuse.salt.existingSecretKey=salt
    ```
  </Tab>
</Tabs>

## Step 2: Create a Langfuse Project

1. Navigate to your Langfuse instance
2. Sign up for an account (or log in with the admin account)
3. Create a new **Project** for each solution you want to trace:
   * `data-insights`, for Data Insights traces
   * `data-governance`, for Data Governance traces
   * `semiconductor`, for Semiconductor traces
4. In each project, go to **Settings → API Keys** and copy the **Public Key** and **Secret Key**

## Step 3: Store Credentials

Store Langfuse credentials as Kubernetes Secrets (or in your Secrets backend):

```bash theme={null}
# Create one secret per solution (use separate Langfuse projects for isolation):
kubectl create secret generic langfuse-api-keys \
  --namespace em-runtime \
  --from-literal=public-key=<data-insights-public-key> \
  --from-literal=secret-key=<data-insights-secret-key>

kubectl create secret generic langfuse-api-keys-dr \
  --namespace em-runtime \
  --from-literal=public-key=<data-governance-public-key> \
  --from-literal=secret-key=<data-governance-secret-key>

kubectl create secret generic langfuse-api-keys-semi \
  --namespace em-runtime \
  --from-literal=public-key=<semiconductor-public-key> \
  --from-literal=secret-key=<semiconductor-secret-key>
```

## Step 4: Configure Solutions

Set the Langfuse environment variables in each solution's Helm values:

### Data Insights

```yaml theme={null}
# Helm values key for em-talk2data (Data Insights solution)
em-talk2data:
  extraEnvVars:
    - name: LANGFUSE_HOST
      value: "https://langfuse.example.com"
    - name: LANGFUSE_PUBLIC_KEY
      valueFrom:
        secretKeyRef:
          name: langfuse-api-keys
          key: public-key
    - name: LANGFUSE_SECRET_KEY
      valueFrom:
        secretKeyRef:
          name: langfuse-api-keys
          key: secret-key
```

### Data Governance

Same configuration, referencing the data-governance project keys:

```yaml theme={null}
# Helm values key for em-data-readiness (Data Governance solution)
em-data-readiness:
  extraEnvVars:
    - name: LANGFUSE_HOST
      value: "https://langfuse.example.com"
    - name: LANGFUSE_PUBLIC_KEY
      valueFrom:
        secretKeyRef:
          name: langfuse-api-keys-dr
          key: public-key
    - name: LANGFUSE_SECRET_KEY
      valueFrom:
        secretKeyRef:
          name: langfuse-api-keys-dr
          key: secret-key
```

### Semiconductor

Apply to both the Backend API and AI Agent services:

```yaml theme={null}
# Helm values key for em-semi (Semiconductor solution)
em-semi:
  extraEnvVars:
    - name: LANGFUSE_HOST
      value: "https://langfuse.example.com"
    - name: LANGFUSE_PUBLIC_KEY
      valueFrom:
        secretKeyRef:
          name: langfuse-api-keys-semi
          key: public-key
    - name: LANGFUSE_SECRET_KEY
      valueFrom:
        secretKeyRef:
          name: langfuse-api-keys-semi
          key: secret-key
```

## Step 5: Verify Traces

After deploying the configuration, trigger an LLM call in any solution:

1. In Data Insights: ask a natural language question
2. In Data Governance: run a profiling job
3. In Semiconductor: send a chat message to the AI agent

Then check the **Traces** tab in Langfuse, you should see the call appear within seconds.

## Troubleshooting

<AccordionGroup>
  <Accordion title="No traces appearing in Langfuse">
    1. Verify `LANGFUSE_HOST`, `LANGFUSE_PUBLIC_KEY`, and `LANGFUSE_SECRET_KEY` are set correctly in the pod
    2. Check that the Langfuse host is reachable from the pod: `kubectl exec -it <pod> -- curl -I https://langfuse.example.com`
    3. Check solution logs for Langfuse callback errors
    4. Verify the public key corresponds to the correct Langfuse project
  </Accordion>

  <Accordion title="Langfuse UI not accessible">
    1. Check pod status: `kubectl get pods -n langfuse`
    2. Check worker logs: `kubectl logs -n langfuse -l app=langfuse-worker`
    3. Verify the `NEXTAUTH_URL` matches the URL you're accessing
  </Accordion>
</AccordionGroup>
