使用 Unsiloed 與 TypeSafe Jev 進行檔案審查
Document Review with Unsiloed and TypeSafe Jev
使用 Unsiloed 與 TypeSafe Jev 進行檔案審查 - 工作流程:先用 Unsiloed 擷取結構化欄位並提供 extraction_score 與 grounding_score,然後將結果送至 Jev,Jev 以 noul 方式判斷欄位的合理性。
本文示範如何結合 Unsiloed 與 TypeSafe Jev,透過 OCR 與機器判斷檢查檔案錯誤,提供實作範例與成本估算。
一個抽取管線可以正確讀取一個值,但仍可能將錯誤資料傳遞下游。印刷清晰的多餘零號即使經過優秀的光學字元辨識(OCR)也能存活。
結合 Unsiloed 與 TypeSafe 的 Jev 可以協助我們檢查檔案中的 OCR 失敗與一般錯誤。Unsiloed 會擷取結構化欄位並定位於頁面。Jev 將擷取到的資訊與聚焦問題做對照判斷。我們可以結合這些結果決定哪些欄位需要審閱。
Jev 將聚焦問題轉換為型別答案
Jev 的請求將其考慮的資訊(state)與它所做的決策(questions)分離。在我們的工作流程中,state 包含 Unsiloed 擷取到的紀錄以及解讀它們所需的上下文。每個問題告訴 Jev 要檢查什麼以及要回傳哪種答案型別;它也可以為可能的答案定義標準。
型別決定我們的程式會收到什麼。Noul 回傳一個陳述為真之機率。Choice 從已命名的選項中選擇;Score 評估一套有序層級的評分標準。Choice 與 Score 也會回傳機率分佈與置信值,總結其集中度。Noul 沒有獨立的置信欄位。
三種型別可以在同一次請求中共用 state,如圖所示。後續我們的範例只會使用 Noul。

Noul 值為 0.04 表示對我們問題的「是」機率為 4%,即強烈「否」。這並不代表「Jev 的置信度為 4%」。靠近兩端的值表示明確方向;靠近中間的值則需謹慎。
將 Unsiloed 擷取的欄位送給 Jev,然後路由結果
Unsiloed 保留印刷內容並提供信心分數,協助辨識模糊讀取。以本例為例,我們使用含六行的藥物清單。咖啡斑遮住一個劑量,而另一行則印刷清晰但不合理的數量。我們將透過擷取與 Jev 的檢查來追蹤兩者。

我們的 擷取模式 定義了 Unsiloed 應為每項藥物回傳的欄位。它要求完整的劑量儲存格,包括數量與單位,且不會校正意外數量或根據常規處方做遮蔽文字推測。啟用來源引用 enable_citations=true,並在擷取工作完成前等待,再構建 Jev 的狀態。
每個欄位都有兩個 Unsiloed 信心分數:extraction_score 測量擷取值的信心,grounding_score 測量該值在檔案中定位的信心。兩者皆介於零與一之間。引用會標示其頁碼與包圍框,為來源文字的矩形範圍。
以下是已儲存回應中染汙的 cetirizine 劑量,並附上原始 1,200 × 1,500 畫素影像上的畫素座標:
{
"value": "1 tablet",
"score": { "grounding_score": 0.76, "extraction_score": 0.74 },
"citation": {
"page": 1,
"bbox": [582, 975, 649, 994],
"page_width": 1200,
"page_height": 1500
}
}
為每行藥物分配一個 ID,例如 row-5,並將其與擷取欄位及其引用一起保留。這樣程式碼就能在之後將 Jev 的答案對應到同一行。保留引用以便審查者能在原始頁面上定位每個擷取欄位。
將擷取值與上下文送給 Jev。它在未看到影像或 Unsiloed 分數的情況下,判斷指令已被擷取。每行我們提出一個 Noul 問題:此劑量與頻率對該藥物是否合理?六行共用一次請求,且 每個問題獨立評估。
在連線兩個 API 的伺服端模組中,構造此請求(示範單行及其問題):
const request = {
model: "jev-1.13.0",
state: {
context: "Check for obvious quantity, unit or frequency errors. " +
"Dose means amount taken each time, not supply quantity. " +
"Do not assess patient-specific safety or propose corrections.",
careContext: "Adult outpatient medication reconciliation, age 52",
medications: [{
id: "row-5", medicine: "Cetirizine 10 mg tablet",
dose: "1 tablet", frequency: "Once daily as needed",
route: "Oral", instructions: "For allergy symptoms."
}]
},
questions: {
"row-5": {
type: "noul",
instructions: {
question: "Is the extracted dose and frequency plausible on its " +
"face for this medicine and strength in the stated adult " +
"outpatient context, without an obvious quantity or " +
"frequency transcription error?",
row_id: "row-5"
},
criteria: {
true: "Plausible on its face; no obvious quantity, unit or frequency error.",
false: "Clearly implausible; warrants review of the original prescription."
}
}
}
};
此處已簡化上下文與標準;已錄製的請求包含完整文字與全部六行。我們使用 row-5 作為問題編號,讓程式能將答案對應到該行。 同時也將其作為 row_id 放入指示中,讓 Jev 知道要評斷哪筆紀錄:問題編號 不會傳送至模型。
將請求以 JSON 形式傳送至 https://api.typesafe.ai/v1/systemone。使用您的 TypeSafe API 金鑰在 Authorization: Bearer <API_KEY> 標頭進行驗證,並將金鑰保留於伺服器端。answers["row-5"] 位置的錄製答案為 { "type": "noul", "noul": 0.94 }。將該答案與已儲存的 row-5 提取結果使用共用 ID 匹配。
Our code now decides whether the row needs review. For the reading check, we take the lowest Unsiloed score across the row’s fields, so a low score on any field flags the whole row. For the plausibility check, we use Jev’s noul value.
In the same module, pass those two values as reading and plausible to this function. It returns the reasons to send the row for review, or an empty array when neither check flags it. These demo rules also flag missing or invalid scores:
const valid = n => Number.isFinite(n) && n >= 0 && n <= 1;
function reviewReasons(reading, plausible) {
return [
...(!valid(reading) || reading < 0.90 ? ["Verify source reading"] : []),
...(!valid(plausible) || plausible < 0.50 ? ["Review instruction"] : [])
];
}
Here, a reading score below 0.90 or a plausibility answer below 0.50 triggers review. These are example cutoffs: test them against manually reviewed documents before using them in production. Jev answers near 0.50 may also need review because neither yes nor no is clearly favored.
Keep both reasons when both checks fail. A plausible instruction can still contain misread text, so a high Jev answer must not cancel a low Unsiloed score. Save the original extraction and Jev request and response alongside the reviewer’s decision so you can later check why a row was flagged and how it was resolved.
Follow the Flagged Rows From Extraction to Review
Step through the saved API results to see what Unsiloed reads, what Jev checks, and why the two flagged rows need different kinds of review.
For the stained cetirizine dose, Unsiloed extracts “1 tablet” with an extraction score of 0.74 and a grounding score of 0.76. Jev returns 0.94 for plausibility, but it never sees the stain. That judgment depends on the extracted text being right. The reading check still flags the row because someone must confirm the obscured mark.
The ibuprofen row reverses the pattern. Unsiloed reads “10 tablets, three times daily” with both scores at 0.99; Jev returns 0.04 for the same plausibility question. The reviewer needs to investigate the clearly printed instruction. Neither model substitutes an assumed intended dose.
每一次檢查都會標記需要審核的專案,其他則遺漏。其餘四行符合兩個示範門檻,正如 錄製回覆所示。說明與路由標籤來自我們的應用程式;Jev 只回傳輸入的答案,而非說明。
How Much Jev Adds Per Document
此示範中的一份藥物清單會產生一個包含六個問題且有 1,812 個輸入 token 的 Jev 請求。在 Jev 1.13.0 的 公佈價格為每十億輸入 token $42,且輸出免費(截至 2026 年 9 月 30 日檢查),這相當於每份檔案額外增加 $0.000076。處理 100,000 篇類似檔案將額外產生約 $7.61 的 Jev 費用。
This is a Jev-only estimate; Unsiloed extraction and human review cost separately. Your actual charge depends on the text and questions sent. For a closer estimate, take the input_tokens from a representative Jev response and apply the published rate.
來源:Hacker News (official RSS) · unsiloed.ai