Source code for langchain_community.callbacks.whylabs_callback

from __future__ import annotations

import logging
from typing import TYPE_CHECKING, Any, Optional

from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.utils import get_from_env, guard_import

if TYPE_CHECKING:
    from whylogs.api.logger.logger import Logger

diagnostic_logger = logging.getLogger(__name__)


[docs]def import_langkit( sentiment: bool = False, toxicity: bool = False, themes: bool = False, ) -> Any: """导入langkit python包,如果未安装则引发错误。 参数: sentiment: 是否导入langkit.sentiment模块。默认为False。 toxicity: 是否导入langkit.toxicity模块。默认为False。 themes: 是否导入langkit.themes模块。默认为False。 返回: 导入的langkit模块。 """ langkit = guard_import("langkit") guard_import("langkit.regexes") guard_import("langkit.textstat") if sentiment: guard_import("langkit.sentiment") if toxicity: guard_import("langkit.toxicity") if themes: guard_import("langkit.themes") return langkit
[docs]class WhyLabsCallbackHandler(BaseCallbackHandler): """用于记录到WhyLabs的回调处理程序。此回调处理程序利用`langkit`从与LLM交互时的提示和响应中提取特征。这些特征可用于隔离、评估和观察随时间发生的交互,以检测与幻觉、提示工程或输出验证相关的问题。LangKit是由WhyLabs开发的LLM监控工具包。 以下是使用LangKit可以监控的一些示例: * 文本质量 - 可读性分数 - 复杂度和年级分数 * 文本相关性 - 提示/响应之间的相似性分数 - 与用户定义主题的相似性分数 - 主题分类 * 安全性和隐私性 - 模式 - 与用户定义的正则表达式模式组匹配的字符串计数 - 越狱 - 与已知越狱尝试相关的相似性分数 - 提示注入 - 与已知提示攻击相关的相似性分数 - 拒绝 - 与已知LLM拒绝响应相关的相似性分数 * 情感和毒性 - 情感分析 - 毒性分析 有关更多信息,请参阅https://docs.whylabs.ai/docs/language-model-monitoring 或查看LangKit存储库:https://github.com/whylabs/langkit --- 参数: api_key(可选[str]):WhyLabs API密钥。可选,因为指定API密钥的首选方式是使用环境变量WHYLABS_API_KEY。 org_id(可选[str]):要将配置文件写入的WhyLabs组织ID。可选,因为指定组织ID的首选方式是使用环境变量WHYLABS_DEFAULT_ORG_ID。 dataset_id(可选[str]):要将配置文件写入的WhyLabs数据集ID。可选,因为指定数据集ID的首选方式是使用环境变量WHYLABS_DEFAULT_DATASET_ID。 sentiment(bool):是否启用情感分析。默认为False。 toxicity(bool):是否启用毒性分析。默认为False。 themes(bool):是否启用主题分析。默认为False。"""
[docs] def __init__(self, logger: Logger, handler: Any): """初始化滚动记录器。""" super().__init__() if hasattr(handler, "init"): handler.init(self) if hasattr(handler, "_get_callbacks"): self._callbacks = handler._get_callbacks() else: self._callbacks = dict() diagnostic_logger.warning("initialized handler without callbacks.") self._logger = logger
[docs] def flush(self) -> None: """如果使用滚动记录器,请明确地写入当前配置文件。""" if self._logger and hasattr(self._logger, "_do_rollover"): self._logger._do_rollover() diagnostic_logger.info("Flushing WhyLabs logger, writing profile...")
[docs] def close(self) -> None: """关闭任何记录器,以便在退出之前写出任何配置文件。""" if self._logger and hasattr(self._logger, "close"): self._logger.close() diagnostic_logger.info("Closing WhyLabs logger, see you next time!")
def __enter__(self) -> WhyLabsCallbackHandler: return self def __exit__( self, exception_type: Any, exception_value: Any, traceback: Any ) -> None: self.close()
[docs] @classmethod def from_params( cls, *, api_key: Optional[str] = None, org_id: Optional[str] = None, dataset_id: Optional[str] = None, sentiment: bool = False, toxicity: bool = False, themes: bool = False, logger: Optional[Logger] = None, ) -> WhyLabsCallbackHandler: """从参数中实例化whylogs Logger。 参数: api_key(可选[str]):WhyLabs API密钥。可选,因为指定API密钥的首选方式是使用环境变量WHYLABS_API_KEY。 org_id(可选[str]):要将配置文件写入的WhyLabs组织ID。如果未设置,则必须在环境变量WHYLABS_DEFAULT_ORG_ID中指定。 dataset_id(可选[str]):此回调正在收集遥测数据的模型或数据集。如果未设置,则必须在环境变量WHYLABS_DEFAULT_DATASET_ID中指定。 sentiment(bool):如果为True,将初始化一个模型以执行情感分析复合分数。默认为False,不会收集此指标。 toxicity(bool):如果为True,将初始化一个模型以评分毒性。默认为False,不会收集此指标。 themes(bool):如果为True,将初始化一个模型以计算到配置主题的距离。默认为None,不会收集此指标。 logger(可选[Logger]):如果指定,将绑定配置的记录器作为遥测收集代理。默认为LangKit模式,带有定期的WhyLabs写入器。 """ # langkit library will import necessary whylogs libraries import_langkit(sentiment=sentiment, toxicity=toxicity, themes=themes) why = guard_import("whylogs") get_callback_instance = guard_import( "langkit.callback_handler" ).get_callback_instance WhyLabsWriter = guard_import("whylogs.api.writer.whylabs").WhyLabsWriter udf_schema = guard_import("whylogs.experimental.core.udf_schema").udf_schema if logger is None: api_key = api_key or get_from_env("api_key", "WHYLABS_API_KEY") org_id = org_id or get_from_env("org_id", "WHYLABS_DEFAULT_ORG_ID") dataset_id = dataset_id or get_from_env( "dataset_id", "WHYLABS_DEFAULT_DATASET_ID" ) whylabs_writer = WhyLabsWriter( api_key=api_key, org_id=org_id, dataset_id=dataset_id ) whylabs_logger = why.logger( mode="rolling", interval=5, when="M", schema=udf_schema() ) whylabs_logger.append_writer(writer=whylabs_writer) else: diagnostic_logger.info("Using passed in whylogs logger {logger}") whylabs_logger = logger callback_handler_cls = get_callback_instance(logger=whylabs_logger, impl=cls) diagnostic_logger.info( "Started whylogs Logger with WhyLabsWriter and initialized LangKit. 📝" ) return callback_handler_cls