Comet Opik
chính thứcTruy vấn và phân tích nhật ký Opik, dấu vết, lời nhắc và tất cả dữ liệu đo từ xa khác từ các LLM của bạn bằng ngôn ngữ tự nhiên.
Bạn có thể làm gì với Comet Opik MCP?
-
Truy vấn trace và dự án — Hỏi "liệt kê các dự án Opik của tôi" hoặc "trace nào trong dự án 'demo' đã thất bại hôm nay?" để duyệt dữ liệu không gian làm việc qua
listvàread. -
Chấm điểm và nhận xét trace — Đính kèm điểm phản hồi dạng số kèm lý do, hoặc thêm bình luận dạng văn bản tự do vào trace, span hoặc luồng.
-
Quản lý phiên bản prompt — Lưu phiên bản prompt mới, tạo prompt theo tên nếu chúng chưa tồn tại.
-
Kiểm tra lược đồ ghi — Dùng
schemađể kiểm tra cấu trúc JSON chính xác, trường bắt buộc và ví dụ đã xác thực trước khi xây dựng bất kỳ thao tác ghi nào. -
Theo dõi tình trạng dự án — Nhận tổng quan 7 ngày với số lượng trace, tỷ lệ lỗi, thời lượng và chi phí, hoặc vẽ biểu đồ số liệu theo thời gian.
-
Phân loại sự cố Diagnostics — Liệt kê các vấn đề insight của agent đang mở, giải quyết hoặc đóng chúng, đồng thời bật hoặc kích hoạt quét.
Tài liệu
Máy chủ MCP Opik
Máy chủ Giao thức Ngữ cảnh Mô hình (MCP) chính thức cho Opik, nền tảng đánh giá và quan sát LLM mã nguồn mở, được xây dựng bởi Comet. Kết nối máy chủ AI của bạn (Claude Code, Cursor, VS Code Copilot, Codex, opencode, hoặc bất kỳ máy khách MCP nào) trực tiếp vào không gian làm việc Opik của bạn: đọc trace, ghi điểm, và lưu các phiên bản prompt, tất cả từ trong chat.
Được xây dựng cho các kỹ sư LLM đã chạy Opik và muốn điều khiển nó từ chính trợ lý AI mà họ dùng để viết mã.
Đang nâng cấp từ
npx opik-mcpcũ? Máy chủ TypeScript đã không còn được hỗ trợ và sẽ ngừng hoạt động vào 2026-11-15. Thaynpx -y opik-mcpbằnguvx opik-mcp@latesttrong cấu hình máy khách MCP của bạn. Hướng dẫn đầy đủ:legacy/typescript/MIGRATION.md.
You: "Which traces in project 'demo' failed today?"
Claude: → list(entity_type="trace", project_name="demo") → "Three traces failed…"
You: "Score trace 7f2e… 0.9 on helpfulness with reason 'great recovery'."
Claude: → write(score.create) → done
Bắt đầu nhanh
Một lệnh duy nhất đăng ký máy chủ với các máy khách AI trên máy của bạn, cài đặt
bộ kỹ năng Opik, và xác minh kết nối. Lệnh này cần uv
và không cần Opik SDK:
uvx opik mcp configure
Lệnh này tự động phát hiện Claude Code, Cursor, VS Code Copilot, Codex và opencode, và sử dụng máy chủ lưu trữ trên Opik Cloud (đăng nhập qua trình duyệt, không lưu khóa API) hoặc máy chủ cục bộ này ở nơi khác. Bất kỳ máy khách MCP nào khác có thể lấy URL lưu trữ trực tiếp:
npx add-mcp https://www.comet.com/opik/api/v1/mcp --name opik-mcp
Hướng dẫn thiết lập, khắc phục sự cố và FAQ: comet.com/docs/opik/mcp-server. Phần còn lại của README này bao gồm máy chủ cục bộ, mà lệnh trên thiết lập cho Opik tự lưu trữ và mã nguồn mở, và bạn cũng có thể cấu hình thủ công.
Cài đặt thủ công
opik-mcp là một gói Python (yêu cầu Python 3.13+). Cách được khuyến nghị để
chạy nó là uvx, lệnh này tìm nạp và chạy phiên bản mới nhất đã phát hành theo yêu cầu —
không cần cài đặt toàn cục, không cần xử lý virtualenv.
Cài đặt uv một lần:
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS / Linux
# or: brew install uv
Bạn sẽ cần hai thứ từ không gian làm việc Opik của mình:
OPIK_API_KEY— lấy từcomet.com/api/my/settings/.OPIK_WORKSPACE— tên không gian làm việc của bạn (chữ thường, như xuất hiện trong URL). Ví dụ:https://www.comet.com/acme-ai/...→OPIK_WORKSPACE=acme-ai.COMET_WORKSPACEđược chấp nhận như một bí danh không còn dùng.
Cloud, với khóa API: hãy đặt nó trừ khi mặc định tài khoản của bạn là cái bạn muốn. Nếu bỏ trống, máy chủ sẽ gửi
default, mà Comet phân giải thành không gian làm việc mặc định của tài khoản bạn. Điều đó hoạt động, nhưng nếu bạn thực sự làm việc trong một không gian làm việc có tên, bạn sẽ bị trỏ đến một không gian khác mà không có gì báo cho bạn — các lần đọc của bạn trả về từ sai nơi thay vì báo lỗi.Cloud, qua OAuth: để trống. Không gian làm việc đến từ token bạn đã ủy quyền, và máy chủ bỏ qua cài đặt này hoàn toàn.
Cục bộ / mã nguồn mở: để trống. Opik mã nguồn mở có một không gian làm việc duy nhất tên
defaultvà không có cách tạo không gian khác, đó chính xác là những gì dự phòng cung cấp cho bạn.Comet tự lưu trữ: hãy đặt nó. Không giống mã nguồn mở, các triển khai này có các không gian làm việc có tên thực sự, và rủi ro sai không gian làm việc thầm lặng tương tự cũng áp dụng.
Dù trường hợp nào, hãy đảm bảo giá trị thực sự được thay thế. Các đoạn mã ngoài kia thường chứa các placeholder như
<your-workspace>hoặc${input:OPIK_WORKSPACE}; nếu dán nguyên trạng, những thứ đó không phải tên không gian làm việc. Máy chủ hiện từ chối chúng thẳng thừng thay vì để backend trả lời bằng lỗi xác thực mà không giải thích gì.
Claude Code
Thêm máy chủ bằng một lệnh:
claude mcp add --transport stdio opik-mcp \
--env OPIK_API_KEY=<your-key> \
--env OPIK_WORKSPACE=<your-workspace> \
-- uvx opik-mcp
Hoặc chỉnh sửa ~/.claude.json trực tiếp:
{
"mcpServers": {
"opik-mcp": {
"type": "stdio",
"command": "uvx",
"args": ["opik-mcp"],
"env": {
"OPIK_API_KEY": "<your-key>",
"OPIK_WORKSPACE": "<your-workspace>"
}
}
}
}
Khởi động lại Claude Code. Xác minh bằng /mcp — opik-mcp sẽ xuất hiện như đã kết nối.
Sau đó, trong chat, hãy hỏi: "liệt kê các dự án Opik của tôi" — Claude sẽ gọi công cụ list
và bạn sẽ thấy các dự án trong không gian làm việc của mình.
Cursor
Chỉnh sửa ~/.cursor/mcp.json (toàn cục) hoặc .cursor/mcp.json (dự án), hoặc mở
Cmd+Shift+J → Features → Model Context Protocol:
{
"mcpServers": {
"opik-mcp": {
"type": "stdio",
"command": "uvx",
"args": ["opik-mcp"],
"env": {
"OPIK_API_KEY": "<your-key>",
"OPIK_WORKSPACE": "<your-workspace>"
}
}
}
}
Tải lại Cursor; chấm xanh bên cạnh opik-mcp trong bảng MCP xác nhận kết nối.
Hỏi trong chat: "liệt kê các dự án Opik của tôi".
Cursor hết thời gian 60 giây. Cursor áp đặt thời gian chờ gọi công cụ cứng mà không đặt lại khi có thông báo tiến trình. Xem Giới hạn máy chủ đã biết.
VS Code Copilot
.vscode/mcp.json trong không gian làm việc của bạn (hoặc User Settings JSON):
{
"servers": {
"opik-mcp": {
"type": "stdio",
"command": "uvx",
"args": ["opik-mcp"],
"env": {
"OPIK_API_KEY": "<your-key>",
"OPIK_WORKSPACE": "<your-workspace>"
}
}
}
}
Tải lại cửa sổ; chỉ báo MCP của Copilot Chat hiển thị opik-mcp khi
máy chủ có thể truy cập. Hỏi trong chat: "liệt kê các dự án Opik của tôi".
MCP Inspector (kiểm thử thủ công)
OPIK_API_KEY=<your-key> OPIK_WORKSPACE=<your-workspace> \
npx @modelcontextprotocol/inspector uvx opik-mcp
Opik tự lưu trữ
Thêm COMET_URL_OVERRIDE (và OPIK_URL nếu Opik nằm ở đường dẫn không mặc định) vào
cùng khối env trong cấu hình máy chủ của bạn:
{
"mcpServers": {
"opik-mcp": {
"type": "stdio",
"command": "uvx",
"args": ["opik-mcp"],
"env": {
"OPIK_API_KEY": "<your-key>",
"OPIK_WORKSPACE": "<your-workspace>",
"COMET_URL_OVERRIDE": "https://opik.your-company.com",
"OPIK_MCP_ANALYTICS_SOURCE": ""
}
}
}
}
Bỏ qua OPIK_WORKSPACE trên triển khai mã nguồn mở, nơi default là không gian làm việc
duy nhất; giữ nó trên Comet tự lưu trữ, nơi có các không gian làm việc có tên thực sự.
Đặt OPIK_MCP_ANALYTICS_SOURCE="" sẽ loại bỏ bản cài đặt của bạn khỏi
nhãn nguồn cloud-Comet trên các sự kiện telemetry.
Công cụ
opik-mcp cung cấp một bề mặt nhỏ, hướng kết quả bao phủ toàn bộ vòng đời
(đọc → chú thích → quản lý → soạn thảo → lặp lại).
| Công cụ | Mục đích |
|---|---|
read | Đọc phổ quát theo id / tên / URI opik:// |
list | Liệt kê phổ quát với bộ lọc tên tùy chọn + phân trang |
write | Ghi phổ quát — ghi trace/span, chấm điểm, bình luận, lưu prompt, quản lý dataset & thí nghiệm |
schema | Kiểm tra nội bộ các lược đồ thao tác ghi (được LLM dùng để xây dựng payload hợp lệ) |
read_skill | Đọc một trong các kỹ năng agent Opik đi kèm với máy chủ này |
read
Một công cụ cho bất kỳ câu hỏi "cho tôi xem X" nào. Nhận một entity_type cùng với một id
(UUID hoặc, đối với các loại có tên, một tên) hoặc một URI opik:// đầy đủ. Các lần đọc tổng hợp
(trace, prompt, thread, agent_insights_issue) nhúng các phần tử con của chúng để
một lần gọi duy nhất trả về bức tranh đầy đủ.
Bản ghi bạn đặt tên trả về nguyên vẹn. Các phần tử con được nhúng thì không: phần thân
của chúng được tìm nạp bằng truncate=true của backend, vì vậy một trường trên ~10 KB bị cắt
trong ClickHouse và các hình ảnh base64 được thay thế bằng "[image]" — một tệp đính kèm
được lặp lại qua 200 span sẽ tốn kém hơn mọi thứ khác trong lần đọc.
Câu trả lời nói rõ điều đó trong spanBodies / messageBodies, và bất kỳ phần tử con nào
lại nguyên vẹn thông qua read("span", id) hoặc read("trace", trace_id) của chính nó,
các lệnh này truy cập các endpoint không có tham số truncate nào cả.
Một bộ sưu tập được nhúng cũng bị giới hạn độ dài: 200 span, 200 lượt, 100
phiên bản prompt. Vượt quá giới hạn đó, spansTruncated / messagesTruncated /
versionsTruncated là true và một dòng moreSpans / moreMessages /
moreVersions bên cạnh nó mang số lượng và lệnh gọi list(...) chính xác
tiếp tục từ nơi phần được nhúng dừng lại.
Các thực thể được hỗ trợ: project, trace, span, dataset, dataset_item,
experiment, prompt, thread, agent_insights_issue. Tra cứu theo tên có sẵn
cho project, experiment, prompt, dataset (chậm hơn — hai lần gọi API
— và có thể trả về nhiều kết quả khớp). thread và agent_insights_issue
có phạm vi dự án: truyền project_id hoặc project_name, hoặc một liên kết/URI mang
dự án. dataset và dataset_item trước đây được gọi là test_suite và
test_suite_item; các tên cũ vẫn phân giải được, nhưng chúng không được
quảng bá và mã mới nên dùng các tên mới.
read(entity_type="trace", id="7f2e3c8a-…")
read(entity_type="project", id="demo") # name lookup
read(entity_type="trace", id="opik://traces/7f2e3c8a-…")
read(entity_type="agent_insights_issue", id="<issue-uuid>", project_id="<project-uuid>")
read(
entity_type="agent_insights_issue",
id="https://www.comet.com/opik/<ws>/projects/<pid>/diagnostics?issue=<id>",
)
Một liên kết sao chép từ giao diện Opik hoạt động như id: một liên kết thread hoặc một
liên kết trang Chẩn đoán mang dự án, vì vậy không cần project_id và
loại thực thể được lấy từ liên kết.
Một lần đọc project trả lời "dự án của tôi đang hoạt động thế nào" trong một lần gọi. Nó trả về
{project, summary, vocabulary, contains, url}: bản ghi, sau đó là bốn
con số mà trang Nhật ký hiển thị dưới dạng thẻ (số trace, tỷ lệ lỗi, thời lượng
trung bình, tổng chi phí) trong 7 ngày qua so với 7 ngày trước đó, chỉ lưu lượng SDK,
như trên màn hình. since / until di chuyển cửa sổ đó; since="30d" là những gì
giao diện mở. Một tỷ lệ hoặc trung bình trong khoảng thời gian không có trace trả về
dưới dạng null, vì 0% lỗi trong một tuần không có lưu lượng đọc như một tuần khỏe mạnh.
vocabulary là bản đồ bạn cần trước khi có thể hỏi bất cứ điều gì khác:
tên điểm phản hồi của dự án, các khóa sử dụng token của nó, và các quy tắc tự động hóa
chấm điểm các trace của nó. Đây là những tên đi vào bộ lọc hoặc vào
series= bên dưới, và đoán chúng trả về một trang trống trông như tin tốt.
Tên điểm và quy tắc bị giới hạn, luôn báo cáo tổng thực sự, và đặt tên
cho lệnh gọi trả về phần còn lại; các khóa sử dụng được liệt kê đầy đủ, vì không có gì
khác liệt kê chúng. contains đặt tên cho thí nghiệm, dataset, phiên bản prompt và lần chạy tối ưu hóa
mới nhất, vì vậy "chuyện gì đang xảy ra ở đây" không cần thêm bốn lần gọi nữa. Một phần
không tải được sẽ nói rõ điều đó thay vì trông trống rỗng, và một phần trống
bị bỏ qua.
Một lần đọc agent_insights_issue trả về {issue, example_trace_ids, details}:
bản ghi vấn đề Chẩn đoán (tên, mô tả, nguyên nhân, đề xuất sửa chữa,
mức độ nghiêm trọng, trạng thái), các id đã khử trùng lặp của các trace thể hiện nó (cùng
mẫu mà trang Chẩn đoán hiển thị — mở một cái bằng read("trace", id)),
và phân tích theo ngày. Phần thân trace không được nhúng, vì vậy lần đọc vẫn là một
lần gọi backend. since / until thu hẹp các hàng theo ngày; mặc định là
toàn thời gian. Khi máy chủ biết URL Opik và không gian làm việc của phiên, lần đọc
cũng mang url (trang Chẩn đoán của vấn đề) và trace_url_template
(một liên kết sâu cho bất kỳ trace ví dụ nào), vì vậy trợ lý có thể đưa cho bạn
thứ gì đó có thể nhấp được; trong phiên OAuth có không gian làm việc không thể phân giải,
các liên kết bị bỏ qua thay vì đoán.
Bản thân các trace không mang URL — một liên kết cho một trace không thể suy ra từ
các trường mà read hoặc list trả về, và một hình dạng đoán sẽ 404. Các
hướng dẫn phiên đặt tên một mẫu cho nó thay vào đó,
.../v1/session/redirect/projects/?trace_id={trace_id}&path=..., vì vậy
trợ lý điền một id và đưa cho bạn một liên kết. Nó đi qua chuyển hướng của opik-backend,
nơi phân giải dự án và không gian làm việc từ trace, vì vậy nó hoạt động
ở nơi URL dự án trực tiếp không thể, bao gồm cả phiên OAuth với không gian làm việc chưa phân giải.
Đó là cùng một liên kết mà Python SDK in cho một trace.
list
Duyệt hoặc tìm kiếm một bộ sưu tập với phân trang. Các loại có phạm vi dự án (trace,
span, thread, agent_insights_issue, dataset_item, prompt_version)
cần phần tử cha của chúng: một UUID hoặc tên dự án, một UUID dataset, hoặc một UUID prompt.
list(entity_type="experiment", page=1, size=25)
list(entity_type="experiment", name="rerank") # name substring filter
list(entity_type="agent_insights_issue", project_name="demo") # open Diagnostics issues
list(entity_type="agent_insights_issue", project_id="<uuid>", status="resolved")
list(entity_type="trace", project_name="demo") # latest traces of one project
list(
entity_type="trace", project_name="demo", filters="error_info is_not_empty AND duration > 5000"
)
list(
entity_type="span",
project_name="demo", # spans across the whole project
filters='type = "llm" AND usage.total_tokens > 10000',
)
list(
entity_type="thread",
project_name="demo",
filters="number_of_messages > 20 AND feedback_scores.helpfulness < 0.5",
)
list(entity_type="experiment", filters='dataset_id = "<dataset-uuid>" AND tags contains "baseline"')
Bộ lọc. trace, span, thread, experiment và dataset_item nhận một
chuỗi OQL, cùng cú pháp với search_traces(filter_string=…) của SDK:
<field>[.<key>] <op> <value> [AND ...]
ops: = != > >= < <= contains not_contains starts_with ends_with is_empty is_not_empty in not_in
Chuỗi nằm trong dấu ngoặc kép, số để trần, duration tính bằng mili giây,
ngày là các thời điểm ISO-8601 có múi giờ ("2026-09-08T10:00:00Z").
Điểm và từ điển nhận một khóa: feedback_scores.accuracy < 0.5,
metadata.environment = "prod". AND là bộ nối duy nhất.
Giống trang Nhật ký của giao diện, danh sách trace, span và thread thêm source = "sdk" để
các trace của bộ đánh giá, playground và thí nghiệm tránh xa; tự đặt tên source
để xem chúng. Dòng đầu ra đầu tiên lặp lại bộ lọc đã được áp dụng.
Bộ lọc lỗi sẽ thất bại trước khi đến được backend mà không có thông tin cần thiết để sửa:
vị trí của lỗi cú pháp, tên trường gần nhất, các toán tử hợp lệ cho
kiểu của trường, hoặc định dạng giá trị mong đợi. Các trường có tập giá trị đóng
(source, span type, thread status, visibility_mode) cũng được kiểm tra
với tập đó, bao gồm mọi phần tử của danh sách in. source là trường mà
backend tự xác thực, và nó trả lời một giá trị không xác định với mã 500 thay vì
400, vì vậy source = "SDK" nếu không sẽ là một lỗi máy chủ mơ hồ cho một
chữ cái viết hoa. Phần còn lại được so sánh dưới dạng chuỗi và trả về một trang trống,
trông giống như "không có kết quả khớp" trong khi thực ra nghĩa là "không có giá trị như vậy". Hãy hỏi
schema("list.trace") (hoặc list.span, list.thread, list.experiment) để
tham chiếu đầy đủ các trường, bao gồm cả các giá trị được chấp nhận.
Tìm một trường hợp cụ thể trong tập dữ liệu. list(entity_type="dataset_item", dataset_id=…) filters on the case itself: data.<key> để lấy các khóa mà
tập dữ liệu được xây dựng, full_data để tìm một chuỗi con của toàn bộ payload (một
quét toàn bộ — hãy chỉ định tên khóa khi có thể), cùng với id, tags, source, trace_id,
span_id và các mốc thời gian. data.<key> chỉ chấp nhận sáu toán tử chuỗi
(=, !=, contains, not_contains, starts_with, ends_with);
backend trả lời một phép so sánh với mã 400, vì vậy trường hợp này bị từ chối trước khi
gọi. Endpoint không có sắp xếp và không có tìm kiếm văn bản tự do — sort bị từ chối
thay vì bị bỏ qua. read(entity_type="dataset_item", id=…) trả về một trường hợp
nguyên vẹn, đó là cách một giá trị mà bảng đã cắt được đọc lại.
list(entity_type="dataset_item", dataset_id="<uuid>", filters='data.question contains "install"')
list(
entity_type="dataset_item", dataset_id="<uuid>", filters='trace_id = "<trace-uuid>"'
) # the case made from that trace
read(entity_type="dataset_item", id="<item-uuid>") # the case, uncut
Với experiment_ids, cùng một danh sách được dùng để so sánh — các trường hợp có
mỗi lần chạy được gắn kèm — và nó lọc trên các lần chạy (feedback_scores.<name>,
output, duration). Hai cái này là hai tập trường khác nhau trên hai endpoint
backend: schema("list.dataset_item_case") là các trường hợp của riêng tập dữ liệu,
schema("list.dataset_item") là so sánh.
Sắp xếp. trace, span, thread và experiment nhận
sort="<field> [asc|desc]", desc theo mặc định và chỉ một trường:
sort="duration desc", sort="total_estimated_cost",
sort="feedback_scores.accuracy asc", sort="usage.total_tokens". Trường được
kiểm tra với danh sách có thể sắp xếp của thực thể trước khi gọi, vì backend
âm thầm bỏ qua các trường mà nó không thể sắp xếp. Trên các workspace rất lớn, backend
bỏ hoàn toàn việc sắp xếp; tiêu đề sẽ nói rõ điều đó khi xảy ra.
dataset_item chỉ sắp xếp như một phép so sánh (với experiment_ids): endpoint
items không nhận tham số sắp xếp, vì vậy một sắp xếp trên danh sách thông thường bị từ chối
thay vì bị bỏ qua.
Khoảng thời gian và tìm kiếm. trace, span và thread nhận since và
until, mỗi cái là một khoảng tương đối ("30m", "1h", "7d") hoặc một thời điểm ISO-8601
có múi giờ, vì vậy "giờ qua" không cần tính toán đồng hồ. Khoảng thời gian được tính theo
thời gian tạo bản ghi, điều này rẻ cho backend và khớp với
start_time trong vài giây đối với lưu lượng trực tiếp. Để có một ranh giới chính xác, hãy đặt
start_time trong filters. Ba loại tương tự nhận search, văn bản tự do khớp
ở bất kỳ đâu trong id, name, input, output, metadata, tags và thread id. Tìm kiếm quét
toàn bộ dự án trên backend, vì vậy lần gọi đầu tiên trên một dự án lớn có thể mất
hàng chục giây. Những lần gọi đó có thời gian chờ 60 giây. Thêm since giúp chúng
nhanh trở lại.
Đọc bảng. Thời lượng được gắn nhãn duration_ms / ttft_ms và
hiển thị dưới dạng mili giây nguyên; trường vẫn là duration trong filters và
sort. Dấu thời gian được hiển thị đến giây và chi phí dưới dạng số thập phân đơn giản.
Các hàng dự án mang last_updated_trace_at để bạn có thể thấy dự án nào có
lưu lượng trực tiếp; các hàng thread mang tin nhắn đầu tiên. Một trang trống dưới một
khoảng thời gian cho biết khi nào trace cuối cùng của dự án được ghi, và một trang trống dưới
source = "sdk" mặc định cho biết cách xem các nguồn khác. Một
project_name viết sai chính tả sẽ trả về tên hiện có gần nhất.
list(
entity_type="trace",
project_name="demo",
since="1h",
filters="error_info is_not_empty",
sort="duration desc",
)
list(entity_type="trace", project_name="demo", search="order-42")
Các vấn đề chẩn đoán. agent_insights_issue là trang Diagnostics qua
MCP: các lỗi lặp lại mà công việc Diagnostics của Opik đã nhóm cho một dự án,
được xếp hạng theo cách UI xếp hạng chúng (gần đây nhất được thấy trước). Các cột là severity,
status, total_occurrences (tổng mọi thời điểm), latest_count (ngày
báo cáo gần nhất, con số mà mô tả của chính vấn đề đề cập đến) và last_seen.
Các vấn đề đang mở được liệt kê theo mặc định; truyền status="resolved" hoặc "closed" để xem
phần còn lại. read và list cũng trả lời cho issue, đây là những gì UI gọi
chúng; tên dài là tên trong enum entity_type, vì vậy thực thể đó
không xuất hiện hai lần ở đó. Số đếm là mọi thời điểm để khớp với UI; cùng since / until
như cho traces thu hẹp khoảng thời gian, được cắt xuống các ngày báo cáo UTC vì
Diagnostics tổng hợp theo ngày.
Một danh sách trống cho biết lý do tại sao nó trống, vì "không có gì hỏng" và "không ai bật Diagnostics" trông giống nhau nếu không. Có năm trạng thái: Diagnostics không khả dụng trên bản triển khai này, chưa được bật cho dự án này, đã tắt, đã bật nhưng chưa được quét gần đây, hoặc đã bật và sạch với thời gian của lần quét cuối. Các trạng thái bạn có thể hành động sẽ nêu tên lệnh gọi cần thực hiện, và mọi trạng thái đều liên kết đến trang Diagnostics của dự án.
Một danh sách không trống tự ghi ngày tháng. Các vấn đề là bất cứ điều gì lần quét cuối đã nhóm,
vì vậy câu trả lời kết thúc bằng Report covers data through <time>, và khi khoảng thời gian
bạn hỏi chạy qua đó, nó nêu tên phần đuôi chưa được bao phủ và cách đóng
nó: một trình kích hoạt khi một lần quét lại đủ xa, nếu không thì các trace thô với
since mà nó cung cấp cho bạn. Hãy hỏi một tuần trên một dự án được quét hàng đêm và
ngày cuối cùng bị thiếu trong câu trả lời được nhóm; đây là điều nói rõ điều đó.
write("agent_insights_job.enable", {"project_name": "demo"}) bật Diagnostics
lên. Nó quét hàng ngày từ đó, và gọi lại là an toàn.
write("agent_insights_job.trigger", …) quét 24 giờ qua ngay bây giờ, mà không
cần chờ lần chạy hàng đêm. Cả hai đều yêu cầu quyền mà việc đọc các vấn đề yêu cầu,
và cả hai đều từ chối nơi bản triển khai không có Diagnostics.
Một vấn đề di chuyển qua vòng đời của nó với
write("agent_insights_issue.resolve", {"issue_id": "<uuid>", "project_name": "demo"})
— đã xử lý — hoặc …close cho một vấn đề không đáng hành động, và …reopen để đưa
một trong hai trở lại danh sách mở. Cả ba đều yêu cầu cùng một quyền và trả lời
bằng một liên kết đến chế độ xem mà vấn đề đã chuyển đến, vì một vấn đề đã giải quyết không còn
trên trang mặc định. Việc một lỗi đã được sửa hay chưa là một phán đoán, vì vậy
những thao tác này dành cho khi bạn hỏi: trợ lý không có nhiệm vụ dọn dẹp danh sách trong khi
phân loại nó.
Số liệu theo thời gian. project_metric vẽ biểu đồ một số liệu cho một dự án dưới dạng một
bảng các khoảng thời gian: số lượng trace, span và thread, thời lượng, tỷ lệ lỗi,
chi phí, mức sử dụng token và điểm phản hồi. Nó trả lời câu hỏi theo sau
phần tổng quan, đó là khi nào một thứ gì đó đã thay đổi.
list(entity_type="project_metric", project_name="demo", metric_type="trace_count")
list(
entity_type="project_metric",
project_name="demo",
metric_type="trace_error_rate",
since="14d",
interval="daily",
)
list(
entity_type="project_metric", project_name="demo", metric_type="span_count", breakdown="model"
) # one column per model
list(
entity_type="project_metric",
project_name="demo",
metric_type="span_duration",
breakdown="model",
series="p99",
) # the p99 of each model
Các hàng là các khoảng thời gian, không phải bản ghi, vì vậy page, size và sort bị từ chối
thay vì bị bỏ qua. interval là hourly, daily, weekly hoặc total;
nếu bỏ qua, nó theo khoảng thời gian giống như tab Metrics — theo giờ lên đến 3
ngày, theo ngày lên đến 30, theo tuần xa hơn — vì vậy một biểu đồ mặc định là vài chục hàng
bất kể phạm vi, và một tháng theo giờ (721 hàng) là điều bạn phải yêu cầu.
since / until nhận các dạng giống như mọi nơi khác và mặc định là
7 ngày qua. filters sử dụng các trường của thực thể mà số liệu
đang nói đến, vì vậy một số liệu span được lọc bởi các trường span.
breakdown chia mỗi khoảng theo tags, name, error_info, error_type,
model, provider, span_type, guardrail_name hoặc metadata.<key>. Không phải
mọi số liệu đều chấp nhận mọi thứ trong số đó, và bảy số liệu không chấp nhận gì cả; công cụ
biết cái nào và nói rõ trước khi gọi backend, nêu tên một số liệu trả lời
cùng một câu hỏi nếu có. Ba nhóm trả về nhiều chuỗi cùng một lúc (một thời lượng dưới dạng p50/p90/p99, một điểm phản hồi theo tên, mức sử dụng token
theo khóa), và backend vẽ biểu đồ một trong số chúng tại một thời điểm khi nhóm, vì vậy
series= chọn nó: một phần trăm, một tên điểm, hoặc một khóa sử dụng. Thời lượng
mặc định là p50 và mức sử dụng token là total_tokens, và cái nào được sử dụng sẽ được
lặp lại trên dòng đầu tiên.
Các khoảng trống được bỏ qua và đếm bên dưới, vì vậy một tháng yên tĩnh là vài hàng thay vì một cột số không, và một tỷ lệ trên một khoảng không có trace là vắng mặt thay vì được báo cáo là không.
Hãy hỏi schema("list.project_metric") để biết bảng số liệu, các khoảng thời gian và
ma trận nhóm theo từng số liệu.
Tên của một dự án. score_name liệt kê các tên điểm phản hồi được ghi trong
một dự án và online_rule các bộ đánh giá quy tắc tự động hóa được cấu hình trên đó,
đây là nơi hầu hết các tên đó đến từ. Cả hai đều là cùng một danh sách
mà read("project", …) mang, đầy đủ và được phân trang, cho khi phiên bản
giới hạn trong phần tổng quan là không đủ.
list(entity_type="score_name", project_name="demo")
list(entity_type="online_rule", project_name="demo")
write
Bộ điều phối ghi phổ quát. Truyền operation + data và bộ điều phối
xác thực payload, áp dụng động từ REST phù hợp, và trả về
phản hồi của backend.
Các thao tác:
| Thao tác | Chức năng |
|---|---|
trace.create | Ghi một trace đơn lẻ (hoặc một lô). Cha cho spans / scores / comments. |
trace.update | Hoàn tất hoặc sửa đổi một trace hiện có. |
span.create | Ghi một span trên một trace hiện có (hoặc một lô). |
score.create | Gắn một điểm phản hồi số vào một trace, span, hoặc thread. |
comment.create | Gắn một bình luận văn bản tự do vào một trace, span, hoặc thread. |
prompt_version.save | Lưu một phiên bản prompt mới (tạo prompt theo tên nếu thiếu). |
dataset.create | Tạo một tập dữ liệu — type: "test_suite" biến nó thành một bộ kiểm thử đánh giá. |
dataset_item.upsert | Upsert các mục vào một tập dữ liệu (luôn ở dạng envelope). |
experiment.create | Tạo một thử nghiệm có phạm vi trong một tập dữ liệu. |
experiment_item.create | Gắn các hàng trace + dataset_item vào một thử nghiệm. |
thread.close | Đóng một thread (đánh dấu nó không hoạt động). Truyền thread_id và dự án. |
thread.open | Mở lại một thread đã đóng. Truyền thread_id và dự án. |
agent_insights_job.enable | Bật Diagnostics cho một dự án (quét hàng ngày, an toàn để lặp lại). |
agent_insights_job.trigger | Chạy một lần quét Diagnostics ngay bây giờ, trong 24 giờ qua. |
agent_insights_issue.resolve | Đánh dấu một vấn đề Diagnostics là đã xử lý (hỏi người dùng trước). |
agent_insights_issue.close | Đánh dấu một vấn đề Diagnostics là không đáng hành động (hỏi người dùng trước). |
agent_insights_issue.reopen | Đưa một vấn đề Diagnostics đã giải quyết hoặc đã đóng trở lại danh sách mở. |
write(
operation="score.create",
data={
"target": "trace",
"target_id": "7f2e3c8a-…",
"name": "helpfulness",
"value": 0.9,
"reason": "great recovery",
},
)
schema
Kiểm tra hình dạng JSON chính xác và các trường bắt buộc của bất kỳ thao tác ghi nào trước khi
bạn gọi nó — hữu ích khi bạn không chắc data nên trông như thế nào. Trả về
schema, phạm vi OAuth, và một ví dụ đã được xác thực. Tra cứu thuần túy, không gọi
backend.
schema(operation="score.create")
schema(operation="prompt_version.save")
Cùng một công cụ trả lời list.trace, list.span, list.thread và
list.experiment với tham chiếu của công cụ list cho thực thể đó: mọi
trường có thể lọc với kiểu và toán tử hợp lệ của nó, các trường có thể sắp xếp, liệu
một khoảng thời gian và tìm kiếm văn bản tự do có áp dụng, và hai ví dụ về bộ lọc.
schema(operation="list.trace")
Cấu hình
Mọi cài đặt là một biến môi trường. Các biến bắt buộc được in đậm.
Danh tính / endpoint
| Biến | Mặc định | Ghi chú |
|---|---|---|
OPIK_API_KEY | — | Bắt buộc cho mọi thao tác đọc/ghi có xác thực. |
OPIK_WORKSPACE | chưa đặt | Tên không gian làm việc. Trên cloud với API key, nếu không đặt sẽ gửi default, giá trị này phân giải thành không gian làm việc mặc định của tài khoản bạn — hãy đặt tường minh nếu bạn làm việc ở không gian khác, nếu không các thao tác đọc sẽ âm thầm lấy từ sai không gian làm việc. Để trống khi dùng OAuth (token đã mang sẵn thông tin này) và trên bản local/OSS (default là không gian làm việc duy nhất ở đó). |
COMET_WORKSPACE | — | Bí danh không còn dùng cho OPIK_WORKSPACE (tương thích ngược). OPIK_WORKSPACE được ưu tiên nếu cả hai đều được đặt. |
COMET_WORKSPACE_ID | chưa đặt | UUID không gian làm việc tùy chọn. Được ghi vào sự kiện phân tích khi được đặt và có quyền ưu tiên hơn giá trị đã phân giải. Hiếm khi cần — các bản cài qua OAuth tự lấy UUID từ token. |
COMET_URL_OVERRIDE | https://www.comet.com | Đặt thành máy chủ Comet tự lưu trữ của bạn, hoặc https://dev.comet.com cho môi trường staging. |
OPIK_URL | suy ra từ COMET_URL_OVERRIDE + /opik/api | Chỉ ghi đè nếu Opik nằm trên máy chủ/đường dẫn khác với giao diện Comet. |
OPIK_DEFAULT_PROJECT_NAME | chưa đặt | Khi được đặt, khối instructions theo phiên sẽ yêu cầu LLM truyền giá trị này làm project_name trong mọi lệnh gọi công cụ trừ khi người dùng chỉ định một dự án khác. |
Máy chủ / giao thức vận chuyển
| Biến | Mặc định | Ghi chú |
|---|---|---|
OPIK_MCP_TRANSPORT | stdio | stdio cho máy chủ khởi chạy từ host, streamable-http để lắng nghe trên một cổng. |
OPIK_MCP_HOST | 127.0.0.1 | Máy chủ bind của uvicorn (chỉ dành cho streamable-http). |
OPIK_MCP_PORT | 8080 | Cổng bind của uvicorn (chỉ dành cho streamable-http). |
OPIK_MCP_RELOAD | false | true để bật --reload của uvicorn (chỉ dành cho phát triển). |
OPIK_MCP_AS_URL | chưa đặt | URL Máy chủ Ủy quyền OAuth, được quảng bá trong /.well-known/oauth-protected-resource (RFC 9728) và được dùng làm mục tiêu proxy cho các truy vấn khám phá AS. Bắt buộc để các máy chủ MCP khởi động quy trình OAuth qua HTTP. |
OPIK_MCP_RESOURCE_URI | chưa đặt | URI công khai chuẩn của máy chủ này, được quảng bá làm resource trong siêu dữ liệu tài nguyên được bảo vệ và được dùng để suy ra gợi ý WWW-Authenticate. |
OPIK_MCP_OAUTH_VALIDATION_CACHE_TTL_S | 30 | Khoảng thời gian một câu trả lời "hợp lệ" từ điểm nội quan token của opik-backend được tin cậy trước khi yêu cầu tiếp theo trên cùng token OAuth hỏi lại. Giới hạn tải backend do xác thực từng yêu cầu và khoảng thời gian token hết hạn vẫn được chuyển tiếp (khoảng thời gian đó cũng kết thúc ở mã 401 đầu tiên backend trả về). Bị giới hạn bởi expires_at của chính token khi backend báo cáo. |
OPIK_MCP_LOG_LEVEL | INFO | Ngưỡng ghi log stderr. |
Chọn giao thức vận chuyển
Hai dạng bearer, hai hợp đồng trên giao thức HTTP. Một token truy cập OAuth opik_mcp_at_… được xác thực trên mọi yêu cầu với điểm nội quan token của opik-backend (có bộ nhớ đệm, xem OPIK_MCP_OAUTH_VALIDATION_CACHE_TTL_S);
token hết hạn hoặc bị thu hồi sẽ nhận HTTP 401 kèm WWW-Authenticate: Bearer error="invalid_token", đây là điều các máy chủ MCP dựa vào để thực hiện cấp quyền refresh_token âm thầm. API key của Opik không được xác thực cục bộ: nó được chuyển tiếp nguyên văn đến opik-backend, nơi duy nhất thực thi. Chọn giao thức vận chuyển theo hình thức triển khai:
| Tình huống | Giao thức vận chuyển |
|---|---|
| Máy khách MCP và Opik trên cùng một máy (bản OSS cục bộ) | stdio (khuyến nghị — đơn giản nhất, không cần cổng, không cần thiết lập OAuth) |
| Máy khách MCP cục bộ → Opik từ xa (Comet cloud / tự lưu trữ) | stdio với OPIK_API_KEY, hoặc HTTP với OAuth (OPIK_MCP_AS_URL trỏ đến backend) |
| opik-mcp được lưu trữ sau cùng một biên với opik-backend | HTTP — bearer được backend xác thực theo từng yêu cầu |
Lưu ý cho bản OSS cục bộ: backend OSS không xác thực yêu cầu, vì vậy opik-mcp HTTP đứng trước nó cũng mở như chính REST API OSS. Giữ bind 127.0.0.1 mặc định (và ưu tiên stdio) trên các mạng dùng chung.
Đo lường từ xa
Sự kiện sử dụng ẩn danh (chỉ loại sự kiện + thời gian — không có nội dung truy vấn). Bản băm SHA-256 của API key được bao gồm để bộ phận hỗ trợ có thể tìm tài khoản của bạn; khóa thô không bao giờ rời khỏi tiến trình. Từ chối: OPIK_MCP_ANALYTICS_ENABLED=false.
| Biến | Mặc định | Ghi chú |
|---|---|---|
OPIK_MCP_ANALYTICS_ENABLED | true | Đặt thành false để tắt mọi đo lường từ xa. |
OPIK_MCP_ANALYTICS_URL | https://stats.comet.com/notify/event/ | Ghi đè cho staging. |
OPIK_MCP_ANALYTICS_ENVIRONMENT | prod | Thẻ trên mọi sự kiện (prod / staging / dev). |
OPIK_MCP_ANALYTICS_SOURCE | comet.com | Bộ thu dùng giá trị này để đánh dấu on_prem=False. Bản cài tại chỗ nên ghi đè thành "" hoặc tên miền riêng của họ. |
OPIK_MCP_ANALYTICS_CONNECT_TIMEOUT_S | 5.0 | Thời gian chờ kết nối HTTP. |
OPIK_MCP_ANALYTICS_TOTAL_TIMEOUT_S | 10.0 | Thời gian chờ tổng yêu cầu HTTP. |
Giới hạn máy chủ đã biết
Các máy chủ khác nhau về thời gian cho phép một lệnh gọi công cụ chạy:
- Claude Code — không có thời gian chờ lệnh gọi công cụ được ghi nhận. Khuyến nghị.
- Cursor — thời gian chờ 60s cố định không được đặt lại khi có tiến trình (lỗi upstream).
- MCP Inspector —
MAX_TOTAL_TIMEOUTgiới hạn tổng thời lượng (mặc định 60s). Tăng giá trị này trong giao diện Inspector cho các thao tác dài.
Nếu một lệnh gọi bị kẹt, hãy đặt OPIK_MCP_LOG_LEVEL=DEBUG để có nhật ký yêu cầu đầy đủ.
Xử lý sự cố
OPIK_API_KEY không được nhận — biến không đến được tiến trình máy chủ.
Trong Claude Code / Cursor / VS Code, biến môi trường chỉ áp dụng khi nằm trong
khối env của cấu hình máy chủ MCP, không phải trong shell của bạn. Khởi động lại máy chủ sau khi chỉnh sửa.
Lệnh gọi Cursor hết thời gian ở 60s — lỗi đã biết của Cursor, không phải opik-mcp. Hoặc
thu hẹp lệnh gọi (size nhỏ hơn, cửa sổ thời gian chặt hơn), hoặc chạy cùng thao tác
trên Claude Code vốn không có giới hạn cứng.
Máy chủ không hiển thị, đăng nhập không mở, sai không gian làm việc, uvx không tìm thấy.
Những vấn đề này được đề cập trong phần xử lý sự cố của tài liệu.
opik mcp status (từ cùng CLI uvx opik) liệt kê mọi máy khách đã cấu hình máy chủ và
liệu cấu hình của nó có bị lệch hay không.
Phát triển
git clone git@github.com:comet-ml/opik-mcp.git
cd opik-mcp
make install # uv sync --locked --extra dev
make check # lint + typecheck + test
make run-dev # uvicorn with --reload + DEBUG logs
make inspect # MCP Inspector against the running server
Các mục tiêu phổ biến:
| Mục tiêu | Chức năng |
|---|---|
make install | uv sync --locked --extra dev |
make run | Chạy máy chủ MCP (stdio theo mặc định). |
make run-dev | Chạy với ghi log DEBUG + uvicorn --reload. |
make dev | Chạy qua mcp dev (trình bao bọc chế độ dev của Inspector). |
make inspect | Khởi chạy MCP Inspector với một máy chủ đang chạy. |
make test | uv run pytest -q. |
make lint | ruff check + kiểm tra định dạng. |
make format | ruff format + ruff check --fix. |
make typecheck | mypy. |
make check | lint + typecheck + test. |
Cấu trúc kho lưu trữ:
opik-mcp/
├── src/opik_mcp/ ← server, tools, analytics
├── tests/ ← pytest suites
├── scripts/ ← live-BE smoke + MCP-session smoke
├── legacy/typescript/ ← migration guide for the deprecated v2 TS server (source: tag `legacy-typescript-final`)
├── pyproject.toml
└── Makefile
Nhận trợ giúp
- Mở một issue cho lỗi và yêu cầu tính năng
- Tài liệu Opik cho tài liệu SDK / backend
- Slack cộng đồng Comet cho các câu hỏi
Nâng cấp từ v2? Máy chủ TypeScript cũ vẫn được phát hành trên npm dưới tên
opik-mcp@^2(npx -y opik-mcp); mã nguồn của nó nằm ở thẻ gitlegacy-typescript-final. Xemlegacy/typescript/DEPRECATED.mdđể biết chính sách hỗ trợ.
Giấy phép
Apache-2.0.