Skip to main content

自定义 JavaScript

要创建自定义 API 提供者,请在单独的模块中实现 ApiProvider 接口。以下是该接口的定义:

export interface CallApiContextParams {
vars: Record<string, string | object>;
prompt: Prompt;
// 当在测试用例中覆盖提供者时使用。
originalProvider?: ApiProvider;
logger?: winston.Logger;
}

export interface CallApiOptionsParams {
// 是否在 API 响应中包含 logprobs(用于 OpenAI 提供者)
includeLogProbs?: boolean;
}

export interface ApiProvider {
constructor(options: { id?: string; config: Record<string, any> });

// 提供者的唯一标识符
id: () => string;

// 文本生成函数
callApi: (
prompt: string,
context?: CallApiContextParams,
options?: CallApiOptionsParams,
) => Promise<ProviderResponse>;

// 嵌入函数
callEmbeddingApi?: (prompt: string) => Promise<ProviderEmbeddingResponse>;

// 分类函数
callClassificationApi?: (prompt: string) => Promise<ProviderClassificationResponse>;

// 在输出 UI 中显示
label?: ProviderLabel;

// 评估器在提供者响应上应用的转换
transform?: string;

// 提供者的自定义延迟
delay?: number;

// 提供者配置
config?: any;
}

export interface ProviderResponse {
cached?: boolean;
cost?: number;
error?: string;
logProbs?: number[];
metadata?: Record<string, any>;
output?: string | any;
tokenUsage?: TokenUsage;
}

另请参阅:ProviderResponse

示例

以下是一个自定义 API 提供者的示例,它返回预定义的输出以及令牌使用情况:

import fetch from 'node-fetch';

class CustomApiProvider {
constructor(options) {
// 提供者 ID 可以通过配置文件覆盖(例如在使用多个相同提供者时)
this.providerId = options.id || 'custom provider';

// options.config 包含传递给提供者的任何自定义选项
this.config = options.config;
}

id() {
return this.providerId;
}

async callApi(prompt, context) {
// 在此处添加您的自定义 API 逻辑
// 使用选项,例如:`this.config.temperature`、`this.config.max_tokens` 等。

console.log('此测试用例的变量:', JSON.stringify(context.vars));

return {
// 必需
output: '模型输出',

// 可选
tokenUsage: {
total: 10,
prompt: 5,
completion: 5,
},
};
}
}

module.exports = CustomApiProvider;

自定义 API 提供者还可以用于嵌入、分类、相似性或审核。

module.exports = class CustomApiProvider {
constructor(options) {
this.providerId = options.id || 'custom provider';
this.config = options.config;
}

id() {
return this.providerId;
}

// 嵌入
async callEmbeddingApi(prompt) {
// 在此处添加您的自定义嵌入逻辑
return {
embedding: [], // 您的嵌入数组
tokenUsage: { total: 10, prompt: 1, completion: 0 },
};
}

// 分类
async callClassificationApi(prompt) {
// 在此处添加您的自定义分类逻辑
return {
classification: {
classA: 0.6,
classB: 0.4,
},
};
}

// 相似性
async callSimilarityApi(reference, input) {
// 在此处添加您的自定义相似性逻辑
return {
similarity: 0.85,
tokenUsage: { total: 10, prompt: 5, completion: 5 },
};
}

// 审核
async callModerationApi(prompt, response) {
// 在此处添加您的自定义审核逻辑
return {
flags: [
{
code: 'inappropriate',
description: '潜在的不适当内容',
confidence: 0.7,
},
],
};
}
};

缓存

您可以通过导入 promptfoo.cache 模块与 promptfoo 的缓存进行交互。例如:

const promptfoo = require('../../dist/src/index.js').default;

const cache = promptfoo.cache.getCache();
await cache.set('foo', 'bar');
console.log(await cache.get('foo')); // "bar"

缓存由 cache-manager 管理。

promptfoo 还内置了用于带缓存和超时获取的实用函数:

const { data, cached } = await promptfoo.cache.fetchWithCache(
'https://api.openai.com/v1/chat/completions',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
},
body: JSON.stringify(body),
},
10_000, // 10 秒超时
);

console.log('从 OpenAI 获取的数据:', data);
console.log('是否从缓存中获取?', cached);

使用提供者

在 promptfoo 配置中包含自定义提供者:

providers:
- 'file://relative/path/to/customApiProvider.js'

或者,您可以直接在 CLI 中传递自定义 API 提供者的路径:

promptfoo eval -p prompt1.txt prompt2.txt -o results.csv -v vars.csv -r ./customApiProvider.js

此命令将使用自定义API提供程序评估提示,并将结果保存到指定的CSV文件中。

自定义提供程序自定义提供程序嵌入的完整工作示例可在示例目录中找到。

同一提供程序的多个实例

您可以使用不同的ID实例化同一类型的多个提供程序。在此示例中,我们向提供程序传递不同的温度配置:

providers:
- id: file:///absolute/path/to/customProvider.js
label: custom-provider-hightemp
config:
temperature: 1.0
- id: file:///absolute/path/to/customProvider.js
label: custom-provider-lowtemp
config:
temperature: 0

ES模块

支持ES模块,但必须具有.mjs文件扩展名。或者,如果您正在转译Javascript或Typescript,我们建议将promptfoo指向转译后的普通Javascript输出。

环境变量覆盖

自定义提供程序可以通过EnvOverrides类型访问环境变量。这允许您覆盖默认的API端点、密钥和其他配置选项。以下是可用覆盖的部分列表:

export type EnvOverrides = {
OPENAI_API_KEY?: string;
ANTHROPIC_API_KEY?: string;
AZURE_OPENAI_API_KEY?: string;
COHERE_API_KEY?: string;
// ... 以及其他更多
};

您可以通过options.config.env对象在自定义提供程序中访问这些覆盖。