Cortex 文档已覆盖 Parse、Storage、Knowledge、Evaluation 与 Synthesis。查看 最新变更

Evaluation 和 Synthesis

通过 Cortex Evaluation 和 Synthesis Job 运行评测、生成数据,并持久化报告与输出对象。

Cortex Evaluation 和 Synthesis 复用 Parse 和 Knowledge 使用的 Job、Storage、授权和遥测基础能力。下面的 API 片段是 AI 生成的 Python、JavaScript 和 Java 客户端示例。

列出评测引擎和指标

import osimport requestsBASE_URL = os.getenv("CORTEX_URL", "http://127.0.0.1:8080")TOKEN = os.getenv("CORTEX_TOKEN", "replace_with_token")def auth_headers():    return {"Authorization": f"Bearer {TOKEN}"}for path in ["/v1/eval/engines", "/v1/eval/metrics"]:    response = requests.get(f"{BASE_URL}{path}", headers=auth_headers())    response.raise_for_status()    print(path, response.json())
const BASE_URL = process.env.CORTEX_URL ?? "http://127.0.0.1:8080";const TOKEN = process.env.CORTEX_TOKEN ?? "replace_with_token";const authHeaders = {  Authorization: `Bearer ${TOKEN}`,};for (const path of ["/v1/eval/engines", "/v1/eval/metrics"]) {  const response = await fetch(`${BASE_URL}${path}`, { headers: authHeaders });  if (!response.ok) throw new Error(await response.text());  console.log(path, await response.json());}
import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;public class CortexExample {  static final String BASE_URL = System.getenv().getOrDefault("CORTEX_URL", "http://127.0.0.1:8080");  static final String TOKEN = System.getenv().getOrDefault("CORTEX_TOKEN", "replace_with_token");  static final HttpClient HTTP = HttpClient.newHttpClient();  static void print(HttpResponse<String> response) {    System.out.println(response.statusCode());    System.out.println(response.body());  }  public static void main(String[] args) throws Exception {    for (String path : new String[] {"/v1/eval/engines", "/v1/eval/metrics"}) {      HttpRequest request = HttpRequest.newBuilder()        .uri(URI.create(BASE_URL + path))        .header("Authorization", "Bearer " + TOKEN)        .GET()        .build();      print(HTTP.send(request, HttpResponse.BodyHandlers.ofString()));    }  }}

提交 RAG 评测 Job

import osimport requestsBASE_URL = os.getenv("CORTEX_URL", "http://127.0.0.1:8080")TOKEN = os.getenv("CORTEX_TOKEN", "replace_with_token")def auth_headers():    return {"Authorization": f"Bearer {TOKEN}"}payload = {  "name": "quickstart-rag-eval",  "eval_type": "rag",  "engine_id": "deepeval",  "input": {    "type": "inline_test_cases",    "test_cases": [      {        "user_input": "What does Cortex Parse do?",        "actual_output": "Cortex Parse converts URLs and files into normalized Markdown.",        "expected_output": "Parse should mention URLs, files, and Markdown.",        "retrieval_contexts": [          "Cortex Parse accepts URLs and files and returns normalized Markdown with metadata."        ],        "metadata": {          "case_id": "rag-001"        }      }    ]  },  "target": {    "type": "existing_outputs"  },  "metrics": [    {      "metric_key": "rag.answer_relevance",      "threshold": 0.65    },    {      "metric_key": "rag.faithfulness",      "threshold": 0.65    },    {      "metric_key": "rag.contextual_relevance",      "threshold": 0.6    }  ],  "output": {    "persist_report_object": True,    "include_sample_results": True  }}response = requests.post(    f"{BASE_URL}/v1/eval/jobs",    headers={**auth_headers(), "Content-Type": "application/json"},    json=payload,)response.raise_for_status()data = response.json()print(data)
const BASE_URL = process.env.CORTEX_URL ?? "http://127.0.0.1:8080";const TOKEN = process.env.CORTEX_TOKEN ?? "replace_with_token";const authHeaders = {  Authorization: `Bearer ${TOKEN}`,};const payload = {  "name": "quickstart-rag-eval",  "eval_type": "rag",  "engine_id": "deepeval",  "input": {    "type": "inline_test_cases",    "test_cases": [      {        "user_input": "What does Cortex Parse do?",        "actual_output": "Cortex Parse converts URLs and files into normalized Markdown.",        "expected_output": "Parse should mention URLs, files, and Markdown.",        "retrieval_contexts": [          "Cortex Parse accepts URLs and files and returns normalized Markdown with metadata."        ],        "metadata": {          "case_id": "rag-001"        }      }    ]  },  "target": {    "type": "existing_outputs"  },  "metrics": [    {      "metric_key": "rag.answer_relevance",      "threshold": 0.65    },    {      "metric_key": "rag.faithfulness",      "threshold": 0.65    },    {      "metric_key": "rag.contextual_relevance",      "threshold": 0.6    }  ],  "output": {    "persist_report_object": true,    "include_sample_results": true  }};const response = await fetch(`${BASE_URL}/v1/eval/jobs`, {  method: "POST",  headers: { ...authHeaders, "Content-Type": "application/json" },  body: JSON.stringify(payload),});if (!response.ok) throw new Error(await response.text());const data = await response.json();console.log(data);
import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;public class CortexExample {  static final String BASE_URL = System.getenv().getOrDefault("CORTEX_URL", "http://127.0.0.1:8080");  static final String TOKEN = System.getenv().getOrDefault("CORTEX_TOKEN", "replace_with_token");  static final HttpClient HTTP = HttpClient.newHttpClient();  static void print(HttpResponse<String> response) {    System.out.println(response.statusCode());    System.out.println(response.body());  }  public static void main(String[] args) throws Exception {    String json = """      {        \"name\": \"quickstart-rag-eval\",        \"eval_type\": \"rag\",        \"engine_id\": \"deepeval\",        \"input\": {          \"type\": \"inline_test_cases\",          \"test_cases\": [            {              \"user_input\": \"What does Cortex Parse do?\",              \"actual_output\": \"Cortex Parse converts URLs and files into normalized Markdown.\",              \"expected_output\": \"Parse should mention URLs, files, and Markdown.\",              \"retrieval_contexts\": [                \"Cortex Parse accepts URLs and files and returns normalized Markdown with metadata.\"              ],              \"metadata\": {                \"case_id\": \"rag-001\"              }            }          ]        },        \"target\": {          \"type\": \"existing_outputs\"        },        \"metrics\": [          {            \"metric_key\": \"rag.answer_relevance\",            \"threshold\": 0.65          },          {            \"metric_key\": \"rag.faithfulness\",            \"threshold\": 0.65          },          {            \"metric_key\": \"rag.contextual_relevance\",            \"threshold\": 0.6          }        ],        \"output\": {          \"persist_report_object\": true,          \"include_sample_results\": true        }      }      """;    HttpRequest request = HttpRequest.newBuilder()      .uri(URI.create(BASE_URL + "/v1/eval/jobs"))      .header("Authorization", "Bearer " + TOKEN)      .header("Content-Type", "application/json")      .POST(HttpRequest.BodyPublishers.ofString(json))      .build();    print(HTTP.send(request, HttpResponse.BodyHandlers.ofString()));  }}

轮询并获取结果:

import osimport requestsBASE_URL = os.getenv("CORTEX_URL", "http://127.0.0.1:8080")TOKEN = os.getenv("CORTEX_TOKEN", "replace_with_token")def auth_headers():    return {"Authorization": f"Bearer {TOKEN}"}response = requests.get(f"{BASE_URL}/v1/jobs/job_xxx", headers=auth_headers())response.raise_for_status()data = response.json()print(data)
const BASE_URL = process.env.CORTEX_URL ?? "http://127.0.0.1:8080";const TOKEN = process.env.CORTEX_TOKEN ?? "replace_with_token";const authHeaders = {  Authorization: `Bearer ${TOKEN}`,};const response = await fetch(`${BASE_URL}/v1/jobs/job_xxx`, {  headers: authHeaders,});if (!response.ok) throw new Error(await response.text());const data = await response.json();console.log(data);
import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;public class CortexExample {  static final String BASE_URL = System.getenv().getOrDefault("CORTEX_URL", "http://127.0.0.1:8080");  static final String TOKEN = System.getenv().getOrDefault("CORTEX_TOKEN", "replace_with_token");  static final HttpClient HTTP = HttpClient.newHttpClient();  static void print(HttpResponse<String> response) {    System.out.println(response.statusCode());    System.out.println(response.body());  }  public static void main(String[] args) throws Exception {    HttpRequest request = HttpRequest.newBuilder()      .uri(URI.create(BASE_URL + "/v1/jobs/job_xxx"))      .header("Authorization", "Bearer " + TOKEN)      .GET()      .build();    print(HTTP.send(request, HttpResponse.BodyHandlers.ofString()));  }}
import osimport requestsBASE_URL = os.getenv("CORTEX_URL", "http://127.0.0.1:8080")TOKEN = os.getenv("CORTEX_TOKEN", "replace_with_token")def auth_headers():    return {"Authorization": f"Bearer {TOKEN}"}response = requests.get(f"{BASE_URL}/v1/eval/jobs/job_xxx/result", headers=auth_headers())response.raise_for_status()data = response.json()print(data)
const BASE_URL = process.env.CORTEX_URL ?? "http://127.0.0.1:8080";const TOKEN = process.env.CORTEX_TOKEN ?? "replace_with_token";const authHeaders = {  Authorization: `Bearer ${TOKEN}`,};const response = await fetch(`${BASE_URL}/v1/eval/jobs/job_xxx/result`, {  headers: authHeaders,});if (!response.ok) throw new Error(await response.text());const data = await response.json();console.log(data);
import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;public class CortexExample {  static final String BASE_URL = System.getenv().getOrDefault("CORTEX_URL", "http://127.0.0.1:8080");  static final String TOKEN = System.getenv().getOrDefault("CORTEX_TOKEN", "replace_with_token");  static final HttpClient HTTP = HttpClient.newHttpClient();  static void print(HttpResponse<String> response) {    System.out.println(response.statusCode());    System.out.println(response.body());  }  public static void main(String[] args) throws Exception {    HttpRequest request = HttpRequest.newBuilder()      .uri(URI.create(BASE_URL + "/v1/eval/jobs/job_xxx/result"))      .header("Authorization", "Bearer " + TOKEN)      .GET()      .build();    print(HTTP.send(request, HttpResponse.BodyHandlers.ofString()));  }}

异步评测完成后可以持久化 evaluation_report 对象,并回写 eval_runs.report_object_id

列出合成引擎

import osimport requestsBASE_URL = os.getenv("CORTEX_URL", "http://127.0.0.1:8080")TOKEN = os.getenv("CORTEX_TOKEN", "replace_with_token")def auth_headers():    return {"Authorization": f"Bearer {TOKEN}"}response = requests.get(f"{BASE_URL}/v1/synthesis/engines", headers=auth_headers())response.raise_for_status()data = response.json()print(data)
const BASE_URL = process.env.CORTEX_URL ?? "http://127.0.0.1:8080";const TOKEN = process.env.CORTEX_TOKEN ?? "replace_with_token";const authHeaders = {  Authorization: `Bearer ${TOKEN}`,};const response = await fetch(`${BASE_URL}/v1/synthesis/engines`, {  headers: authHeaders,});if (!response.ok) throw new Error(await response.text());const data = await response.json();console.log(data);
import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;public class CortexExample {  static final String BASE_URL = System.getenv().getOrDefault("CORTEX_URL", "http://127.0.0.1:8080");  static final String TOKEN = System.getenv().getOrDefault("CORTEX_TOKEN", "replace_with_token");  static final HttpClient HTTP = HttpClient.newHttpClient();  static void print(HttpResponse<String> response) {    System.out.println(response.statusCode());    System.out.println(response.body());  }  public static void main(String[] args) throws Exception {    HttpRequest request = HttpRequest.newBuilder()      .uri(URI.create(BASE_URL + "/v1/synthesis/engines"))      .header("Authorization", "Bearer " + TOKEN)      .GET()      .build();    print(HTTP.send(request, HttpResponse.BodyHandlers.ofString()));  }}

生成 RAG goldens

import osimport requestsBASE_URL = os.getenv("CORTEX_URL", "http://127.0.0.1:8080")TOKEN = os.getenv("CORTEX_TOKEN", "replace_with_token")def auth_headers():    return {"Authorization": f"Bearer {TOKEN}"}payload = {  "name": "quickstart-qa-preview",  "synthesis_type": "qa_pairs",  "engine_id": "deepeval",  "source": {    "type": "documents",    "documents": [      "Cortex Parse turns URLs and storage objects into LLM-ready Markdown."    ]  },  "config": {    "sample_count": 2,    "max_contexts_per_case": 1,    "include_expected_output": True  },  "output": {    "output_format": "json",    "include_preview": True  }}response = requests.post(    f"{BASE_URL}/v1/synthesis/jobs",    headers={**auth_headers(), "Content-Type": "application/json"},    json=payload,)response.raise_for_status()data = response.json()print(data)
const BASE_URL = process.env.CORTEX_URL ?? "http://127.0.0.1:8080";const TOKEN = process.env.CORTEX_TOKEN ?? "replace_with_token";const authHeaders = {  Authorization: `Bearer ${TOKEN}`,};const payload = {  "name": "quickstart-qa-preview",  "synthesis_type": "qa_pairs",  "engine_id": "deepeval",  "source": {    "type": "documents",    "documents": [      "Cortex Parse turns URLs and storage objects into LLM-ready Markdown."    ]  },  "config": {    "sample_count": 2,    "max_contexts_per_case": 1,    "include_expected_output": true  },  "output": {    "output_format": "json",    "include_preview": true  }};const response = await fetch(`${BASE_URL}/v1/synthesis/jobs`, {  method: "POST",  headers: { ...authHeaders, "Content-Type": "application/json" },  body: JSON.stringify(payload),});if (!response.ok) throw new Error(await response.text());const data = await response.json();console.log(data);
import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;public class CortexExample {  static final String BASE_URL = System.getenv().getOrDefault("CORTEX_URL", "http://127.0.0.1:8080");  static final String TOKEN = System.getenv().getOrDefault("CORTEX_TOKEN", "replace_with_token");  static final HttpClient HTTP = HttpClient.newHttpClient();  static void print(HttpResponse<String> response) {    System.out.println(response.statusCode());    System.out.println(response.body());  }  public static void main(String[] args) throws Exception {    String json = """      {        \"name\": \"quickstart-qa-preview\",        \"synthesis_type\": \"qa_pairs\",        \"engine_id\": \"deepeval\",        \"source\": {          \"type\": \"documents\",          \"documents\": [            \"Cortex Parse turns URLs and storage objects into LLM-ready Markdown.\"          ]        },        \"config\": {          \"sample_count\": 2,          \"max_contexts_per_case\": 1,          \"include_expected_output\": true        },        \"output\": {          \"output_format\": \"json\",          \"include_preview\": true        }      }      """;    HttpRequest request = HttpRequest.newBuilder()      .uri(URI.create(BASE_URL + "/v1/synthesis/jobs"))      .header("Authorization", "Bearer " + TOKEN)      .header("Content-Type", "application/json")      .POST(HttpRequest.BodyPublishers.ofString(json))      .build();    print(HTTP.send(request, HttpResponse.BodyHandlers.ofString()));  }}

获取结果:

import osimport requestsBASE_URL = os.getenv("CORTEX_URL", "http://127.0.0.1:8080")TOKEN = os.getenv("CORTEX_TOKEN", "replace_with_token")def auth_headers():    return {"Authorization": f"Bearer {TOKEN}"}response = requests.get(f"{BASE_URL}/v1/synthesis/jobs/job_xxx/result", headers=auth_headers())response.raise_for_status()data = response.json()print(data)
const BASE_URL = process.env.CORTEX_URL ?? "http://127.0.0.1:8080";const TOKEN = process.env.CORTEX_TOKEN ?? "replace_with_token";const authHeaders = {  Authorization: `Bearer ${TOKEN}`,};const response = await fetch(`${BASE_URL}/v1/synthesis/jobs/job_xxx/result`, {  headers: authHeaders,});if (!response.ok) throw new Error(await response.text());const data = await response.json();console.log(data);
import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;public class CortexExample {  static final String BASE_URL = System.getenv().getOrDefault("CORTEX_URL", "http://127.0.0.1:8080");  static final String TOKEN = System.getenv().getOrDefault("CORTEX_TOKEN", "replace_with_token");  static final HttpClient HTTP = HttpClient.newHttpClient();  static void print(HttpResponse<String> response) {    System.out.println(response.statusCode());    System.out.println(response.body());  }  public static void main(String[] args) throws Exception {    HttpRequest request = HttpRequest.newBuilder()      .uri(URI.create(BASE_URL + "/v1/synthesis/jobs/job_xxx/result"))      .header("Authorization", "Bearer " + TOKEN)      .GET()      .build();    print(HTTP.send(request, HttpResponse.BodyHandlers.ofString()));  }}

异步合成完成后可以持久化 synthesis_output 对象,并回写 synthesis_runs.output_object_id

供应商提示

  • Evaluation 和 Synthesis 适配器应接收完整供应商槽位配置。
  • 本地 runtime profile 可将 DeepEval 路由到 Kimi、OpenRouter、OpenAI-compatible endpoint 或其他配置供应商。
  • 长耗时模型 Job 应使用大于预期 provider latency 的 lease;当前本地示例使用 300 秒 lease 和 30 秒 heartbeat。

本页目录