合同審查輔助
合同審查輔助用兩檔模型:主力模型抽取關鍵條款、給業務負責人寫摘要,更強的模型對照公司的審查清單(playbook)逐條標出風險條款,並說明修改稿改了什麼。結果是給法務和律師的參考,不構成法律意見,最終由律師判斷。按每月 300 份合同、其中 100 份需要比對修改稿估算,用各模型最低價分組的即時價格計算,模型費用每月約 ¥40.72。
價格更新於 2026年11月13日 下午6:03
月成本估算
假設:每月審查 300 份合同,平均每份約 1.5 萬 tokens(中文約 1.5 萬字);條款抽取與摘要每份輸入約 1.6 萬 tokens、輸出約 1,500 tokens;風險審查每份輸入約 2 萬 tokens(合同 1.5 萬、審查清單 4,000、指令 1,000),輸出約 2,000 tokens;其中 100 份有修改稿需要比對,每次輸入約 6,000 tokens,輸出約 1,000 tokens。
業務問題
銷售、採購、合作合同越籤越多,法務每份都要從頭讀一遍:付款條件、違約責任、責任上限、解約條款、爭議解決。對方改一版發回來,還要逐段找改了哪裡。業務部門等著簽字,法務很容易成為瓶頸。
直接把合同丟給大模型問「有沒有風險」,得到的往往是泛泛的提醒,和公司自己的底線對不上;模型還可能引用合同里根本沒有的句子,或者漏掉關鍵的一條。
更可靠的做法是把公司的審查標準寫成清單,讓模型逐條對照、引用原文、說明理由,程式核對引用是否真的出自合同,最後由律師確認。模型負責先把需要關注的地方找出來,判斷和決定仍然由律師作出。
推薦模型組合
推薦模型按即時目錄自動選取,價格取各模型最低價分組,更新於 2026年11月13日 下午6:03。點模型名可檢視全部分組價格。
條款抽取與業務摘要(主力模型)
qwen3.5-plus通義千問
輸入 ¥1.12 / 輸出 ¥6.72 每百萬 tokens國產模型分組
每份合同都先過這一步:抽出主體、金額、期限、付款、違約、解約、爭議解決等關鍵條款,按 JSON 返回,再寫一段給業務負責人看的白話摘要。讀長文、寫短文,輸入 tokens 佔大頭。
風險審查與版本比對(更強的模型)
Claude Sonnet 5.5Anthropic
輸入 ¥3.2 / 輸出 ¥16 每百萬 tokensClaude 經濟分組
對照審查清單逐條判斷,要在長合同裡準確找到對應條款並說明理由,是整個流程裡最需要判斷力的一步,用更強的模型。合同、清單和指令放在同一次請求裡,輸入常在 2 萬 tokens 左右,單次請求能放多長,以所選模型官方公佈的上下文長度為準。
參考架構
- 1
寫審查清單
法務把公司的審查標準寫成清單(playbook):每條有編號、主題、我方標準立場和不能接受的底線,比如「我方責任上限不超過合同金額」。清單是模型判斷的依據,寫得越具體,結果越穩定。
- 2
解析與切分
Word 和帶文字層的 PDF 用程式提取文本,保留條款編號;掃描件先轉成文字。特別長的合同按章節拆開分別審查,再合併結果。
- 3
條款抽取與摘要
主力模型按固定欄位抽取關鍵條款並返回 JSON,再寫一段給業務負責人的摘要:我們要付出什麼、得到什麼、主要風險在哪裡。
- 4
對照清單審查
更強的模型拿合同全文和審查清單逐條比對,每條發現都給出清單編號、條款號、原文引用、風險等級和修改建議;清單裡有、合同裡缺的條款也列出來。程式再檢查每條引用能否在原文裡找到,找不到的標記出來請律師重點核對。
- 5
版本比對
對方發回修改稿時,先用程式做文本比對找出改動的段落,只把改動前後的內容交給模型,讓它說明每處改動對哪一方有利、涉及清單裡的哪一條。
- 6
律師確認
審查意見、修改建議和摘要都標明是模型輔助生成,由律師確認後再發給業務部門或對方;律師的修改意見可以反過來補進審查清單。
成本估算
假設:每月審查 300 份合同,平均每份約 1.5 萬 tokens(中文約 1.5 萬字);條款抽取與摘要每份輸入約 1.6 萬 tokens、輸出約 1,500 tokens;風險審查每份輸入約 2 萬 tokens(合同 1.5 萬、審查清單 4,000、指令 1,000),輸出約 2,000 tokens;其中 100 份有修改稿需要比對,每次輸入約 6,000 tokens,輸出約 1,000 tokens。
| 專案 | 模型 | 用量假設 | 費用 |
|---|---|---|---|
| 條款抽取與業務摘要 | qwen3.5-plus | 300 次 × 輸入 16,000 + 輸出 1,500 tokens | ¥8.4 |
| 對照清單的風險審查 | Claude Sonnet 5.5 | 300 次 × 輸入 20,000 + 輸出 2,000 tokens | ¥28.8 |
| 修改稿比對 | Claude Sonnet 5.5 | 100 次 × 輸入 6,000 + 輸出 1,000 tokens | ¥3.52 |
| 合計(每月) | ¥40.72 | ||
按各模型最低價分組的即時價格計算,價格更新於 2026年11月13日 下午6:03。
只含模型呼叫費用,不含律師審核和文本解析成本。審查清單放在提示詞開頭、每次請求都不變,所選模型支援上下文快取時,命中快取的部分按更低的快取讀取價計費,實際費用會更低。表中按最低價分組計算;如果給合同審查單獨選了官方來源的分組,按該分組的價格重新估算。合同越長、份數越多,費用大致按比例增加。
示例程式碼
審查清單寫成結構化資料,模型按清單返回帶原文引用的發現,程式核對引用是否出自合同;版本比對先用 difflib 找出改動的段落,只把改動交給模型解釋。
import difflib
import json
import os
from openai import OpenAI
client = OpenAI(base_url="https://www.tutujin.com/v1", api_key=os.environ["TUTUJIN_API_KEY"])
# The company playbook, written by your legal team: one entry per rule.
PLAYBOOK = [
{"id": "LIAB-1", "topic": "limitation of liability", "standard": "Our total liability is capped at the contract value.", "red_line": "Unlimited liability for us."},
{"id": "PAY-1", "topic": "payment terms", "standard": "We pay within 30 days of a valid invoice.", "red_line": "Payment due in under 15 days or prepayment over 30%."},
{"id": "TERM-1", "topic": "termination", "standard": "Either party may terminate with 30 days of written notice.", "red_line": "Only the other party may terminate for convenience."},
]
RULES = "Playbook:\n" + json.dumps(PLAYBOOK, ensure_ascii=False)
def ask(system, user):
resp = client.chat.completions.create(
model="claude-sonnet-5-5",
messages=[{"role": "system", "content": system + "\n\n" + RULES}, {"role": "user", "content": user}],
temperature=0,
)
return resp.choices[0].message.content
def review(contract):
raw = ask(
"You help a company lawyer review contracts against the playbook. For every clause that departs from a rule "
"or crosses a red line, and for every playbook topic the contract does not cover, return one finding. "
'Reply with JSON only: {"findings": [{"rule_id": "", "clause": "clause number", "quote": "exact words copied '
'from the contract, empty if missing", "risk": "high|medium|low", "reason": "", "suggestion": ""}]}. '
"Do not give legal advice; the lawyer decides.",
contract,
)
findings = json.loads(raw[raw.find("{"): raw.rfind("}") + 1])["findings"]
for f in findings:
# a quote that cannot be found in the contract must be checked by the lawyer, never trusted
f["quote_found"] = f["quote"] == "" or f["quote"] in contract
return findings
def explain_changes(old, new):
"""Diff in code first, so the model only reads the paragraphs that changed."""
a, b = old.splitlines(), new.splitlines()
changes = [
"BEFORE:\n" + "\n".join(a[i1:i2]) + "\nAFTER:\n" + "\n".join(b[j1:j2])
for op, i1, i2, j1, j2 in difflib.SequenceMatcher(None, a, b).get_opcodes()
if op != "equal"
]
return ask(
"For each change, say in one or two sentences what changed, which party it favours "
"and which playbook rule it touches, if any.",
"\n\n".join(changes),
)
with open("contract_v1.txt", encoding="utf-8") as f1, open("contract_v2.txt", encoding="utf-8") as f2:
v1, v2 = f1.read(), f2.read()
for item in review(v2):
print(item["risk"], item["rule_id"], item["clause"], "" if item["quote_found"] else "QUOTE NOT FOUND - check by hand")
print(explain_changes(v1, v2))常見問題
每月審查 300 份合同,模型費用大概多少?
按每份約 1.5 萬 tokens、每份都做條款抽取和風險審查、其中 100 份比對修改稿估算,用最低價分組計算約 ¥40.72。合同長度和審查份數對費用影響最大。
模型的審查結果能當作法律意見嗎?
不能。模型的輸出是給法務和律師的參考,幫你先把需要關注的條款找出來,整理好理由和原文引用。它可能漏掉風險、誤解條款含義,也不瞭解交易背景,最終判斷和對外意見必須由律師作出。
為什麼要先寫審查清單?
沒有清單,模型只能給出泛泛的風險提示,和公司的實際底線對不上。清單把我們能接受什麼、不能接受什麼寫清楚,模型逐條對照,結果才能比較、能複核;清單也可以隨著律師的意見不斷補充。
合同太長,一次放不下怎麼辦?
單次請求能放多少內容,以所選模型官方公佈的上下文長度為準。超長合同按章節拆開分別審查,每段都帶上審查清單,最後合併結果;也可以只把和清單主題相關的章節交給審查模型。
合同裡的商業機密和個人資訊怎麼處理?
請求會經本站轉發給模型服務處理。建議先隱去對方名稱、身份證號、銀行帳號等不影響審查的資訊再提交;對線路來源有要求的,可以給合同審查單獨建一把 Key,選官方來源的分組,模型詳情頁列出了每個模型可用的分組。能否使用,請按你們自己的保密和資料合規要求評估。
掃描版合同能審嗎?
可以,先把掃描件轉成文字再審。識圖模型讀取掃描件的做法見文件解析與資訊抽取方案;轉出來的文字要核對一遍,數字和日期最容易出錯。
