自定义 Python
python
提供程序允许你使用 Python 脚本作为评估提示的 API 提供程序。当你有自定义逻辑或用 Python 实现的模型,并希望将其集成到测试套件中时,这非常有用。
配置
要配置 Python 提供程序,你需要指定 Python 脚本的路径以及要传递给脚本的任何附加选项。以下是一个 YAML 格式的配置示例:
providers:
- id: 'file://my_script.py'
label: '测试脚本 1' # 此提供程序的可选显示标签
config:
additionalOption: 123
Python 脚本
你的 Python 脚本应实现一个函数,该函数接受提示、选项和上下文作为参数。它应返回一个 JSON 编码的 ProviderResponse
。
ProviderResponse
必须包含一个包含 API 调用结果的output
字段。- 可选地,如果出现问题,它可以包含一个
error
字段,以及一个用于报告使用的令牌数量的tokenUsage
字段。 - 默认情况下,支持的函数是
call_api
、call_embedding_api
和call_classification_api
。要覆盖函数名称,请按如下方式指定脚本:file://my_script.py:function_name
以下是一个可以与 Python 提供程序一起使用的 Python 脚本示例,其中包括对提示、选项和上下文的处理:
# my_script.py
import json
def call_api(prompt: str, options: Dict[str, Any], context: Dict[str, Any]) -> ProviderResponse:
# 注意:提示可能是 JSON 格式的,因此你可能需要解析它。
# 例如,如果提示是一个表示对话的 JSON 字符串:
# prompt = '[{"role": "user", "content": "Hello, world!"}]'
# 你可以这样解析它:
# prompt = json.loads(prompt)
# 'options' 参数包含 API 调用的附加配置。
config = options.get('config', None)
additional_option = config.get('additionalOption', None)
# 'context' 参数提供有关哪些变量用于创建最终提示的信息。
user_variable = context['vars'].get('userVariable', None)
# 提示是处理完变量后的最终提示字符串。
# 自定义逻辑来处理提示在这里。
# 例如,你可能调用外部 API 或运行一些计算。
# TODO: 替换为实际的 LLM API 实现。
def call_llm(prompt):
return f"Stub response for prompt: {prompt}"
output = call_llm(prompt)
# 结果应是一个至少包含 'output' 字段的字典。
result = {
"output": output,
}
if some_error_condition:
result['error'] = "处理过程中发生错误"
if token_usage_calculated:
# 如果你想报告令牌使用情况,可以设置 'tokenUsage' 字段。
result['tokenUsage'] = {"total": token_count, "prompt": prompt_token_count, "completion": completion_token_count}
return result
def call_embedding_api(prompt: str) -> ProviderEmbeddingResponse:
# 返回 ProviderEmbeddingResponse
pass
def call_classification_api(prompt: str) -> ProviderClassificationResponse:
# 返回 ProviderClassificationResponse
pass
类型
传递给 Python 脚本函数和 ProviderResponse
返回类型的类型定义如下:
class ProviderOptions:
id: Optional[str]
config: Optional[Dict[str, Any]]
class CallApiContextParams:
vars: Dict[str, str]
class TokenUsage:
total: int
prompt: int
completion: int
class ProviderResponse:
output: Optional[Union[str, Dict[str, Any]]]
error: Optional[str]
tokenUsage: Optional[TokenUsage]
cost: Optional[float]
cached: Optional[bool]
logProbs: Optional[List[float]]
class ProviderEmbeddingResponse:
embedding: List[float]
tokenUsage: Optional[TokenUsage]
cached: Optional[bool]
class ProviderClassificationResponse:
classification: Dict[str, Any]
tokenUsage: Optional[TokenUsage]
cached: Optional[bool]
设置 Python 可执行文件
在某些情况下,你可能需要指定自定义的 Python 可执行文件。这在使用虚拟环境或默认 Python 路径未指向所需 Python 解释器时特别有用。
以下是如何使用 pythonExecutable
选项覆盖 Python 可执行文件的示例:
providers:
- id: 'file://my_script.py'
config:
pythonExecutable: /path/to/python3.11
故障排除
查看 Python 输出
如果你在 Python 脚本中使用 print
语句,请设置 LOG_LEVEL=debug
以查看脚本调用和输出:
LOG_LEVEL=debug npx promptfoo@latest eval
设置 Python 二进制路径
如果你使用特定的 Python 二进制文件(例如来自虚拟环境或 poetry),请将 PROMPTFOO_PYTHON
环境变量设置为二进制文件的位置。
还要注意,promptfoo 会尊重 PYTHONPATH
。你可以利用这一点来告诉 Python 解释器你的自定义模块所在的位置。
例如:
PROMPTFOO_PYTHON=venv/bin/python3.9 PYTHONPATH=/usr/lib/foo npx promptfoo@latest eval