关于 CompletionKit
CompletionKit 面向需要测试提示词的团队,可在数据集上运行提示词,并由 LLM 评审员按自定义标准为输出评分。它支持比较不同提示词、模型和参数的运行结果,并依据评审反馈提出改进版本。
主要功能
- 01在数据集上批量运行提示词
- 02按自定义标准进行 LLM 评分
- 03比较提示词、模型和温度设置
- 04基于评审反馈建议提示词改进
- 05提供托管版、自托管版和 Rails 引擎
适用场景
- 01用真实数据评估提示词输出
- 02比较修改前后的提示词评分
- 03将提示词评估嵌入现有 Rails 应用
MCP 相关
提供 MCP 服务,使 MCP 客户端能够通过 CompletionKit 的接口执行提示词评估;README 将 MCP 与 REST API 和网页界面并列为操作方式。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://completionkit.com/mcpclaude mcp add --transport http com-completionkit-evals https://completionkit.com/mcp{"mcpServers":{"com-completionkit-evals":{"type":"http","url":"https://completionkit.com/mcp"}}}在 Cursor 中打开{"servers":{"com-completionkit-evals":{"type":"http","url":"https://completionkit.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"com-completionkit-evals":{"type":"http","url":"https://completionkit.com/mcp"}}}{"mcpServers":{"com-completionkit-evals":{"serverUrl":"https://completionkit.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
https://completionkit.com/mcp需要授权工具
54此工具无需参数。
详细介绍
你的提示词也需要测试。
使用真实数据运行每条提示词。根据你定义的标准,通过大模型评审员为每个输出打分。随意更改任何内容:提示词、模型、温度、数据集。重新运行,准确查看哪些地方有所改善,哪些地方出了问题。当分数告诉你哪里不对劲时,CompletionKit 会根据评审员对你运行结果的实际反馈,建议一条改进后的提示词。你可以检查差异,将其作为新版本应用,然后验证改进效果。
这就是“这条提示词似乎可用”与“这条提示词在 200 个输入上的得分为 4.3 分(满分 5 分),高于上一版本的 3.8 分”之间的区别。
前往 completionkit.com 开始使用 → | RubyGems
只想直接使用? CompletionKit Cloud 使用相同的引擎,完全托管——无需安装,也无需处理 Rails 运维;套餐请访问 completionkit.com/pricing。

三种运行方式
使用相同的引擎、界面、REST API 和 MCP 服务——选择适合你的部署方式。前两种与技术栈无关:你可以将 CompletionKit 作为产品运行,并通过 HTTP 和 MCP 与之交互,而你自己的应用可以使用任何语言编写。第三种适用于已经基于 Rails 构建的团队。
1. 托管版 — completionkit.com(推荐)
最快捷的方式。注册后即可使用与可自托管版本相同的引擎,无需接触 Rails 应用。无需运行 db:migrate,无需 Puma,无需 Solid Queue,也无需管理服务商密钥——多租户工作区,团队成员登录即可使用。套餐请访问 completionkit.com/pricing。
2. 可自托管 — 捆绑的独立应用
在自己的基础设施上将其作为独立产品运行。无需集成,也无需编写 Ruby——应用启动后,无论你自己的应用基于什么技术栈,都可以通过 Web 界面、REST API 和 MCP 服务完成所有操作。它需要 Postgres,以及一台能够运行应用的主机(Fly、Render、Heroku、Docker 等)。
git clone https://github.com/homemade-software-inc/completion-kit.git
cd completion-kit/standalone
bundle install
bin/rails completion_kit:install:migrations
bin/rails db:migrate
同时运行 Web 服务和 Solid Queue 工作进程。在两个终端中分别运行:
bin/rails server
bin/jobs
或者在一个终端中使用 foreman:foreman start -f Procfile.dev。
访问 http://localhost:3000。添加服务商凭据(Settings),创建提示词,上传 CSV 数据集,然后运行。生产环境配置请参阅部署可自托管版本。
3. Rails 引擎 — 挂载到现有的 Rails 应用中
gem "completion-kit"
bin/rails generate completion_kit:install
bin/rails db:migrate
引擎挂载在 /completion_kit。生成 / 评审流程会将 Active Job 任务(CompletionKit::GenerateRowJob、CompletionKit::JudgeReviewJob、CompletionKit::RunCompletionCheckJob)加入队列,因此宿主应用需要使用能够实际处理这些任务的 Active Job 适配器,例如 Solid Queue、Sidekiq、GoodJob 等。:async 适配器不适合用于生产环境:它会在 Web Puma 的线程池中运行任务,既不保证持久性,也不会重试;而且耗时较长的大模型调用会阻塞请求处理。
宿主应用布局集成。 如果宿主应用覆盖了引擎布局(例如在引擎控制器上使用 layout "application",或在自己的外壳中渲染引擎视图),请在该布局中包含引擎的样式表和 JavaScript:
<%= stylesheet_link_tag "completion_kit/application", media: "all" %>
<%= javascript_include_tag "completion_kit/application", defer: true, nonce: true %>
如果不包含 JavaScript,页面内的交互行为会静默失效:可点击的表格行、对话框、复制按钮、API 令牌显示、运行表单、实时运行状态、实时标签面包屑更新、相对时间刷新、CSV 行悬停展开、模型刷新进度、聚焦首个错误,以及本地时间格式化。
内容安全策略。 引擎页面没有内联事件处理程序或内联脚本,而且引擎布局会将请求 nonce 添加到脚本标签中,因此页面可在基于 nonce 的 script-src 策略下正常运行。视图仍使用内联 style 属性,因此暂时不要在 nonce 指令中包含 style-src,并在其中允许 'unsafe-inline'。
使用在整个会话期间有效的 nonce,而不是每个请求都生成新的随机 nonce。Turbo Drive 会在每个新页面主体中重新创建脚本,并使用 csp-nonce 元标签中的 nonce,但浏览器会继续执行其首次加载页面时的策略头,因此每个请求使用不同的 nonce 会导致首次 Drive 访问后 nonce 脚本被阻止。
在会话中保留一个随机 nonce,并像下面的示例一样,对 API 控制器跳过该 nonce,这样不使用 Cookie 的 API 和 MCP 调用就不会获得会话 Cookie。Rails 的默认值 ->(request) { request.session.id.to_s } 也会在整个会话期间有效,但新访客首次收到响应时它为空,因此只允许 nonce 脚本的策略会阻止该页面上的脚本,直到会话建立。
Rails.application.configure do
config.content_security_policy do |policy|
policy.default_src :self
policy.script_src :self
policy.style_src :self, :unsafe_inline
end
config.content_security_policy_nonce_generator = lambda do |request|
next if request.controller_instance.is_a?(ActionController::API)
request.session[:csp_nonce] ||= SecureRandom.base64(16)
end
config.content_security_policy_nonce_directives = %w(script-src)
end
提供商
CompletionKit 会自动从各提供商的 API 发现可用模型。
| 提供商 | 环境变量 | 涵盖内容 |
|---|---|---|
| OpenAI | OPENAI_API_KEY | GPT-5、GPT-4.1、GPT-4o 等 |
| Anthropic | ANTHROPIC_API_KEY | Claude Opus、Sonnet、Haiku |
| Ollama / 本地端点 | OLLAMA_API_ENDPOINT(默认值:http://localhost:11434/v1)、OLLAMA_API_KEY(可选) | 通过 ollama pull 拉取的任何模型,或任何兼容 OpenAI 的本地服务(vLLM、LM Studio、llama.cpp) |
| OpenRouter | OPENROUTER_API_KEY | 通过一个 API 密钥访问来自 30 多家提供商的 100 多个模型 |
| Azure AI Foundry | 无环境变量 — 通过提供商 UI / ProviderCredential 添加(必须填写 api_key 和 api_endpoint,api_version 可选) | Azure OpenAI 部署和 Foundry 项目 |
将这些设为环境变量,或在生成的初始化程序中进行配置。你也可以通过 Web UI 的“设置”添加提供商凭据。
来自 OLLAMA_API_KEY 或 config.ollama_api_key 的 Ollama 密钥只会发送到 OLLAMA_API_ENDPOINT 或 config.ollama_api_endpoint 指定的 Ollama 端点;如果两者均未设置且 config.allow_loopback_endpoints 已启用(默认如此),则发送到 http://localhost:11434/v1。没有自身密钥的提供商凭据,仅当其指向同一端点时才会使用该密钥。若指向其他位置,CompletionKit 不会发送密钥,因此请将密钥保存在凭据本身中。保存在凭据上的密钥始终会发送到该凭据对应的端点。两个端点在协议、主机、端口和路径一致时即视为匹配。协议和主机的大小写、明确写出的默认端口、尾随斜杠以及尾随的 /v1 均不影响匹配。空白的已存储密钥视为未设置密钥。
加密
提供商 API 密钥使用 Active Record 加密进行静态加密。应用在生产环境启动前,必须配置三个加密密钥。
生成密钥:
bin/rails db:encryption:init
然后将它们设为环境变量:
COMPLETION_KIT_ENCRYPTION_PRIMARY_KEY=<generated value>
COMPLETION_KIT_ENCRYPTION_DETERMINISTIC_KEY=<generated value>
COMPLETION_KIT_ENCRYPTION_KEY_DERIVATION_SALT=<generated value>
或者将它们添加到 config/credentials.yml.enc 的 active_record_encryption 下。在开发环境中,独立应用会使用内置的备用值,因此可在本地跳过此步骤。
身份验证
CompletionKit 在任何已部署的环境中都要求进行身份验证。在开发和测试环境中,路由默认开放(并会记录警告日志);在其他所有环境中,如果未配置身份验证,则会返回 403。
基本身份验证(推荐用于简单配置)
CompletionKit.configure do |c|
c.username = "admin"
c.password = ENV["COMPLETION_KIT_PASSWORD"]
end
自定义身份验证(Devise 等)
CompletionKit.configure do |c|
c.auth_strategy = ->(controller) { controller.authenticate_user! }
end
只能启用一种模式。
评审者名称
当有人在 Web UI 中记录对评判者评分的判定时,CompletionKit 会使用评审者名称保存该判定。每位评审者对每个响应和指标只能有一个判定,因此请为每个人设置不同的名称,否则他们的判定会互相覆盖。将 current_reviewer 设为一个可调用对象,该对象接收控制器并返回已登录人员的名称:
CompletionKit.configure do |c|
c.auth_strategy = ->(controller) { controller.authenticate_user! }
c.current_reviewer = ->(controller) { controller.current_user&.email }
end
该可调用对象必须返回 String 或 nil。任何其他值(例如用户记录)都会引发 CompletionKit::ConfigurationError。如果未设置 current_reviewer 或其返回空白值,则判定会以 username 保存;若未设置用户名,则使用 "operator"。Web UI 不会自行读取 X-Remote-User 标头。如果应用前方的代理设置了该标头,请传递该标头:
CompletionKit.configure do |c|
c.current_reviewer = ->(controller) { controller.request.headers["X-Remote-User"] }
end
仅当可信代理始终覆盖此标头时,才使用该标头。否则,任何客户端都可以发送该标头并冒用任意评审者名称。
REST API 和 MCP 服务会从各自的 created_by 参数获取评审者名称。
速率限制
REST API、MCP 端点和 Web UI 都会按 IP 地址进行每分钟速率限制。默认限制较为宽松;可在初始化程序中调整:
CompletionKit.configure do |c|
c.api_rate_limit = 120 # REST API + MCP, requests per minute (default 120)
c.web_rate_limit = 300 # web UI, requests per minute (default 300)
end
限流使用 Rails.cache。共享缓存存储(Solid Cache、Redis)可在多个应用实例间准确限流;每进程缓存存储仍会对每个实例分别限流。
输入限制
上传内容、提示词模板和正则表达式检查模式都有大小限制,避免单个过大或恶意的输入占用工作进程。请在初始化器中调整这些限制:
CompletionKit.configure do |c|
c.max_upload_bytes = 25 * 1024 * 1024 # largest dataset CSV or import file (default 25 MB)
c.max_template_bytes = 1024 * 1024 # largest prompt template (default 1 MB)
c.regex_timeout = 1.0 # seconds a regex check may spend matching one row (default 1.0)
end
模板超过 max_template_bytes 的提示词在保存模板时会验证失败。降低限制前保存的提示词会继续正常工作,直到其模板发生更改。
数据集 CSV 的第一行是标题行。保存 CSV 时,如果标题行为空或超过 64 KB,数据集会验证失败。64 KB 限制是固定的,不是可配置项。
保存 CSV 时,如果其中包含无效的 UTF-8 字节,数据集也会验证失败,因此请将电子表格导出为 UTF-8 CSV。
如果正则表达式检查运行时间超过限制,该行会失败并显示超时。限制取 regex_timeout 与应用的 Regexp.timeout 中较短者,因此引擎不会放宽应用设置的更严格限制。引擎会为每个模式设置限制,绝不会更改进程级的 Regexp.timeout。请将 regex_timeout 设为至少 0.001 秒的有限数值,或设为 nil,仅使用 Regexp.timeout。任何其他值(例如 0 或 Float::INFINITY)都会在初始化器运行时引发 ArgumentError。
工作原理
这是一个循环。每次运行都会得到一个分数,可以与上一次进行比较。
- 创建提示词,其中包含
{{variable}}占位符 - 上传数据集。 一个 CSV 文件,其列标题与变量名称相匹配。
- 运行测试,针对模型运行,并使用 LLM 评审员根据你定义的标准为输出评分。
- 迭代。 更改提示词、模型、温度或数据集,然后重新运行。CompletionKit 会为提示词创建版本,让你随时可以与之前的结果进行比较。
- 获取建议。 分数降低时,可以向 CompletionKit 请求 AI 生成的改进建议。建议基于评审员对每条响应的实际反馈,而非泛泛的提示词工程建议。检查差异,然后将其作为新版本应用。
概念
- 提示词。 带有
{{variable}}占位符的版本化模板。编辑已运行过的提示词会创建新版本,因此之前的结果仍可复现。 - 数据集。 包含真实输入的 CSV 文件。每一行都会成为一个测试用例。
- 运行。 针对数据集执行一次提示词运行。记录每项输入(模型、温度、指标),并保存所有输出和分数。
- 响应。 模型对数据集某一行的输出,附带评审结果。
- 指标。 一个评估维度,包含名称、说明、评估步骤以及 1-5 星评分标准。LLM 评审员会据此为每条响应评分。
- 指标组。 可重复使用的一组指标,可作为一个整体应用于运行。
- 标签。 可添加到提示词、运行、指标和数据集上的领域标签。会从 10 种颜色组成的调色板中自动分配。可以按标签筛选任意索引页(
?tag[]=...)。 - 提供商凭据。 模型提供商的 API 密钥。静态加密,绝不会通过 API 返回。
REST API
每项资源都可通过持有者令牌 JSON API 访问:
CompletionKit.configure { |c| c.api_token = ENV["COMPLETION_KIT_API_TOKEN"] }
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:3000/completion_kit/api/v1/prompts
在运行中的应用访问 /completion_kit/api_reference,查看各端点的文档及可复制的 curl 示例。
MCP 服务
CompletionKit 在 /completion_kit/mcp 提供 Model Context Protocol 服务,将每项资源作为工具公开,供支持 MCP 的客户端(Claude Code、Cursor 等)直接调用:
{
"mcpServers": {
"completion-kit": {
"url": "https://your-app.com/completion_kit/mcp",
"headers": { "Authorization": "Bearer YOUR_TOKEN" }
}
}
}
应用内的 API 参考页面提供安装代码片段,可直接复制到 MCP 客户端配置中。
部署自托管实例
任何兼容 Rails 的托管平台都适用(Fly、Heroku、Render、Docker 等)。通过 DATABASE_URL 指向一个 Postgres 实例,设置提供商环境变量,并在每次部署时运行 cd standalone && bin/rails db:migrate。
| 变量 | 用途 | 默认值 |
|---|---|---|
COMPLETION_KIT_API_TOKEN | REST API 和 MCP 的 Bearer 令牌 | (无,API 已禁用) |
COMPLETION_KIT_USERNAME | Web UI 登录用户名 | admin |
COMPLETION_KIT_PASSWORD | Web UI 登录密码 | (无,开发环境中开放访问) |
你还需要上文 加密 部分中的三个 COMPLETION_KIT_ENCRYPTION_* 密钥。
gem 发布新的迁移时,请在本地安装并提交,然后再推送:
cd standalone
bin/rails completion_kit:install:migrations
bin/rails db:migrate
git add db/migrate/ && git commit -m "install new engine migration"
Docker
独立应用附带 Dockerfile,因此无需在主机上安装 Ruby 工具链即可自托管。请以仓库根目录作为构建上下文 — 应用依赖其旁边的引擎源码:
docker build -f standalone/Dockerfile -t completion-kit .
CompletionKit 需要 Rails 密钥(SECRET_KEY_BASE)和三个 Active Record 加密密钥。使用 Docker 时,主机上没有 Rails 工具链可运行 bin/rails db:encryption:init,因此请使用 openssl 生成这些密钥。只生成一次并妥善保存 — 如果加密密钥发生变化,数据库中已存储的提供商凭据将无法解密。将所有内容写入环境文件:
cat > completion-kit.env <<EOF
DATABASE_URL=postgres://user:pass@host/completionkit
SECRET_KEY_BASE=$(openssl rand -hex 64)
COMPLETION_KIT_ENCRYPTION_PRIMARY_KEY=$(openssl rand -hex 32)
COMPLETION_KIT_ENCRYPTION_DETERMINISTIC_KEY=$(openssl rand -hex 32)
COMPLETION_KIT_ENCRYPTION_KEY_DERIVATION_SALT=$(openssl rand -hex 32)
EOF
写入文件时会运行 openssl rand,因此每一行都会获得真实的随机值。请勿将 completion-kit.env 纳入版本控制,并将其备份到安全的位置。
使用同一镜像运行 Web 进程和作业工作进程,并让两者都指向该文件:
docker run -d -p 3000:3000 --env-file completion-kit.env completion-kit
docker run -d --env-file completion-kit.env completion-kit ./bin/jobs
两个进程必须共享相同的 SECRET_KEY_BASE 和加密密钥 — 单个环境文件可确保这一点。Web 容器会在启动时运行 db:prepare,因此迁移会在首次启动和每次部署时应用。
多租户宿主应用(高级)
对于在多租户应用中挂载 CompletionKit 的宿主,可使用两个可选钩子按租户限定引擎记录,而无需分叉引擎:
CompletionKit.configure do |config|
config.tenant_scope = -> {
org = Current.organization&.id
org ? where(organization_id: org) : where("1=0")
}
config.tenant_scope_columns = [:organization_id]
end
tenant_scope 会作为每个引擎模型的 default_scope 运行(使用 unscoped 可绕过)。tenant_scope_columns 会追加到引擎的每项唯一性验证中。添加租户列和复合唯一索引由宿主的迁移负责。两项默认值(nil、[])均不起作用。completion_kit:mark_interrupted_runs_failed rake 任务会绕过 tenant_scope,并将所有租户中正在运行的任务标记为失败,因此,如果宿主还在数据库中强制执行多租户隔离(例如使用行级安全策略),就必须以能够访问所有租户记录的数据库角色运行该任务。
自定义模型端点和通过 URL 导入的 CSV 默认可能访问服务器自身的环回接口,因此本地 Ollama 开箱即用。如果使用引擎的人员不应访问应用服务器本身的服务,请设置 config.allow_loopback_endpoints = false。私有地址、链路本地地址和保留地址始终会被拒绝。
一个钩子可让宿主在引擎列出、计数或遍历运行时统一应用自身的显示规则,而无需覆盖控制器或视图:
CompletionKit.configure do |config|
config.runs_display_scope = -> { where(created_at: 90.days.ago..) }
config.runs_display_footer_partial = "runs/display_notice"
end
runs_display_scope 是一个针对 Run 关系求值的可调用对象,采用与 tenant_scope 相同的纯 where 风格(它通过 instance_exec 运行,因此应写成零参数形式,并将关系作为 self,类似 Rails scope lambda)。它必须返回一个关系:如果可调用对象返回 nil 或任何不可链式调用的值,列表渲染时就会报错。引擎会通过 Run.display_scoped 将其应用于引擎负责的所有运行列表和计数(运行索引、提示词和数据集展示页、比较选择器、新建运行的标签默认值、v1 API 索引及其 X-Total-Count、MCP runs_list 工具、仪表板和 API 参考页的近期运行面板、仪表板“Runs”统计卡片计数,以及提供商凭据使用统计),并通过 Run.visible_run_ids 应用于遍历运行的子记录(指标页面上的指标信任面板样本和一致性示例)。对于仅适用于列表的显示规则,请使用此钩子,而非全局 default_scope,后者会导致 Run 关联在所有遍历场景中失效。
以下情况有意不受此规则影响,因为它们仍须查看所有运行:通过 ID 查找单个运行(runs#show、MCP runs_get 工具、v1 API show)、删除确认中的级联计数、自动生成的运行名称计数器、仪表板统计卡片的显示条件(它依据未限定范围的运行总数,因此,即使某个工作区的运行全被显示范围排除,也仍会显示活动卡片,而不是空白仪表板),以及评判器少样本数据的播种逻辑,它会从已更正的示例中学习,即使这些示例来自显示范围排除的运行也不例外。
runs_display_footer_partial 用于指定一个局部模板,渲染在仪表板、索引页以及提示词和数据集展示页的运行列表下方;它会收到一个名为 runs 的局部变量,其中包含当前显示的运行。如果显示范围排除了某个页面原本会列出的所有运行,该页面会显示“没有可显示的运行。”,并在其下方渲染页脚局部模板。引擎无法得知范围为何排除这些运行,因此请使用该局部模板解释显示规则:该规则由宿主通过 runs_display_scope 管理,也只有宿主能够说明或统计被排除的内容。两项默认值均为 nil(不起作用),因此不会改变独立运行时的行为。
贡献
有关开发环境设置、测试和拉取请求指南,请参阅 CONTRIBUTING.md。
许可证
CompletionKit 0.3.0 及后续版本采用 Business Source License 1.1 许可。您可以将 CompletionKit 自由用于任何用途,包括生产环境,但不得将其(或其衍生产品)作为托管或管理服务提供给第三方,且该服务的主要价值不得是 CompletionKit 本身。每个版本发布三年后,该版本将自动转为 GPL-3 许可。
CompletionKit 0.2.x 及更早版本仍采用 MIT License 许可。
如需其他许可方式,请联系 [email protected]。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。