|
| 1 | +--- |
| 2 | +title: Custom output rendering |
| 3 | +sidebarTitle: Custom output rendering |
| 4 | +--- |
| 5 | + |
| 6 | +This page describes how to use custom output rendering to visualize outputs from [_experiments_](/langsmith/evaluation-concepts#experiment) using your own custom HTML pages. |
| 7 | + |
| 8 | +You'll learn how to: |
| 9 | + |
| 10 | +- **[Configure custom rendering](#configure-custom-output-rendering)** in the LangSmith UI or via the API. |
| 11 | +- **[Build a custom renderer](#build-a-custom-renderer)** to display output data. |
| 12 | +- **[Understand where custom rendering appears](#where-custom-rendering-appears)** in LangSmith. |
| 13 | + |
| 14 | +## Overview |
| 15 | + |
| 16 | +By default, LangSmith displays outputs in a standard JSON format. With custom output rendering, you can replace this default view with your own HTML page that receives the output data via the postMessage API and renders it however you choose. |
| 17 | + |
| 18 | +This is particularly useful for: |
| 19 | + |
| 20 | +- **Domain-specific formatting**: Display medical records, legal documents, or other specialized data types in their native format. |
| 21 | +- **Custom visualizations**: Create charts, graphs, or diagrams from numeric or structured output data. |
| 22 | + |
| 23 | +Custom rendering is configured per-[_dataset_](/langsmith/evaluation-concepts#datasets). |
| 24 | + |
| 25 | +## Prerequisites |
| 26 | + |
| 27 | +<Check> |
| 28 | +- A LangSmith dataset |
| 29 | +- A web page that can receive postMessage events (can be hosted anywhere or run locally) |
| 30 | +- Basic knowledge of HTML/JavaScript and the postMessage API |
| 31 | +</Check> |
| 32 | + |
| 33 | +## Configure custom output rendering |
| 34 | + |
| 35 | +### In the LangSmith UI |
| 36 | + |
| 37 | +To configure custom output rendering for a dataset: |
| 38 | + |
| 39 | + |
| 40 | + |
| 41 | +1. Navigate to your dataset in the **Datasets & Experiments** page. |
| 42 | +2. Click **⋮** (three-dot menu) in the top right corner. |
| 43 | +3. Select **Custom Output Rendering**. |
| 44 | +4. Toggle **Enable custom output rendering**. |
| 45 | +5. Enter the webpage URL in the **URL** field. |
| 46 | +6. Click **Save**. |
| 47 | + |
| 48 | + |
| 49 | + |
| 50 | +### Via the API |
| 51 | + |
| 52 | +You can also configure custom rendering programmatically by updating the dataset metadata: |
| 53 | + |
| 54 | +<CodeGroup> |
| 55 | +```python Python |
| 56 | +from langsmith import Client |
| 57 | + |
| 58 | +client = Client() |
| 59 | + |
| 60 | +# Update dataset metadata with iframe config |
| 61 | +client.update_dataset( |
| 62 | + dataset_id="your-dataset-id", |
| 63 | + metadata={ |
| 64 | + "iframe_config": { |
| 65 | + "enabled": True, |
| 66 | + "url": "https://your-domain.com/output-renderer.html" |
| 67 | + } |
| 68 | + } |
| 69 | +) |
| 70 | +``` |
| 71 | + |
| 72 | +```typescript TypeScript |
| 73 | +import { Client } from "langsmith"; |
| 74 | + |
| 75 | +const client = new Client(); |
| 76 | + |
| 77 | +// Update dataset metadata with iframe config |
| 78 | +await client.updateDataset("your-dataset-id", { |
| 79 | + metadata: { |
| 80 | + iframe_config: { |
| 81 | + enabled: true, |
| 82 | + url: "https://your-domain.com/output-renderer.html" |
| 83 | + } |
| 84 | + } |
| 85 | +}); |
| 86 | +``` |
| 87 | +</CodeGroup> |
| 88 | + |
| 89 | +## Build a custom renderer |
| 90 | + |
| 91 | +### Understand the message format |
| 92 | + |
| 93 | +Your HTML page will receive output data via the [postMessage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage). LangSmith sends messages with the following structure: |
| 94 | + |
| 95 | +```typescript |
| 96 | +{ |
| 97 | + type: "output" | "reference", |
| 98 | + data: { |
| 99 | + // The outputs (actual output or reference output) |
| 100 | + // Structure varies based on your application |
| 101 | + }, |
| 102 | + metadata: { |
| 103 | + inputs: { |
| 104 | + // The inputs that generated this output |
| 105 | + // Structure varies based on your application |
| 106 | + } |
| 107 | + } |
| 108 | +} |
| 109 | +``` |
| 110 | + |
| 111 | +- `type`: Indicates whether this is an actual output (`"output"`) or a reference output (`"reference"`). |
| 112 | +- `data`: The output data itself. |
| 113 | +- `metadata.inputs`: The input data that generated this output, provided for context. |
| 114 | + |
| 115 | +<Note> |
| 116 | +**Message delivery timing**: LangSmith uses an exponential backoff retry mechanism to ensure your page receives the data even if it loads slowly. Messages are sent up to 6 times with increasing delays (100ms, 200ms, 400ms, 800ms, 1600ms, 3200ms). |
| 117 | +</Note> |
| 118 | + |
| 119 | +### Example implementation |
| 120 | + |
| 121 | +This example listens for incoming postMessage events and displays them on the page. Each message is numbered and formatted as JSON, making it easy to inspect the data structure LangSmith sends to your renderer. |
| 122 | + |
| 123 | +```html |
| 124 | +<!DOCTYPE html> |
| 125 | +<html> |
| 126 | + <head> |
| 127 | + <meta charset="UTF-8" /> |
| 128 | + <title>PostMessage Echo</title> |
| 129 | + <link rel="stylesheet" href="https://unpkg.com/sakura.css/css/sakura.css" /> |
| 130 | + </head> |
| 131 | + <body> |
| 132 | + <h1>PostMessage Messages</h1> |
| 133 | + <div id="messages"></div> |
| 134 | + <script> |
| 135 | + let count = 0; |
| 136 | + window.addEventListener("message", (event) => { |
| 137 | + count++; |
| 138 | + const header = document.createElement("h3"); |
| 139 | + header.appendChild(document.createTextNode(`Message ${count}`)); |
| 140 | + const code = document.createElement("code"); |
| 141 | + code.appendChild( |
| 142 | + document.createTextNode(JSON.stringify(event.data, null, 2)) |
| 143 | + ); |
| 144 | + const pre = document.createElement("pre"); |
| 145 | + pre.appendChild(code); |
| 146 | + document.getElementById("messages").appendChild(header); |
| 147 | + document.getElementById("messages").appendChild(pre); |
| 148 | + }); |
| 149 | + </script> |
| 150 | + </body> |
| 151 | +</html> |
| 152 | +``` |
| 153 | + |
| 154 | +## Where custom rendering appears |
| 155 | + |
| 156 | +When enabled, your custom rendering will replace the default output view in: |
| 157 | + |
| 158 | +- **Experiment comparison view**: When comparing outputs across multiple experiments: |
| 159 | + |
| 160 | + |
| 161 | + |
| 162 | +- **Run detail panes**: When viewing runs that are associated with a dataset: |
| 163 | + |
| 164 | + |
| 165 | + |
| 166 | +- **Annotation queues**: When experiments are added to annotation queues for review: |
| 167 | + |
| 168 | + |
0 commit comments