variably-sdk 2.6.1__tar.gz → 2.7.1__tar.gz
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.
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/PKG-INFO +37 -3
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/README.md +36 -2
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/pyproject.toml +1 -1
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably/client.py +53 -34
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably/observe.py +72 -42
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably_sdk.egg-info/PKG-INFO +37 -3
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/setup.cfg +0 -0
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/setup.py +0 -0
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably/__init__.py +0 -0
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably/cache.py +0 -0
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably/config.py +0 -0
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably/errors.py +0 -0
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably/http_client.py +0 -0
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably/logger.py +0 -0
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably/types.py +0 -0
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably/version.py +0 -0
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably_sdk.egg-info/SOURCES.txt +0 -0
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably_sdk.egg-info/dependency_links.txt +0 -0
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably_sdk.egg-info/requires.txt +0 -0
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/src/variably_sdk.egg-info/top_level.txt +0 -0
- {variably_sdk-2.6.1 → variably_sdk-2.7.1}/tests/test_streaming.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: variably-sdk
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.1
|
|
4
4
|
Summary: Official Python SDK for Variably feature flags, LLM experimentation, and prompt optimization platform
|
|
5
5
|
Author: Variably
|
|
6
6
|
Author-email: Variably <support@variably.com>
|
|
@@ -53,6 +53,11 @@ Official Python SDK for Variably — LLM evaluation, experimentation, and prompt
|
|
|
53
53
|
pip install variably-sdk
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
For Docker/Kubernetes deployments, add to your `requirements.txt`:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
variably-sdk>=2.6.1
|
|
60
|
+
```
|
|
56
61
|
## Quick Start — Observe Mode
|
|
57
62
|
|
|
58
63
|
Add **one line** to your existing LLM app and get **multi-dimension evaluation** across 40+ metrics in 6 categories: Quality, Safety, Semantic, Grounding, Coherence, and Advanced.
|
|
@@ -148,7 +153,36 @@ observe(
|
|
|
148
153
|
)
|
|
149
154
|
```
|
|
150
155
|
|
|
151
|
-
###
|
|
156
|
+
### RAG applications — grounding & hallucination scoring
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
observe(
|
|
160
|
+
prompt=user_query,
|
|
161
|
+
response=llm_answer,
|
|
162
|
+
provider_response=completion,
|
|
163
|
+
reference_materials=[
|
|
164
|
+
{"id": "chunk-1", "content": "Retrieved text...", "source": "docs.pdf"},
|
|
165
|
+
{"id": "chunk-2", "content": "Another chunk...", "source": "faq.md"},
|
|
166
|
+
],
|
|
167
|
+
retrieval_query=user_query,
|
|
168
|
+
)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Multi-turn chat — coherence scoring
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
observe(
|
|
175
|
+
prompt=latest_user_message,
|
|
176
|
+
response=llm_answer,
|
|
177
|
+
provider_response=completion,
|
|
178
|
+
conversation_history=[
|
|
179
|
+
{"role": "user", "content": "What is diabetes?"},
|
|
180
|
+
{"role": "assistant", "content": "Diabetes is a chronic condition..."},
|
|
181
|
+
{"role": "user", "content": "What are the symptoms?"},
|
|
182
|
+
],
|
|
183
|
+
session_id="conv-123",
|
|
184
|
+
)
|
|
185
|
+
```
|
|
152
186
|
|
|
153
187
|
| Parameter | Type | Required | Description |
|
|
154
188
|
|-----------|------|----------|-------------|
|
|
@@ -365,7 +399,7 @@ result = client.submit_response(
|
|
|
365
399
|
| `workflow_history[].content` | `str` | Message content |
|
|
366
400
|
| `retrieval_query` | `str` (optional) | The rewritten query sent to the retriever |
|
|
367
401
|
|
|
368
|
-
See [Context-Aware RAG Evaluation](../../docs/concepts/context-aware-rag-evaluation.md) for the full concept doc with architecture diagrams and integration examples.
|
|
402
|
+
See [Context-Aware RAG Evaluation](../../docs/concepts/LLM%20Evaluation/context-aware-rag-evaluation.md) for the full concept doc with architecture diagrams and integration examples.
|
|
369
403
|
|
|
370
404
|
#### Integration with LangGraph / FastAPI streaming
|
|
371
405
|
|
|
@@ -8,6 +8,11 @@ Official Python SDK for Variably — LLM evaluation, experimentation, and prompt
|
|
|
8
8
|
pip install variably-sdk
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
For Docker/Kubernetes deployments, add to your `requirements.txt`:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
variably-sdk>=2.6.1
|
|
15
|
+
```
|
|
11
16
|
## Quick Start — Observe Mode
|
|
12
17
|
|
|
13
18
|
Add **one line** to your existing LLM app and get **multi-dimension evaluation** across 40+ metrics in 6 categories: Quality, Safety, Semantic, Grounding, Coherence, and Advanced.
|
|
@@ -103,7 +108,36 @@ observe(
|
|
|
103
108
|
)
|
|
104
109
|
```
|
|
105
110
|
|
|
106
|
-
###
|
|
111
|
+
### RAG applications — grounding & hallucination scoring
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
observe(
|
|
115
|
+
prompt=user_query,
|
|
116
|
+
response=llm_answer,
|
|
117
|
+
provider_response=completion,
|
|
118
|
+
reference_materials=[
|
|
119
|
+
{"id": "chunk-1", "content": "Retrieved text...", "source": "docs.pdf"},
|
|
120
|
+
{"id": "chunk-2", "content": "Another chunk...", "source": "faq.md"},
|
|
121
|
+
],
|
|
122
|
+
retrieval_query=user_query,
|
|
123
|
+
)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Multi-turn chat — coherence scoring
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
observe(
|
|
130
|
+
prompt=latest_user_message,
|
|
131
|
+
response=llm_answer,
|
|
132
|
+
provider_response=completion,
|
|
133
|
+
conversation_history=[
|
|
134
|
+
{"role": "user", "content": "What is diabetes?"},
|
|
135
|
+
{"role": "assistant", "content": "Diabetes is a chronic condition..."},
|
|
136
|
+
{"role": "user", "content": "What are the symptoms?"},
|
|
137
|
+
],
|
|
138
|
+
session_id="conv-123",
|
|
139
|
+
)
|
|
140
|
+
```
|
|
107
141
|
|
|
108
142
|
| Parameter | Type | Required | Description |
|
|
109
143
|
|-----------|------|----------|-------------|
|
|
@@ -320,7 +354,7 @@ result = client.submit_response(
|
|
|
320
354
|
| `workflow_history[].content` | `str` | Message content |
|
|
321
355
|
| `retrieval_query` | `str` (optional) | The rewritten query sent to the retriever |
|
|
322
356
|
|
|
323
|
-
See [Context-Aware RAG Evaluation](../../docs/concepts/context-aware-rag-evaluation.md) for the full concept doc with architecture diagrams and integration examples.
|
|
357
|
+
See [Context-Aware RAG Evaluation](../../docs/concepts/LLM%20Evaluation/context-aware-rag-evaluation.md) for the full concept doc with architecture diagrams and integration examples.
|
|
324
358
|
|
|
325
359
|
#### Integration with LangGraph / FastAPI streaming
|
|
326
360
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "variably-sdk"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.7.1"
|
|
8
8
|
description = "Official Python SDK for Variably feature flags, LLM experimentation, and prompt optimization platform"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.7"
|
|
@@ -464,16 +464,26 @@ class VariablyClient:
|
|
|
464
464
|
experiment_key, dict(user_context), input_variables
|
|
465
465
|
)
|
|
466
466
|
|
|
467
|
+
# API returns nested structure: {"experiment": {...}, "selected_variant": {...}}
|
|
468
|
+
experiment = response.get("experiment", {})
|
|
469
|
+
variant = response.get("selected_variant", {})
|
|
470
|
+
params = variant.get("parameters", {})
|
|
471
|
+
|
|
472
|
+
# Extract model/provider from nested parameters.llmConfig
|
|
473
|
+
llm_config = params.get("llmConfig", params)
|
|
474
|
+
model = llm_config.get("model", "")
|
|
475
|
+
provider = llm_config.get("provider", "")
|
|
476
|
+
|
|
467
477
|
return PromptVariant(
|
|
468
|
-
experiment_id=
|
|
469
|
-
experiment_key=
|
|
470
|
-
variant_id=
|
|
471
|
-
variant_key=
|
|
472
|
-
prompt_template=
|
|
473
|
-
model=
|
|
474
|
-
provider=
|
|
475
|
-
parameters=
|
|
476
|
-
is_control=
|
|
478
|
+
experiment_id=experiment.get("experiment_id", experiment.get("id", "")),
|
|
479
|
+
experiment_key=experiment_key,
|
|
480
|
+
variant_id=variant.get("variant_id", variant.get("id", "")),
|
|
481
|
+
variant_key=variant.get("variant_key", variant.get("name", "")),
|
|
482
|
+
prompt_template=variant.get("prompt_template", variant.get("prompt", "")),
|
|
483
|
+
model=model,
|
|
484
|
+
provider=provider,
|
|
485
|
+
parameters=params,
|
|
486
|
+
is_control=variant.get("is_control", variant.get("isControl", False)),
|
|
477
487
|
)
|
|
478
488
|
|
|
479
489
|
def evaluate_prompt(
|
|
@@ -576,7 +586,8 @@ class VariablyClient:
|
|
|
576
586
|
"response": response,
|
|
577
587
|
}
|
|
578
588
|
if user_context:
|
|
579
|
-
|
|
589
|
+
# Convert snake_case keys to camelCase for the Go backend
|
|
590
|
+
data["user_context"] = self.http_client._convert_user_context(dict(user_context))
|
|
580
591
|
if input_variables:
|
|
581
592
|
data["input_variables"] = input_variables
|
|
582
593
|
if provider:
|
|
@@ -601,41 +612,49 @@ class VariablyClient:
|
|
|
601
612
|
prompt: Union[str, List[Dict[str, Any]]],
|
|
602
613
|
response: str,
|
|
603
614
|
*,
|
|
604
|
-
|
|
605
|
-
reference_materials: Optional[List[Dict[str, Any]]] = None,
|
|
606
|
-
retrieval_query: Optional[str] = None,
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
615
|
+
# RAG / Grounding context
|
|
616
|
+
reference_materials: Optional[List[Dict[str, Any]]] = None, # Retrieved docs for grounding scoring
|
|
617
|
+
retrieval_query: Optional[str] = None, # The actual search query (if rewritten/expanded)
|
|
618
|
+
# Multi-turn / Session context
|
|
619
|
+
session_id: Optional[str] = None, # Groups conversation turns into sessions
|
|
620
|
+
conversation_history: Optional[List[Dict[str, Any]]] = None, # Prior turns for coherence scoring
|
|
621
|
+
# User & organization context
|
|
622
|
+
user_id: Optional[str] = None, # End-user ID for per-user analytics
|
|
623
|
+
tags: Optional[List[str]] = None, # Grouping labels, e.g. ["production", "rag"]
|
|
624
|
+
metadata: Optional[Dict[str, Any]] = None, # Arbitrary key-value data
|
|
625
|
+
# LLM metadata
|
|
626
|
+
provider: Optional[str] = None, # e.g. "openai", "anthropic"
|
|
627
|
+
model: Optional[str] = None, # e.g. "gpt-4o", "claude-3.5-sonnet"
|
|
628
|
+
latency_ms: Optional[int] = None, # Response time in ms
|
|
629
|
+
prompt_tokens: Optional[int] = None, # Input token count
|
|
630
|
+
completion_tokens: Optional[int] = None, # Output token count
|
|
631
|
+
cost: Optional[float] = None, # Cost in USD
|
|
617
632
|
) -> LogResult:
|
|
618
|
-
"""Log a prompt/response pair for
|
|
633
|
+
"""Log a prompt/response pair for multi-dimensional evaluation (Observe Mode).
|
|
619
634
|
|
|
620
635
|
Zero-friction entry point — no experiment creation needed. Just log your
|
|
621
636
|
prompts and responses and see quality scores in the dashboard.
|
|
622
637
|
|
|
623
638
|
Args:
|
|
624
|
-
prompt: The
|
|
625
|
-
response: The
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
retrieval_query: The query sent to
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
639
|
+
prompt: The user's input / question (str or messages list).
|
|
640
|
+
response: The AI's generated response text.
|
|
641
|
+
reference_materials: Retrieved docs (RAG chunks) for grounding scoring.
|
|
642
|
+
Enables: faithfulness, hallucination rate, attribution accuracy.
|
|
643
|
+
retrieval_query: The query sent to your retriever/search.
|
|
644
|
+
If your pipeline rewrites queries, pass the rewritten version.
|
|
645
|
+
session_id: Conversation/thread ID — groups turns into sessions.
|
|
646
|
+
conversation_history: Prior turns for coherence scoring.
|
|
647
|
+
Each dict: {"role": "user"/"assistant", "content": "..."}.
|
|
648
|
+
Not needed if session_id is provided (auto-built from stored turns).
|
|
649
|
+
user_id: End-user ID for per-user quality analytics.
|
|
650
|
+
tags: Grouping labels for filtering (e.g. ["production", "chatbot"]).
|
|
651
|
+
metadata: Arbitrary key-value data attached to this evaluation.
|
|
632
652
|
provider: LLM provider name (e.g. "openai", "anthropic").
|
|
633
|
-
model: Model name (e.g. "gpt-
|
|
653
|
+
model: Model name (e.g. "gpt-4o", "claude-3.5-sonnet").
|
|
634
654
|
latency_ms: LLM call latency in milliseconds.
|
|
635
655
|
prompt_tokens: Number of input tokens.
|
|
636
656
|
completion_tokens: Number of output tokens.
|
|
637
657
|
cost: Cost in USD for this LLM call.
|
|
638
|
-
metadata: Arbitrary key-value metadata.
|
|
639
658
|
|
|
640
659
|
Returns:
|
|
641
660
|
LogResult with observation_id and status.
|
|
@@ -142,58 +142,85 @@ def observe(
|
|
|
142
142
|
prompt: str,
|
|
143
143
|
response: str,
|
|
144
144
|
*,
|
|
145
|
-
# Auto-extraction
|
|
145
|
+
# --- Auto-extraction ---
|
|
146
|
+
# Pass the raw LLM response object (OpenAI, Anthropic, Google).
|
|
147
|
+
# Model name, token counts, and provider are auto-detected — no manual setup needed.
|
|
146
148
|
provider_response: Any = None,
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
#
|
|
155
|
-
|
|
149
|
+
|
|
150
|
+
# --- LLM metadata (manual overrides — take precedence over auto-extracted values) ---
|
|
151
|
+
model: Optional[str] = None, # e.g. "gpt-4o", "claude-3.5-sonnet"
|
|
152
|
+
provider: Optional[str] = None, # e.g. "openai", "anthropic", "google"
|
|
153
|
+
latency_ms: Optional[int] = None, # Response time in milliseconds
|
|
154
|
+
prompt_tokens: Optional[int] = None, # Input token count
|
|
155
|
+
completion_tokens: Optional[int] = None, # Output token count
|
|
156
|
+
cost: Optional[float] = None, # Cost in USD for this LLM call
|
|
157
|
+
|
|
158
|
+
# --- RAG / Grounding context ---
|
|
159
|
+
# Pass your retrieved documents to enable grounding scoring:
|
|
160
|
+
# faithfulness, hallucination rate, attribution accuracy, context utilization.
|
|
161
|
+
reference_materials: Optional[List[Dict[str, Any]]] = None, # [{"id": "chunk-1", "content": "...", "source": "docs.pdf"}]
|
|
162
|
+
# If your pipeline rewrites/expands queries before search, pass the actual search query here.
|
|
163
|
+
# Enables retrieval relevance scoring. If not provided, the raw prompt is used.
|
|
156
164
|
retrieval_query: Optional[str] = None,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
#
|
|
160
|
-
|
|
161
|
-
|
|
165
|
+
|
|
166
|
+
# --- Multi-turn / Session context ---
|
|
167
|
+
# Groups conversation turns into sessions. Enables session-level metrics,
|
|
168
|
+
# quality trend tracking, and automatic coherence scoring across turns.
|
|
169
|
+
# Use your conversation/thread ID — any unique string per conversation.
|
|
162
170
|
session_id: Optional[str] = None,
|
|
163
|
-
|
|
171
|
+
# Explicit prior turns for coherence scoring. Each dict: {"role": "user"/"assistant", "content": "..."}.
|
|
172
|
+
# Advanced: not needed if you pass session_id (variA/Bly auto-builds history from previous turns).
|
|
173
|
+
prior_turns: Optional[List[Dict[str, str]]] = None,
|
|
174
|
+
|
|
175
|
+
# --- User & organization context ---
|
|
176
|
+
user_id: Optional[str] = None, # Your end-user's ID — enables per-user analytics
|
|
177
|
+
tags: Optional[List[str]] = None, # Grouping labels, e.g. ["production", "rag", "v2"]
|
|
178
|
+
metadata: Optional[Dict[str, Any]] = None, # Any arbitrary key-value data for filtering
|
|
179
|
+
|
|
180
|
+
# --- Backward compatibility ---
|
|
181
|
+
conversation_history: Optional[List[Dict[str, str]]] = None, # Deprecated: use prior_turns instead
|
|
164
182
|
) -> Optional[Dict[str, Any]]:
|
|
165
|
-
"""Log a prompt/response pair to
|
|
183
|
+
"""Log a prompt/response pair to variA/Bly for multi-dimensional evaluation.
|
|
184
|
+
|
|
185
|
+
Add this one call after your LLM generates a response. All parameters are
|
|
186
|
+
optional except ``prompt`` and ``response``. The more context you provide,
|
|
187
|
+
the deeper the evaluation.
|
|
166
188
|
|
|
167
189
|
Never raises. Returns ``{"observation_id": "...", "status": "queued"}``
|
|
168
190
|
on success, or ``None`` on any error (missing API key, network failure, etc.).
|
|
169
191
|
|
|
170
192
|
Args:
|
|
171
|
-
prompt: The user's input / question
|
|
172
|
-
response: The
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
provider: Provider override (e.g. ``"openai"``).
|
|
179
|
-
Takes precedence over auto-detected value.
|
|
193
|
+
prompt: The user's input / question — exactly what the user typed.
|
|
194
|
+
response: The AI's generated response text.
|
|
195
|
+
|
|
196
|
+
provider_response: Raw LLM response object (OpenAI, Anthropic, Google).
|
|
197
|
+
Auto-extracts model name, token counts, and provider via duck typing.
|
|
198
|
+
|
|
199
|
+
model: Model name override (e.g. ``"gpt-4o"``). Overrides auto-extracted value.
|
|
200
|
+
provider: Provider override (e.g. ``"openai"``). Overrides auto-detected value.
|
|
180
201
|
latency_ms: Response generation time in milliseconds.
|
|
181
|
-
prompt_tokens: Input token count
|
|
182
|
-
|
|
183
|
-
completion_tokens: Output token count override.
|
|
184
|
-
Takes precedence over auto-extracted value.
|
|
202
|
+
prompt_tokens: Input token count. Overrides auto-extracted value.
|
|
203
|
+
completion_tokens: Output token count. Overrides auto-extracted value.
|
|
185
204
|
cost: Cost in USD for this LLM call.
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
205
|
+
|
|
206
|
+
reference_materials: Retrieved documents (RAG chunks) for grounding scoring.
|
|
207
|
+
Enables: faithfulness, hallucination rate, attribution accuracy.
|
|
208
|
+
Each dict should have ``"id"``, ``"content"``, and optionally ``"source"``.
|
|
209
|
+
retrieval_query: The query your pipeline sent to the retriever/search.
|
|
210
|
+
If your pipeline rewrites queries before search, pass the rewritten version.
|
|
211
|
+
Enables accurate retrieval relevance scoring.
|
|
212
|
+
|
|
213
|
+
session_id: Conversation/thread ID — groups multi-turn interactions into sessions.
|
|
214
|
+
Enables: session tracing, quality trends, degradation detection, auto-coherence.
|
|
215
|
+
prior_turns: Explicit prior conversation turns for coherence scoring.
|
|
216
|
+
Each dict: ``{"role": "user"/"assistant", "content": "..."}``.
|
|
217
|
+
Not needed if you pass ``session_id`` (history is auto-built from stored turns).
|
|
218
|
+
|
|
219
|
+
user_id: Your end-user's ID for per-user quality analytics.
|
|
220
|
+
tags: Grouping labels for filtering (e.g. ``["production", "rag"]``).
|
|
221
|
+
metadata: Arbitrary key-value data attached to this evaluation.
|
|
222
|
+
|
|
223
|
+
conversation_history: Deprecated — use ``prior_turns`` instead.
|
|
197
224
|
|
|
198
225
|
Returns:
|
|
199
226
|
Dict with ``observation_id`` and ``status`` on success, or ``None``.
|
|
@@ -217,6 +244,9 @@ def observe(
|
|
|
217
244
|
else auto.get("completion_tokens")
|
|
218
245
|
)
|
|
219
246
|
|
|
247
|
+
# Resolve prior_turns: prefer prior_turns, fall back to deprecated conversation_history
|
|
248
|
+
resolved_prior_turns = prior_turns or conversation_history
|
|
249
|
+
|
|
220
250
|
result = client.log(
|
|
221
251
|
prompt=prompt,
|
|
222
252
|
response=response,
|
|
@@ -228,7 +258,7 @@ def observe(
|
|
|
228
258
|
cost=cost,
|
|
229
259
|
reference_materials=reference_materials,
|
|
230
260
|
retrieval_query=retrieval_query,
|
|
231
|
-
conversation_history=conversation_history
|
|
261
|
+
conversation_history=resolved_prior_turns, # client.log still uses conversation_history internally
|
|
232
262
|
tags=tags,
|
|
233
263
|
user_id=user_id,
|
|
234
264
|
session_id=session_id,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: variably-sdk
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.1
|
|
4
4
|
Summary: Official Python SDK for Variably feature flags, LLM experimentation, and prompt optimization platform
|
|
5
5
|
Author: Variably
|
|
6
6
|
Author-email: Variably <support@variably.com>
|
|
@@ -53,6 +53,11 @@ Official Python SDK for Variably — LLM evaluation, experimentation, and prompt
|
|
|
53
53
|
pip install variably-sdk
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
For Docker/Kubernetes deployments, add to your `requirements.txt`:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
variably-sdk>=2.6.1
|
|
60
|
+
```
|
|
56
61
|
## Quick Start — Observe Mode
|
|
57
62
|
|
|
58
63
|
Add **one line** to your existing LLM app and get **multi-dimension evaluation** across 40+ metrics in 6 categories: Quality, Safety, Semantic, Grounding, Coherence, and Advanced.
|
|
@@ -148,7 +153,36 @@ observe(
|
|
|
148
153
|
)
|
|
149
154
|
```
|
|
150
155
|
|
|
151
|
-
###
|
|
156
|
+
### RAG applications — grounding & hallucination scoring
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
observe(
|
|
160
|
+
prompt=user_query,
|
|
161
|
+
response=llm_answer,
|
|
162
|
+
provider_response=completion,
|
|
163
|
+
reference_materials=[
|
|
164
|
+
{"id": "chunk-1", "content": "Retrieved text...", "source": "docs.pdf"},
|
|
165
|
+
{"id": "chunk-2", "content": "Another chunk...", "source": "faq.md"},
|
|
166
|
+
],
|
|
167
|
+
retrieval_query=user_query,
|
|
168
|
+
)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Multi-turn chat — coherence scoring
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
observe(
|
|
175
|
+
prompt=latest_user_message,
|
|
176
|
+
response=llm_answer,
|
|
177
|
+
provider_response=completion,
|
|
178
|
+
conversation_history=[
|
|
179
|
+
{"role": "user", "content": "What is diabetes?"},
|
|
180
|
+
{"role": "assistant", "content": "Diabetes is a chronic condition..."},
|
|
181
|
+
{"role": "user", "content": "What are the symptoms?"},
|
|
182
|
+
],
|
|
183
|
+
session_id="conv-123",
|
|
184
|
+
)
|
|
185
|
+
```
|
|
152
186
|
|
|
153
187
|
| Parameter | Type | Required | Description |
|
|
154
188
|
|-----------|------|----------|-------------|
|
|
@@ -365,7 +399,7 @@ result = client.submit_response(
|
|
|
365
399
|
| `workflow_history[].content` | `str` | Message content |
|
|
366
400
|
| `retrieval_query` | `str` (optional) | The rewritten query sent to the retriever |
|
|
367
401
|
|
|
368
|
-
See [Context-Aware RAG Evaluation](../../docs/concepts/context-aware-rag-evaluation.md) for the full concept doc with architecture diagrams and integration examples.
|
|
402
|
+
See [Context-Aware RAG Evaluation](../../docs/concepts/LLM%20Evaluation/context-aware-rag-evaluation.md) for the full concept doc with architecture diagrams and integration examples.
|
|
369
403
|
|
|
370
404
|
#### Integration with LangGraph / FastAPI streaming
|
|
371
405
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|