Skip to content
指南閱讀約需 9 分鐘

法律文件標註最佳實踐

在 Potato 中標註合同、法庭檔案和監管文本:章節級條目、條款與實體方案、關鍵詞高亮,以及面向專家標註者的品質控制。

Potato Team

在文件進入標註工具之前,先把冗長的法律文件拆成章節級的條目,用各自獨立的方案來標註條款和實體,並讓懂這個領域的標註者來承擔這項任務。對品質影響最大的一個決定是你在哪裡切分文件,因為脫離了定義和交叉引用標註出來的條款,標的就是錯的。

法律文本推翻了大多數標註方案所依賴的前提。文件動輒數百頁,詞彙專門到未經培訓的眾包工作者無法套用標註指南,而含義又取決於對某些章節的交叉引用,那些章節可能在五十頁之外。一個差不多對的 span 邊界會改變一個條款要求當事方去做什麼,所以平常對邊界大致準確的那種容忍度在這裡不成立。

在 Potato 看到文件之前先做的準備

分段屬於資料準備的步驟,而不是某項配置設定。Potato 標註的是你交給它的條目,所以一份合同要變得可標註,得先在你自己的流水線裡拆成若干章節,每一節寫成一個條目,並帶上標註者需要的後設資料:

json
{
  "id": "contract_001_section_3.2",
  "text": "The Licensor grants to the Licensee a non-exclusive, non-transferable license...",
  "section_number": "3.2",
  "section_title": "License Grant",
  "document_id": "contract_001"
}

按文件自身的結構來切分,通常是帶編號的標題,而不是按固定的詞元數量,因為從中間被劈開的條款誰也標不了。每個條目都要帶上章節編號和標題。標註者在判斷一項義務是不是有條件的時候,需要知道自己身處哪一節;而條目裡的章節編號也正是你事後把這些標籤重新拼裝成文件級標註的依據。

用 instance_display 宣告你想顯示哪些欄位,它把標註者看到的內容和你要他們標註的內容分開:

yaml
instance_display:
  fields:
    - key: section_title
      type: text
    - key: text
      type: text

長合同也常常以 PDF 的形式送來。pdf 和 document 這兩種展示類型可以直接渲染它們,省掉一道會把版式線索剝掉的抽取步驟,而有經驗的讀者正是靠那些線索閱讀的。

實體方案與條款方案

法律標註通常會對同一段文字收集兩類不同的資訊。實體 span 標出條款指向的人和事物,條款標籤則給整段文字分類。把它們放在各自獨立的方案裡,標註者就可以既標五個實體又標一個條款類型,兩者互不干擾。

實體由 span 承載。每個標籤都需要一個 name;而在兩位標註者可能對"defined term"理解不同的任務裡,寫一條 tooltip 是划算的:

yaml
annotation_schemes:
  - annotation_type: span
    name: legal_entities
    description: "Mark the parties, defined terms, dates, amounts and obligations."
    labels:
      - name: PARTY
        color: "#FECACA"
        tooltip: "Contracting parties, including Licensor, Licensee and named companies"
      - name: DEFINED_TERM
        color: "#FDE68A"
        tooltip: "A term given a specific meaning by the definitions section"
      - name: DATE
        color: "#BBF7D0"
        tooltip: "Dates and time periods, including notice and cure periods"
      - name: MONETARY
        color: "#C4B5FD"
        tooltip: "Amounts, fees, penalties and caps"
      - name: OBLIGATION
        color: "#BFDBFE"
        tooltip: "Language creating a duty, such as shall, must or agrees to"
      - name: CONDITION
        color: "#FED7AA"
        tooltip: "Language making a duty conditional, such as if, unless or provided that"
      - name: REFERENCE
        color: "#E0E7FF"
        tooltip: "A cross-reference to another section or document"

條款類型是單選,所以它屬於 radio 方案。列表要短到標註者能記在腦子裡,並且在試標階段檢查標籤分佈,因為長列表裡那些很少用到的類別正是分歧集中的地方:

yaml
  - annotation_type: radio
    name: clause_type
    description: "What type of clause is this?"
    labels:
      - Definitions
      - Grant of rights
      - Consideration and payment
      - Term and termination
      - Representations and warranties
      - Indemnification
      - Limitation of liability
      - Confidentiality
      - Intellectual property
      - Dispute resolution
      - Boilerplate

當一個條款可能帶有不止一項義務時,用 multiselect 把它們全部收下,而不是逼著標註者二選一;再用一個 likert 搭配一個自由文本欄位,把風險判斷連同理由一起記下來:

yaml
  - annotation_type: multiselect
    name: obligation_type
    description: "Which kinds of obligation does this clause create?"
    labels:
      - Performance
      - Payment
      - Restriction
      - Conditional obligation
      - Warranty
 
  - annotation_type: likert
    name: risk
    description: "How much risk does this clause carry for the receiving party?"
    size: 5
    min_label: "Low risk"
    max_label: "High risk"
 
  - annotation_type: text
    name: risk_notes
    description: "Explain the risk factors you identified."
    rows: 4
    min_chars: 20

自由文本方案上的 min_chars 下限做的是品質方面的工作,而不是格式方面的。一個沒有理由的風險評分事後無法裁定,而要求 20 個字元足以擋掉只填一個詞的情況,又不至於讓這個欄位變成負擔。

法庭檔案

法庭文件需要的實體集合與合同不同,因為這裡有用的單位是案件後設資料和論證的結構。把它們作為獨立的任務來做,而不是硬把合同方案拉過來覆蓋:

yaml
annotation_schemes:
  - annotation_type: span
    name: case_entities
    description: "Mark case metadata and the parties to the proceeding."
    labels:
      - name: CASE_NUMBER
        tooltip: "The docket or case identifier"
      - name: COURT
        tooltip: "Court name and jurisdiction"
      - name: JUDGE
      - name: PLAINTIFF
      - name: DEFENDANT
      - name: ATTORNEY
      - name: LEGAL_CITATION
        tooltip: "Citations to cases, statutes and regulations"
      - name: RULING
 
  - annotation_type: span
    name: argument_structure
    description: "Mark the claim, its support, and the court's conclusion."
    labels:
      - name: CLAIM
        color: "#FECACA"
      - name: PREMISE
        color: "#BBF7D0"
      - name: EVIDENCE
        color: "#BFDBFE"
      - name: REBUTTAL
        color: "#FED7AA"
      - name: CONCLUSION
        color: "#E0E7FF"

高亮那些真正起作用的措辭

一個班次裡讀到第二十份合同時,表示義務和條件的詞很容易被一眼掃過去,而它們恰恰是決定標籤的詞。Potato 會依據一份關鍵詞檔案來高亮這些詞,那是一個 CSV 檔案,其中 keyword 列是必需的,label、schema 和 color 列是可選的。* 匹配任意一串詞字元:

text
keyword,label,schema,color
shall,OBLIGATION,legal_entities,#FEE2E2
must,OBLIGATION,legal_entities,#FEE2E2
agrees to,OBLIGATION,legal_entities,#FEE2E2
may,CONDITION,legal_entities,#DBEAFE
unless,CONDITION,legal_entities,#DBEAFE
provided that,CONDITION,legal_entities,#DBEAFE
notwithstand*,CONDITION,legal_entities,#DBEAFE

在配置裡指向這個檔案,路徑相對於 task_dir:

yaml
keyword_highlights_file: data/legal_terms.csv

高亮會改變標註者的行為,如果你要衡量的正是人找出義務條款的能力,這就成了問題。keyword_highlight_settings 的應對辦法是隻顯示一部分匹配項,並混入一些干擾項,這樣標註記錄下來的就是標註者自己發現的內容,而不是關鍵詞列表標出來的內容:

yaml
keyword_highlight_settings:
  keyword_probability: 0.8       # show 80% of matched keywords
  random_word_probability: 0.05  # highlight ~5% of other words as distractors

專家任務的品質控制

法律標註把通常的眾包經濟學倒了過來。標註者稀缺而且昂貴,所以真正有用的控制手段是那些能儘早發現理解偏差的,而不是那些用來篩選大批人手的。

把資格認定放在最前面,做成一個培訓階段:標註者在接觸真實資料之前,先帶著反饋做一遍預先標好的例子。之後黃金標準會在整個過程中持續測量準確率;把反饋開啟,它們就成了持續的培訓訊號,而不是一次無聲的稽核:

yaml
num_annotators_per_item: 3
 
gold_standards:
  enabled: true
  items_file: data/gold_clauses.json
  mode: mixed
  frequency: 20
  accuracy:
    min_threshold: 0.85
    evaluation_count: 10
  feedback:
    show_correct_answer: true
    show_explanation: true

0.85 的準確率下限比通用任務會設的更高,這裡站得住腳的理由是出錯的代價,而不是標註者本身的什麼屬性。每個條目三位標註者值得這份開銷,理由也一樣。設計的另一半是你拿分歧怎麼辦。把有爭議的條款交給律師裁定,而不是用多數投票來解決,因為在法律任務上,非專家的多數意見並不構成證據。

注意力檢測在這裡不如在眾包任務上有用。領域專家不太可能在亂點,而你真正要防範的失效方式是對某條標註指南的一貫誤讀,這一點黃金條目能抓住,注意力檢測抓不住。

一份完整的配置

yaml
annotation_task_name: "Contract Clause Analysis"
task_description: "Classify contract clauses and mark the entities they refer to."
 
data_files:
  - data/contract_sections.json
 
item_properties:
  id_key: id
  text_key: text
 
instance_display:
  fields:
    - key: section_title
      type: text
    - key: text
      type: text
 
keyword_highlights_file: data/legal_terms.csv
 
keyword_highlight_settings:
  keyword_probability: 0.8       # show 80% of matched keywords
  random_word_probability: 0.05  # highlight ~5% of other words as distractors
 
annotation_schemes:
  - annotation_type: radio
    name: clause_type
    description: "What type of clause is this?"
    labels:
      - Grant of rights
      - Consideration and payment
      - Term and termination
      - Indemnification
      - Limitation of liability
      - Confidentiality
      - Other
 
  - annotation_type: span
    name: legal_entities
    description: "Mark the parties, defined terms, dates, amounts and obligations."
    labels:
      - name: PARTY
        color: "#FECACA"
      - name: DEFINED_TERM
        color: "#FDE68A"
      - name: MONETARY
        color: "#C4B5FD"
      - name: DATE
        color: "#BBF7D0"
      - name: OBLIGATION
        color: "#BFDBFE"
 
  - annotation_type: likert
    name: risk
    description: "How much risk does this clause carry for the receiving party?"
    size: 5
    min_label: "Low risk"
    max_label: "High risk"
 
  - annotation_type: text
    name: issues
    description: "Note any unusual or problematic language."
    rows: 4
    min_chars: 20
 
num_annotators_per_item: 3
 
gold_standards:
  enabled: true
  items_file: data/gold_clauses.json
  mode: mixed
  frequency: 20
  accuracy:
    min_threshold: 0.85
    evaluation_count: 10
 
agreement_metrics:
  enabled: true
  min_overlap: 2
 
output_annotation_dir: annotation_output

撰寫標註指南

在法律任務上,標註指南比方案本身分量更重,因為方案只給類別起了名字,而指南決定什麼歸入哪一類。指南里該寫四樣東西。

  • 範圍。 哪些文件類型、哪些管轄區、適用哪一部準據法。一種條款類型在英國法下的含義未必搬得過去。
  • 術語表。 用標註者自己日常使用的詞彙來定義每個標籤,並說明這個標籤不涵蓋哪些日常用詞。
  • 邊界規則。 寫明一個 span 從哪裡開始、到哪裡結束。表示義務的 span 要不要把觸發它的條件從句包含進來,還是隻包含義務本身?帶上一個例子把這個問題一次性回答清楚,一致性數字就會變。
  • 交叉引用的處理方式。 說明什麼時候要標註對其他章節的引用、什麼時候忽略,因為這是合同類任務中無聲分歧最常見的來源。

span 上的一致性與標籤上的一致性衡量方式不同,因為兩位標註者可以選中同一個實體類型,卻對它從哪裡開始有分歧。span 的一致性講了精確匹配和部分匹配,而 /admin/iaa 報告會把 span_f1_exact 和 span_f1_partial 一併給出,讓你看清出問題的是這兩者中的哪一個。

延伸閱讀