Merge pull request #5180 from BerriAI/litellm_allow_controlling_logged_tags_langfuse

[Feat-Proxy+langfuse] LiteLLM-specific Tags on Langfuse - `cache_hit`, `cache_key`
This commit is contained in:
Ishaan Jaff 2024-08-13 13:50:01 -07:00 committed by GitHub
commit b24da18d2d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 77 additions and 25 deletions

View file

@ -278,6 +278,42 @@ curl --location 'http://0.0.0.0:4000/chat/completions' \
}' }'
``` ```
### LiteLLM-specific Tags on Langfuse - `cache_hit`, `cache_key`
Use this if you want to control which LiteLLM-specific fields are logged as tags by the LiteLLM proxy. By default LiteLLM Proxy logs no LiteLLM-specific fields
| LiteLLM specific field | Description | Example Value |
|------------------------|-------------------------------------------------------|------------------------------------------------|
| `cache_hit` | Indicates whether a cache hit occured (True) or not (False) | `true`, `false` |
| `cache_key` | The Cache key used for this request | `d2b758c****`|
| `proxy_base_url` | The base URL for the proxy server, the value of env var `PROXY_BASE_URL` on your server | `https://proxy.example.com`|
| `user_api_key_alias` | An alias for the LiteLLM Virtual Key.| `prod-app1` |
| `user_api_key_user_id` | The unique ID associated with a user's API key. | `user_123`, `user_456` |
| `user_api_key_user_email` | The email associated with a user's API key. | `user@example.com`, `admin@example.com` |
| `user_api_key_team_alias` | An alias for a team associated with an API key. | `team_alpha`, `dev_team` |
**Usage**
Specify `langfuse_default_tags` to control what litellm fields get logged on Langfuse
Example config.yaml
```yaml
model_list:
- model_name: gpt-4
litellm_params:
model: openai/fake
api_key: fake-key
api_base: https://exampleopenaiendpoint-production.up.railway.app/
litellm_settings:
success_callback: ["langfuse"]
# 👇 Key Change
langfuse_default_tags: ["cache_hit", "cache_key", "proxy_base_url", "user_api_key_alias", "user_api_key_user_id", "user_api_key_user_email", "user_api_key_team_alias", "semantic-similarity", "proxy_base_url"]
```
### 🔧 Debugging - Viewing RAW CURL sent from LiteLLM to provider ### 🔧 Debugging - Viewing RAW CURL sent from LiteLLM to provider
Use this when you want to view the RAW curl request sent from LiteLLM to the LLM API Use this when you want to view the RAW curl request sent from LiteLLM to the LLM API

View file

@ -53,18 +53,7 @@ _known_custom_logger_compatible_callbacks: List = list(
get_args(_custom_logger_compatible_callbacks_literal) get_args(_custom_logger_compatible_callbacks_literal)
) )
callbacks: List[Union[Callable, _custom_logger_compatible_callbacks_literal]] = [] callbacks: List[Union[Callable, _custom_logger_compatible_callbacks_literal]] = []
_langfuse_default_tags: Optional[ langfuse_default_tags: Optional[List[str]] = None
List[
Literal[
"user_api_key_alias",
"user_api_key_user_id",
"user_api_key_user_email",
"user_api_key_team_alias",
"semantic-similarity",
"proxy_base_url",
]
]
] = None
_async_input_callback: List[Callable] = ( _async_input_callback: List[Callable] = (
[] []
) # internal variable - async custom callbacks are routed here. ) # internal variable - async custom callbacks are routed here.

View file

@ -181,9 +181,9 @@ class BraintrustLogger(CustomLogger):
# generate langfuse tags - Default Tags sent to Langfuse from LiteLLM Proxy # generate langfuse tags - Default Tags sent to Langfuse from LiteLLM Proxy
if ( if (
litellm._langfuse_default_tags is not None litellm.langfuse_default_tags is not None
and isinstance(litellm._langfuse_default_tags, list) and isinstance(litellm.langfuse_default_tags, list)
and key in litellm._langfuse_default_tags and key in litellm.langfuse_default_tags
): ):
tags.append(f"{key}:{value}") tags.append(f"{key}:{value}")
@ -307,9 +307,9 @@ class BraintrustLogger(CustomLogger):
# generate langfuse tags - Default Tags sent to Langfuse from LiteLLM Proxy # generate langfuse tags - Default Tags sent to Langfuse from LiteLLM Proxy
if ( if (
litellm._langfuse_default_tags is not None litellm.langfuse_default_tags is not None
and isinstance(litellm._langfuse_default_tags, list) and isinstance(litellm.langfuse_default_tags, list)
and key in litellm._langfuse_default_tags and key in litellm.langfuse_default_tags
): ):
tags.append(f"{key}:{value}") tags.append(f"{key}:{value}")

View file

@ -366,12 +366,11 @@ class LangFuseLogger:
clean_metadata = {} clean_metadata = {}
if isinstance(metadata, dict): if isinstance(metadata, dict):
for key, value in metadata.items(): for key, value in metadata.items():
# generate langfuse tags - Default Tags sent to Langfuse from LiteLLM Proxy # generate langfuse tags - Default Tags sent to Langfuse from LiteLLM Proxy
if ( if (
litellm._langfuse_default_tags is not None litellm.langfuse_default_tags is not None
and isinstance(litellm._langfuse_default_tags, list) and isinstance(litellm.langfuse_default_tags, list)
and key in litellm._langfuse_default_tags and key in litellm.langfuse_default_tags
): ):
tags.append(f"{key}:{value}") tags.append(f"{key}:{value}")
@ -386,6 +385,11 @@ class LangFuseLogger:
else: else:
clean_metadata[key] = value clean_metadata[key] = value
# Add default langfuse tags
tags = self.add_default_langfuse_tags(
tags=tags, kwargs=kwargs, metadata=metadata
)
session_id = clean_metadata.pop("session_id", None) session_id = clean_metadata.pop("session_id", None)
trace_name = clean_metadata.pop("trace_name", None) trace_name = clean_metadata.pop("trace_name", None)
trace_id = clean_metadata.pop("trace_id", litellm_call_id) trace_id = clean_metadata.pop("trace_id", litellm_call_id)
@ -468,9 +472,9 @@ class LangFuseLogger:
clean_metadata["litellm_response_cost"] = cost clean_metadata["litellm_response_cost"] = cost
if ( if (
litellm._langfuse_default_tags is not None litellm.langfuse_default_tags is not None
and isinstance(litellm._langfuse_default_tags, list) and isinstance(litellm.langfuse_default_tags, list)
and "proxy_base_url" in litellm._langfuse_default_tags and "proxy_base_url" in litellm.langfuse_default_tags
): ):
proxy_base_url = os.environ.get("PROXY_BASE_URL", None) proxy_base_url = os.environ.get("PROXY_BASE_URL", None)
if proxy_base_url is not None: if proxy_base_url is not None:
@ -583,6 +587,27 @@ class LangFuseLogger:
verbose_logger.error(f"Langfuse Layer Error - {traceback.format_exc()}") verbose_logger.error(f"Langfuse Layer Error - {traceback.format_exc()}")
return None, None return None, None
def add_default_langfuse_tags(self, tags, kwargs, metadata):
"""
Helper function to add litellm default langfuse tags
- Special LiteLLM tags:
- cache_hit
- cache_key
"""
if litellm.langfuse_default_tags is not None and isinstance(
litellm.langfuse_default_tags, list
):
if "cache_hit" in litellm.langfuse_default_tags:
_cache_hit_value = kwargs.get("cache_hit", False)
tags.append(f"cache_hit:{_cache_hit_value}")
if "cache_key" in litellm.langfuse_default_tags:
_hidden_params = metadata.get("hidden_params", {}) or {}
_cache_key = _hidden_params.get("cache_key", None)
tags.append(f"cache_key:{_cache_key}")
return tags
def _add_prompt_to_generation_params( def _add_prompt_to_generation_params(
generation_params: dict, clean_metadata: dict generation_params: dict, clean_metadata: dict

View file

@ -40,4 +40,6 @@ general_settings:
litellm_settings: litellm_settings:
fallbacks: [{"gemini-1.5-pro-001": ["gpt-4o"]}] fallbacks: [{"gemini-1.5-pro-001": ["gpt-4o"]}]
success_callback: ["langfuse", "prometheus"] success_callback: ["langfuse", "prometheus"]
langfuse_default_tags: ["cache_hit", "cache_key", "proxy_base_url", "user_api_key_alias", "user_api_key_user_id", "user_api_key_user_email", "user_api_key_team_alias", "semantic-similarity", "proxy_base_url"]
failure_callback: ["prometheus"] failure_callback: ["prometheus"]
cache: True