pi-langfuse 1.4.1 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,140 +0,0 @@
1
- ---
2
- name: langfuse-observability
3
- description: Instrument LLM applications with Langfuse tracing. Use when setting up Langfuse, adding observability to LLM calls, or auditing existing instrumentation.
4
- ---
5
-
6
- # Langfuse Observability
7
-
8
- Instrument LLM applications with Langfuse tracing, following best practices and tailored to your use case.
9
-
10
- ## When to Use
11
-
12
- - Setting up Langfuse in a new project
13
- - Auditing existing Langfuse instrumentation
14
- - Adding observability to LLM calls
15
-
16
- ## Workflow
17
-
18
- ### 1. Assess Current State
19
-
20
- Check the project:
21
-
22
- - Is Langfuse SDK installed?
23
- - What LLM frameworks are used? (OpenAI SDK, LangChain, LlamaIndex, Vercel AI SDK, etc.)
24
- - Is there existing instrumentation?
25
-
26
- **No integration yet:** Set up Langfuse using a framework integration if available. Integrations capture more context automatically and require less code than manual instrumentation.
27
-
28
- **Integration exists:** Audit against baseline requirements below.
29
-
30
- ### 2. Verify Baseline Requirements
31
-
32
- Every trace should have these fundamentals:
33
-
34
- | Requirement | Check | Why |
35
- | ------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------ |
36
- | Model name | Is the LLM model captured? | Enables model comparison and filtering |
37
- | Token usage | Are input/output tokens tracked? | Enables automatic cost calculation |
38
- | Good trace names | Are names descriptive? (`chat-response`, not `trace-1`) | Makes traces findable and filterable |
39
- | Span hierarchy | Are multi-step operations nested properly? | Shows which step is slow or failing |
40
- | Correct observation types | Are generations marked as generations? | Enables model-specific analytics |
41
- | Sensitive data masked | Is PII/confidential data excluded or masked? | Prevents data leakage |
42
- | Trace input/output | Does the trace capture meaningful input/output? Is input explicitly set to show only relevant data (e.g., user message), not all function args? | Makes traces readable in the UI and avoids leaking sensitive args |
43
-
44
- Framework integrations (OpenAI, LangChain, etc.) handle model name, tokens, and observation types automatically. Prefer integrations over manual instrumentation.
45
-
46
- Docs: https://langfuse.com/docs/tracing
47
-
48
- ### 3. Explore Traces First
49
-
50
- Once baseline instrumentation is working, encourage the user to explore their traces in the Langfuse UI before adding more context:
51
-
52
- "Your traces are now appearing in Langfuse. Take a look at a few of them—see what data is being captured, what's useful, and what's missing. This will help us decide what additional context to add."
53
-
54
- This helps the user:
55
-
56
- - Understand what they're already getting
57
- - Form opinions about what's missing
58
- - Ask better questions about what they need
59
-
60
- ### 4. Discover Additional Context Needs
61
-
62
- Determine what additional instrumentation would be valuable. **Infer from code when possible, only ask when unclear.**
63
-
64
- **Infer from code:**
65
-
66
- | If you see in code... | Infer | Suggest |
67
- | ---------------------------------------------------- | ----------------- | ------------------------- |
68
- | Conversation history, chat endpoints, message arrays | Multi-turn app | `session_id` |
69
- | User authentication, `user_id` variables | User-aware app | `user_id` on traces |
70
- | Multiple distinct endpoints/features | Multi-feature app | `feature` tag |
71
- | Customer/tenant identifiers | Multi-tenant app | `customer_id` or tier tag |
72
- | Feedback collection, ratings | Has user feedback | Capture as scores |
73
-
74
- **Only ask when not obvious from code:**
75
-
76
- - "How do you know when a response is good vs bad?" → Determines scoring approach
77
- - "What would you want to filter by in a dashboard?" → Surfaces non-obvious tags
78
- - "Are there different user segments you'd want to compare?" → Customer tiers, plans, etc.
79
-
80
- **Additions and their value:**
81
-
82
- | Addition | Why | Docs |
83
- | ------------------- | ------------------------------------------- | --------------------------------------------------- |
84
- | `session_id` | Groups conversations together | https://langfuse.com/docs/tracing-features/sessions |
85
- | `user_id` | Enables user filtering and cost attribution | https://langfuse.com/docs/tracing-features/users |
86
- | User feedback score | Enables quality filtering and trends | https://langfuse.com/docs/scores/overview |
87
- | `feature` tag | Per-feature analytics | https://langfuse.com/docs/tracing-features/tags |
88
- | `customer_tier` tag | Cost/quality breakdown by segment | https://langfuse.com/docs/tracing-features/tags |
89
-
90
- These are NOT baseline requirements—only add what's relevant based on inference or user input.
91
-
92
- ### 5. Guide to UI
93
-
94
- After adding context, point users to relevant UI features:
95
-
96
- - Traces view: See individual requests
97
- - Sessions view: See grouped conversations (if session_id added)
98
- - Dashboard: Build filtered views using tags
99
- - Scores: Filter by quality metrics
100
-
101
- ## Framework Integrations
102
-
103
- Prefer these over manual instrumentation:
104
-
105
- | Framework | Integration | Docs |
106
- | ------------- | ---------------------- | ---------------------------------------------------- |
107
- | OpenAI SDK | Drop-in replacement | https://langfuse.com/docs/integrations/openai |
108
- | LangChain | Callback handler | https://langfuse.com/docs/integrations/langchain |
109
- | LlamaIndex | Callback handler | https://langfuse.com/docs/integrations/llama-index |
110
- | Vercel AI SDK | OpenTelemetry exporter | https://langfuse.com/docs/integrations/vercel-ai-sdk |
111
- | LiteLLM | Callback or proxy | https://langfuse.com/docs/integrations/litellm |
112
-
113
- Full list: https://langfuse.com/docs/integrations
114
-
115
- ## Always Explain Why
116
-
117
- When suggesting additions, explain the user benefit:
118
-
119
- ```
120
- "I recommend adding session_id to your traces.
121
-
122
- Why: This groups messages from the same conversation together.
123
- You'll be able to see full conversation flows in the Sessions view,
124
- making it much easier to debug multi-turn interactions.
125
-
126
- Learn more: https://langfuse.com/docs/tracing-features/sessions"
127
- ```
128
-
129
- ## Common Mistakes
130
-
131
- | Mistake | Problem | Fix |
132
- | ---------------------------------------------- | --------------------------------------------------- | --------------------------------------------------------------------------------- |
133
- | No `flush()` in scripts | Traces never sent | Call `langfuse.flush()` before exit |
134
- | Flat traces | Can't see which step failed | Use nested spans for distinct steps |
135
- | Generic trace names | Hard to filter | Use descriptive names: `chat-response`, `doc-summary` |
136
- | Logging sensitive data | Data leakage risk | Mask PII before tracing |
137
- | Not explicitly setting input with `@observe` | All function args become trace input (including API keys, configs) | Python: use `langfuse.update_current_span(input=...)`. JS/TS: use `updateActiveObservation({ input: ... })`. Set only the relevant input (e.g., user message) |
138
- | Manual instrumentation when integration exists | More code, less context | Use framework integration |
139
- | Langfuse import before env vars loaded | Langfuse initializes with missing/wrong credentials | Import Langfuse AFTER loading environment variables (e.g., after `load_dotenv()`) |
140
- | Wrong import order with OpenAI | Langfuse can't patch the OpenAI client | Import Langfuse and call its setup BEFORE importing OpenAI client |
@@ -1,234 +0,0 @@
1
- ---
2
- name: langfuse-prompt-migration
3
- description: Migrate hardcoded prompts to Langfuse for version control and deployment-free iteration. Use when user wants to externalize prompts, move prompts to Langfuse, or set up prompt management.
4
- ---
5
-
6
- # Langfuse Prompt Migration
7
-
8
- Migrate hardcoded prompts to Langfuse for version control, A/B testing, and deployment-free iteration.
9
-
10
- ## Prerequisites
11
-
12
- Verify credentials are set before starting. Check existence only — never print the secret key, since the value would land in the agent's context and transcripts:
13
-
14
- ```bash
15
- [ -n "$LANGFUSE_PUBLIC_KEY" ] && echo "LANGFUSE_PUBLIC_KEY: set" || echo "LANGFUSE_PUBLIC_KEY: missing"
16
- [ -n "$LANGFUSE_SECRET_KEY" ] && echo "LANGFUSE_SECRET_KEY: set" || echo "LANGFUSE_SECRET_KEY: missing"
17
- [ -n "$LANGFUSE_HOST" ] && echo "LANGFUSE_HOST: $LANGFUSE_HOST" || echo "LANGFUSE_HOST: missing"
18
- ```
19
-
20
- If not set, ask the user to configure them in their shell or a `.env` file. Do not ask them to paste keys into chat.
21
-
22
- ## Migration Flow
23
-
24
- ```
25
- 1. Scan codebase for prompts
26
- 2. Analyze templating compatibility
27
- 3. Propose structure (names, subprompts, variables)
28
- 4. User approves
29
- 5. Create prompts in Langfuse
30
- 6. Refactor code to use get_prompt()
31
- 7. Link prompts to traces (if tracing enabled)
32
- 8. Verify application works
33
- ```
34
-
35
- ## Step 1: Find Prompts and Build an Inventory
36
-
37
- Before writing ANY code, make a complete list of every prompt you found. For each one, note:
38
-
39
- - Name: descriptive, lowercase, hyphenated (e.g. chat-assistant, email-classifier)
40
- - Source file: where the prompt text lives
41
- - Code file to refactor: the Python/JS file that USES the prompt (for asset files like .txt/.yaml/.md, this is the file that reads/loads the asset — NOT the asset file itself)
42
- - Type: chat (used as a message in a chat API) or text (used as a plain string)
43
- - Variables: values interpolated into the prompt, converted to {{var}} syntax:
44
- f-string {var} → {{var}}
45
- .format(var=...) → {{var}}
46
- ${var} → {{var}}
47
- String concatenation + var + → {{var}}
48
- YAML {var} → {{var}}
49
- - Prompt content: the actual text to upload, with variables converted to {{var}} syntax
50
-
51
- Search for these patterns:
52
-
53
- | Framework | Look for |
54
- |-----------|----------|
55
- | OpenAI | `messages=[{"role": "system", "content": "..."}]` |
56
- | Anthropic | `system="..."` |
57
- | LangChain | `ChatPromptTemplate`, `SystemMessage` |
58
- | Vercel AI | `system: "..."`, `prompt: "..."` |
59
- | Raw | Multi-line strings near LLM calls |
60
-
61
- ## Step 2: Check Templating Compatibility
62
-
63
- **CRITICAL:** Langfuse only supports simple `{{variable}}` substitution. No conditionals, loops, or filters.
64
-
65
- | Template Feature | Langfuse Native | Action |
66
- |------------------|-----------------|--------|
67
- | `{{variable}}` | ✅ | Direct migration |
68
- | `{var}` / `${var}` | ⚠️ | Convert to `{{var}}` |
69
- | `{% if %}` / `{% for %}` | ❌ | Move logic to code |
70
- | `{{ var \| filter }}` | ❌ | Apply filter in code |
71
-
72
- **CRITICAL — Variable syntax:** Langfuse uses DOUBLE curly braces for variables: `{{var}}`. When uploading prompt content, you MUST convert every single-brace `{var}` from the original code to double-brace `{{var}}`. Never upload `{var}` — it must be `{{var}}`.
73
-
74
- ### Decision Tree
75
-
76
- ```
77
- Contains {% if %}, {% for %}, or filters?
78
- ├─ No → Direct migration
79
- └─ Yes → Choose:
80
- ├─ Option A (RECOMMENDED): Move logic to code, pass pre-computed values
81
- └─ Option B: Store raw template, compile client-side with Jinja2
82
- └─ ⚠️ Loses: Playground preview, UI experiments
83
- ```
84
-
85
- ### Simplifying Complex Templates
86
-
87
- **Conditionals** → Pre-compute in code:
88
- ```python
89
- # Instead of {% if user.is_premium %}...{% endif %} in prompt
90
- # Use {{tier_message}} and compute value in code before compile()
91
- ```
92
-
93
- **Loops** → Pre-format in code:
94
- ```python
95
- # Instead of {% for tool in tools %}...{% endfor %} in prompt
96
- # Use {{tools_list}} and format the list in code before compile()
97
- ```
98
-
99
- For external templating details, fetch: https://langfuse.com/faq/all/using-external-templating-libraries
100
-
101
- ## Step 3: Propose Structure
102
-
103
- ### Naming Conventions
104
-
105
- | Rule | Example | Bad |
106
- |------|---------|-----|
107
- | Lowercase, hyphenated | `chat-assistant` | `ChatAssistant_v2` |
108
- | Feature-based | `document-summarizer` | `prompt1` |
109
- | Hierarchical for related | `support/triage` | `supportTriage` |
110
- | Prefix subprompts with `_` | `_base-personality` | `shared-personality` |
111
-
112
- ### Identify Subprompts
113
-
114
- Extract when:
115
- - Same text in 2+ prompts
116
- - Represents distinct component (personality, safety rules, format)
117
- - Would need to change together
118
-
119
- ### Variable Extraction
120
-
121
- | Make Variable | Keep Hardcoded |
122
- |---------------|----------------|
123
- | User-specific (`{{user_name}}`) | Output format instructions |
124
- | Dynamic content (`{{context}}`) | Safety guardrails |
125
- | Per-request (`{{query}}`) | Persona/personality |
126
- | Environment-specific (`{{company_name}}`) | Static examples |
127
-
128
- ## Step 4: Present Plan to User
129
-
130
- Format:
131
- ```
132
- Found N prompts across M files:
133
-
134
- src/chat.py:
135
- - System prompt (47 lines) → 'chat-assistant'
136
-
137
- src/support/triage.py:
138
- - Triage prompt (34 lines) → 'support/triage'
139
- ⚠️ Contains {% if %} - will simplify
140
-
141
- Subprompts to extract:
142
- - '_base-personality' - used by: chat-assistant, support/triage
143
-
144
- Variables to add:
145
- - {{user_name}} - hardcoded in 2 prompts
146
-
147
- Proceed?
148
- ```
149
-
150
- ## Step 5: Create Prompts in Langfuse
151
-
152
- Use `langfuse.create_prompt()` with:
153
- - `name`: Your chosen name
154
- - `prompt`: Template text (or message array for chat type)
155
- - `type`: `"text"` or `"chat"`
156
- - `labels`: `["production"]` (they're already live)
157
- - `config`: Optional model settings
158
-
159
- **Labeling strategy:**
160
- - `production` → All migrated prompts
161
- - `staging` → Add later for testing
162
- - `latest` → Auto-applied by Langfuse
163
-
164
- For full API: fetch https://langfuse.com/docs/prompts/get-started
165
-
166
- ## Step 6: Refactor Code
167
-
168
- Replace hardcoded prompts with:
169
-
170
- ```python
171
- prompt = langfuse.get_prompt("name", label="production")
172
- messages = prompt.compile(var1=value1, var2=value2)
173
- ```
174
-
175
- **Key points:**
176
- - Always use `label="production"` (not `latest`) for stability
177
- - Call `.compile()` to substitute variables
178
- - For chat prompts, result is message array ready for API
179
-
180
- For SDK examples (Python/JS/TS): fetch https://langfuse.com/docs/prompts/get-started
181
-
182
- ## Step 7: Link Prompts to Traces
183
-
184
- If codebase uses Langfuse tracing, link prompts so you can see which version produced each response.
185
-
186
- ### Detect Existing Tracing
187
-
188
- Look for:
189
- - `@observe()` decorators
190
- - `langfuse.trace()` calls
191
- - `from langfuse.openai import openai` (instrumented client)
192
-
193
- ### Link Methods
194
-
195
- | Setup | How to Link |
196
- |-------|-------------|
197
- | `@observe()` decorator | `langfuse_context.update_current_observation(prompt=prompt)` |
198
- | Manual tracing | `trace.generation(prompt=prompt, ...)` |
199
- | OpenAI integration | `openai.chat.completions.create(..., langfuse_prompt=prompt)` |
200
-
201
- ### Verify in UI
202
-
203
- 1. Go to **Traces** → select a trace
204
- 2. Click on **Generation**
205
- 3. Check **Prompt** field shows name and version
206
-
207
- For tracing details: fetch https://langfuse.com/docs/prompts/get-started#link-with-langfuse-tracing
208
-
209
- ## Step 8: Verify Migration
210
-
211
- ### Checklist
212
-
213
- - [ ] All prompts created with `production` label
214
- - [ ] Code fetches with `label="production"`
215
- - [ ] Variables compile without errors
216
- - [ ] Subprompts resolve correctly
217
- - [ ] Application behavior unchanged
218
- - [ ] Generations show linked prompt in UI (if tracing)
219
-
220
- ### Common Issues
221
-
222
- | Issue | Solution |
223
- |-------|----------|
224
- | `PromptNotFoundError` | Check name spelling |
225
- | Variables not replaced | Use `{{var}}` not `{var}`, call `.compile()` |
226
- | Subprompt not resolved | Must exist with same label |
227
- | Old prompt cached | Restart app |
228
-
229
- ## Out of Scope
230
-
231
- - Prompt engineering (writing better prompts)
232
- - Evaluation setup
233
- - A/B testing workflow
234
- - Non-LLM string templates
@@ -1,181 +0,0 @@
1
- ---
2
- name: langfuse-sdk-upgrade
3
- description: Upgrade Langfuse SDKs from older versions to the latest. Use when migrating Python SDK v2/v3 to v4, or JS/TS SDK v3/v4 to v5.
4
- ---
5
-
6
- # Langfuse SDK Upgrade Guide
7
-
8
- Assist users in upgrading their Langfuse SDK to the latest version. The Python and JS/TS SDKs share the same architectural changes but differ in syntax.
9
-
10
- ## When to Use
11
-
12
- - User asks to upgrade/migrate their Langfuse SDK
13
- - User is on an older SDK version and encounters deprecated APIs
14
- - User wants to adopt the latest Langfuse features
15
-
16
- ## Migration Docs
17
-
18
- Always fetch the latest migration guide before starting — these pages are the source of truth:
19
-
20
- - **Python (v3 → v4):** https://langfuse.com/docs/observability/sdk/upgrade-path/python-v3-to-v4
21
- - **JS/TS (v4 → v5):** https://langfuse.com/docs/observability/sdk/upgrade-path/js-v4-to-v5
22
-
23
- Fetch the relevant page as markdown before implementing any changes:
24
-
25
- ```bash
26
- curl -s "https://langfuse.com/docs/observability/sdk/upgrade-path/python-v3-to-v4.md"
27
- curl -s "https://langfuse.com/docs/observability/sdk/upgrade-path/js-v4-to-v5.md"
28
- ```
29
-
30
- ## Upgrade Checklist
31
-
32
- Work through each item in order. Skip items that don't apply to the user's codebase.
33
-
34
- ### Both SDKs
35
-
36
- - [ ] **Update the SDK package** to the latest version
37
- - [ ] **Audit span filtering**: Non-LLM spans (HTTP, DB, queues) no longer export by default. If the user relied on these, configure a custom `should_export_span` / `shouldExportSpan` filter
38
- - [ ] **Replace `update_current_trace()` / `updateActiveTrace()`**: Split into three calls:
39
- - `propagate_attributes()` / `propagateAttributes()` for correlating attributes (`user_id`, `session_id`, `tags`, `metadata`, `trace_name`)
40
- - `set_current_trace_io()` / `setActiveTraceIO()` for input/output (deprecated — prefer setting I/O on root observation directly)
41
- - `set_current_trace_as_public()` / `setActiveTraceAsPublic()` for public flag
42
- - [ ] **Replace `.update_trace()` / `.updateTrace()`** on observation objects (same decomposition as above)
43
- - [ ] **Update API namespace references**: `observations_v_2` / `observationsV2` → `observations`, `score_v_2` / `scoreV2` → `scores`, `metrics_v_2` / `metricsV2` → `metrics`. Legacy v1 APIs moved to `api.legacy.*`
44
- - [ ] **Validate metadata format**: Must be `dict[str, str]` / `Record<string, string>` with values ≤200 characters
45
- - [ ] **Move `release` and `environment`** from code parameters to environment variables (`LANGFUSE_RELEASE`, `LANGFUSE_TRACING_ENVIRONMENT`)
46
- - [ ] **Enable debug logging** during migration to catch issues (`debug=True` in Python, `LANGFUSE_DEBUG="true"` in JS/TS)
47
- - [ ] **Test trace hierarchies** to verify no spans are unexpectedly dropped
48
-
49
- ### Python-specific
50
-
51
- - [ ] **Replace `start_span()` / `start_generation()`** with `start_observation()` (use `as_type="generation"` for generations)
52
- - [ ] **Replace `start_as_current_span()` / `start_as_current_generation()`** with `start_as_current_observation()`
53
- - [ ] **Replace dataset `item.run()`** with `dataset.run_experiment(name=..., task=...)`
54
- - [ ] **Remove `CallbackHandler(update_trace=...)`** parameter — use `propagate_attributes()` wrapper instead
55
- - [ ] **Upgrade to Pydantic v2** — the SDK now requires it. Use `pydantic.v1` compatibility shim if migrating gradually
56
- - [ ] **Update removed types**: `TraceMetadata`, `ObservationParams` removed from `langfuse.types`. Import `MapValue`, `ModelUsage`, `PromptClient` from `langfuse.model`
57
-
58
- ### JS/TS-specific
59
-
60
- - [ ] **Update LangChain `CallbackHandler`** — `traceMetadata` now requires string values; internal behavior uses `propagateAttributes()` instead of direct trace updates
61
- - [ ] **Update OpenAI integration** — `traceMethod` wrapper now uses `propagateAttributes()` internally; wrap entire execution in `propagateAttributes()` if relying on parent attribute inheritance
62
-
63
- ## Key API Changes Reference
64
-
65
- ### Correlating attributes (both SDKs)
66
-
67
- **Before:**
68
- ```python
69
- # Python
70
- langfuse.update_current_trace(name="trace-name", user_id="user-123", session_id="session-abc", tags=["tag1"])
71
- ```
72
- ```typescript
73
- // JS/TS
74
- updateActiveTrace({ name: "trace-name", userId: "user-123", sessionId: "session-456", tags: ["prod"] });
75
- ```
76
-
77
- **After:**
78
- ```python
79
- # Python
80
- from langfuse import propagate_attributes
81
-
82
- with propagate_attributes(trace_name="trace-name", user_id="user-123", session_id="session-abc", tags=["tag1"]):
83
- result = call_llm("hello")
84
- ```
85
- ```typescript
86
- // JS/TS
87
- import { propagateAttributes } from "langfuse";
88
-
89
- await propagateAttributes(
90
- { traceName: "trace-name", userId: "user-123", sessionId: "session-456", tags: ["prod"] },
91
- async () => { /* traced code */ }
92
- );
93
- ```
94
-
95
- ### Span/Generation creation (Python)
96
-
97
- **Before:**
98
- ```python
99
- langfuse.start_span(name="x")
100
- langfuse.start_generation(name="x", model="gpt-4")
101
- ```
102
-
103
- **After:**
104
- ```python
105
- langfuse.start_observation(name="x")
106
- langfuse.start_observation(name="x", as_type="generation", model="gpt-4")
107
- ```
108
-
109
- ### Dataset experiments (Python)
110
-
111
- **Before:**
112
- ```python
113
- for item in dataset.items:
114
- with item.run(run_name="my-run") as span:
115
- result = my_llm(item.input)
116
- span.update(output=result)
117
- ```
118
-
119
- **After:**
120
- ```python
121
- def my_task(*, item, **kwargs):
122
- return my_llm(item.input)
123
-
124
- dataset.run_experiment(name="my-run", task=my_task)
125
- ```
126
-
127
- ### Span filtering (both SDKs)
128
-
129
- To restore pre-upgrade "export all" behavior:
130
-
131
- ```python
132
- # Python
133
- langfuse = Langfuse(should_export_span=lambda span: True)
134
- ```
135
- ```typescript
136
- // JS/TS
137
- const spanProcessor = new LangfuseSpanProcessor({ shouldExportSpan: () => true });
138
- ```
139
-
140
- To extend defaults with custom scopes:
141
-
142
- ```python
143
- # Python
144
- from langfuse.span_filter import is_default_export_span
145
-
146
- langfuse = Langfuse(
147
- should_export_span=lambda span: (
148
- is_default_export_span(span)
149
- or span.instrumentation_scope.name.startswith("my_framework")
150
- )
151
- )
152
- ```
153
- ```typescript
154
- // JS/TS
155
- import { isDefaultExportSpan } from "@langfuse/otel";
156
-
157
- shouldExportSpan: ({ otelSpan }) =>
158
- isDefaultExportSpan(otelSpan) || otelSpan.instrumentationScope.name.startsWith("my_framework")
159
- ```
160
-
161
- ## Common Pitfalls
162
-
163
- | Pitfall | Impact | Fix |
164
- | --- | --- | --- |
165
- | Dropping intermediate spans via filtering | Breaks trace trees — child spans become orphaned | Use `is_default_export_span` as base and only add/remove specific scopes |
166
- | Metadata with non-string values | Values silently coerced or dropped | Ensure all metadata values are strings ≤200 characters |
167
- | Setting attributes outside `propagate_attributes()` callback | Attributes don't attach to observations | Wrap all traced code inside the callback |
168
- | Using deprecated `set_current_trace_io()` for new code | Will be removed in future versions | Set input/output directly on the root observation |
169
- | Forgetting Pydantic v2 upgrade (Python) | Import errors or runtime failures | Upgrade Pydantic or use `pydantic.v1` shim |
170
- | `release`/`environment` still passed as parameters | Silently ignored | Use `LANGFUSE_RELEASE` and `LANGFUSE_TRACING_ENVIRONMENT` env vars |
171
- | LangChain/OpenAI attribute propagation direction changed | Attributes propagate downward only, not upward to parent traces | Wrap outer call in `propagate_attributes()` |
172
-
173
- ## Best Practices
174
-
175
- 1. **Always fetch the migration docs first** — they are the canonical source and may have been updated since this guide was written
176
- 2. **Enable debug logging during migration** to surface dropped spans and trace hierarchy issues
177
- 3. **Use `propagate_attributes()` as the primary mechanism** for setting trace-level correlating attributes
178
- 4. **Set input/output on root observations directly** rather than using deprecated trace-level setters
179
- 5. **Compose custom span filters** with `is_default_export_span` / `isDefaultExportSpan` to extend defaults rather than replacing them entirely
180
- 6. **Test thoroughly** — run the application with debug logging, check the Langfuse UI for missing or orphaned spans, verify metadata appears correctly
181
- 7. **Migrate incrementally** — upgrade the SDK first, fix breaking changes, then adopt new patterns
@@ -1,52 +0,0 @@
1
- ---
2
- name: langfuse-skill-feedback
3
- description: Submit feedback about the Langfuse skill to its maintainers via GitHub Discussions. Use when the user indicates the skill gave incorrect guidance, is missing information, or could be improved.
4
- ---
5
-
6
- # Skill Feedback
7
-
8
- Follow these steps exactly:
9
-
10
- 1. **Ask permission**: Ask the user if they'd like you to submit feedback to the skill maintainers. Make it clear this is about the skill (the agent instructions), not about Langfuse the product. If they decline, move on.
11
- 2. **Draft feedback**: Write the feedback using the form structure below. Present the draft to the user and ask if they'd like to change anything before submitting.
12
- 3. **Submit**: Once approved, submit via `gh` CLI as described below. Share the resulting discussion URL with the user.
13
-
14
- ## Feedback Form Structure
15
-
16
- Draft the feedback using these two fields:
17
-
18
- **Describe your idea or feedback** (required)
19
- A clear description of what went wrong or what could be improved. Include:
20
- - What the user was trying to do
21
- - What the skill did vs what was expected
22
- - Any specific instructions that were incorrect or missing
23
-
24
- **What would the ideal outcome look like?** (optional)
25
- What the correct behavior or guidance should be.
26
-
27
- Format the body as markdown with the two field labels as headings.
28
-
29
- ## Submitting
30
-
31
- Create a GitHub Discussion on the `langfuse/skills` repository using the GraphQL API:
32
-
33
- ```bash
34
- gh api graphql -f query='
35
- mutation($repoId: ID!, $categoryId: ID!, $title: String!, $body: String!) {
36
- createDiscussion(input: {repositoryId: $repoId, categoryId: $categoryId, title: $title, body: $body}) {
37
- discussion { url }
38
- }
39
- }' \
40
- -f repoId="$(gh api graphql -f query='{ repository(owner: "langfuse", name: "skills") { id } }' --jq '.data.repository.id')" \
41
- -f categoryId="$(gh api graphql -f query='{ repository(owner: "langfuse", name: "skills") { discussionCategories(first: 10) { nodes { id name } } } }' --jq '.data.repository.discussionCategories.nodes[] | select(.name == "Ideas & Improvements") | .id')" \
42
- -f title="<concise title>" \
43
- -f body="<formatted feedback>"
44
- ```
45
-
46
- If the `gh` CLI is not authenticated or the request fails, give the user this link to create the discussion manually:
47
-
48
- ```
49
- https://github.com/langfuse/skills/discussions/new?category=ideas-improvements
50
- ```
51
-
52
- After submission, share the discussion URL with the user.