iT邦幫忙

2025 iThome 鐵人賽

0

用 Odoo 落地「去頭去尾、補中間、再回頭砍頭尾」:誠數據(Cheng Data)法規×AI 資料庫欄位設計白皮書

TL;DR
把「讀判決靠理由不靠輸贏」這套邏輯,落成 Odoo 的資料模型(models)欄位(fields)
先用結構化欄位把「中間的論證(ratio decidendi / 原則測試)」存好,再回頭把「事實(頭)與結果(尾)」對齊做一致性檢核,形成可追溯、可計算、可教學的誠數據資料庫。


1) 核心觀念 → 資料欄位的映射

  • 去頭(Facts 去雜):事實原文≠特徵;先去識別去洩漏(遮蔽結果詞彙)。
  • 去尾(Outcome 去惑):訓練/探索階段隔離標籤(勝敗/處置),避免倒因為果。
  • 補中間(Reasoning 補齊):把法院/學理的原則、測試、審查強度結構化(JSON/關聯表),並量化自由/福祉/德性三軸。
  • 回頭砍頭尾(Consistency):以反事實測試、洩漏掃描、跨域驗證欄位與排程,對齊「頭尾」與「中間」。

在 Odoo 裡,以上對應到一組自訂模組(Addon)+多個模型(Model)+欄位(Fields)+伺服器動作/排程(Cron)+記錄規則(Record Rules)。


2) Odoo 模組命名與資料命名

  • 模組名(技術名):cheng_legal_reasoner
  • 主模型前綴:cheng.(例:cheng.casecheng.rule
  • 資料庫(PostgreSQL)由 Odoo ORM 生成;我們只需專注於模型與欄位定義。

3) 重點資料模型(Models)與欄位(Fields)

A. cheng.case(案件主檔:承載頭/中/尾與治理)

欄位 型別 說明
name Char 案件可讀代號(顯示用)
case_id_external Char (indexed) 外部案號/識別碼
jurisdiction Selection 轄區(例:US_NJ、US_FL、TW_TP…)
court_level Selection 法院層級(trial/appeal/supreme)
decision_date Date (indexed) 判決日期
facts_raw Text 事實全文(原始)
facts_clean Text 去識別/去尾遮蔽後文本
issues One2many → cheng.issue 爭點清單
reasoning_ids One2many → cheng.reasoning 中間論證結構(多段)
rules_ids Many2many → cheng.rule 牽涉到的規則/測試
std_of_review Selection 審查強度(strict/intermediate/rationality/proportionality)
axis_freedom Float(0~1) 自由軸(向量化)
axis_welfare Float(0~1) 福祉軸(向量化)
axis_virtue Float(0~1) 德性軸(向量化)
holding_masked Boolean 是否已在文本中遮蔽結果詞
holding Selection 尾:處置/結果(label,訓練期隔離使用)
consistency_score Float 一致性評分(由檢核任務計算)
leakage_flags Integer 洩漏指標 bitmask(0=安全)
domain_shift_score Float 場域遷移穩定度(跨年度/轄區)
notes Html 人工備註與教學說明
state Selection 流程狀態(draft/cleaned/reasoned/validated/published)

B. cheng.issue(爭點)

欄位 型別 說明
case_id Many2one → cheng.case 所屬案件
title Char 爭點標題
description Text 爭點描述
importance Selection 重要度(low/med/high)

C. cheng.rule(規則/測試庫:可重用)

欄位 型別 說明
name Char 規則名稱(例:best_interest_child)
category Selection 類別(contract/constitutional/tort/procedural/ethics…)
elements_required Json 要件陣列
exceptions Json 例外陣列
std_of_review Selection 預設審查強度
authority_refs One2many → cheng.authority 法條/判例引用
active Boolean 是否啟用

D. cheng.authority(權威參照)

欄位 型別 說明
rule_id Many2one → cheng.rule 所屬規則
cite_text Char 引用簡述(例:NJ Supreme Court, 1988)
link Char URL / 來源
pinpoint Char 具體頁碼/段落

E. cheng.reasoning(中間論證段落:把文本變結構)

欄位 型別 說明
case_id Many2one → cheng.case 所屬案件
sequence Integer 段落順序
summary Text 論證小結
axes Json {freedom:0.6,welfare:0.8,virtue:0.3}
tests_passed Json 透過/未透過之測試要件
std_of_review_local Selection 本段採用審查強度
dissent_ref Boolean 是否涉及不同意見/協同意見
confidence Float 自動抽取/人工標註信心值

F. cheng.guardrail(治理與檢核:把「再回頭砍頭尾」制度化)

欄位 型別 說明
case_id Many2one → cheng.case 所屬案件
type Selection counterfactual / leakage_scan / domain_shift
payload Json 檢測的設定(例:把 economic_coercion=0)
result_score Float 分數/指標
passed Boolean 是否通過
log Html 詳細報告

4) 欄位設計準則(誠數據觀點)

  1. 分離文本與標籤facts_rawholding 物理分欄;在 facts_clean結果遮蔽holding_masked=True)。
  2. 把原則變成特徵:三軸(自由/福祉/德性)+規則/測試 JSON 化→可解釋特徵空間
  3. 把審查強度顯性化:全案/段落各自儲存 std_of_review,避免推理強度混淆。
  4. 把一致性變指標:把反事實、洩漏、遷移測試落為 cheng.guardrail 記錄;回填 consistency_scoreleakage_flags
  5. 資料生命週期:用 state 管理清洗、抽取、檢核、發布;每步保留審計軌(Odoo 自帶 chatter)。

5) Odoo 模組骨架(可直接放入 Odoo Addons)

版本:Odoo 16/17 皆可;如用 17 請調整 manifest version

5.1 __manifest__.py

python
{
"name": "Cheng Legal Reasoner",
"summary": "Law reasoning × AI features for case analysis (去頭去尾、補中間、回頭砍頭尾)",
"version": "16.0.1.0.0",
"author": "Cheng Data",
"depends": ["base", "mail"],
"data": [
"security/ir.model.access.csv",
"views/cheng_case_views.xml",
"views/cheng_rule_views.xml",
"views/cheng_guardrail_views.xml",
"data/ir_cron.xml"
],
"application": True,
}

5.2 models/init.py

from . import law_case
from . import law_rule
from . import law_guardrail

5.3 models/law_case.py

from odoo import models, fields, api
from odoo.exceptions import ValidationError
import json

STD = [
('strict','Strict Scrutiny'),
('intermediate','Intermediate'),
('rationality','Rational Basis'),
('proportionality','Proportionality')
]

class ChengCase(models.Model):
_name = "cheng.case"
_description = "Cheng Case"
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = "decision_date desc, id desc"

name = fields.Char(required=True, tracking=True)
case_id_external = fields.Char(index=True)
jurisdiction = fields.Selection([
    ('US_NJ','US - New Jersey'),
    ('US_FL','US - Florida'),
    ('TW_TP','Taiwan - Taipei'),
], index=True)
court_level = fields.Selection([
    ('trial','Trial'),('appeal','Appeal'),('supreme','Supreme')
], index=True)
decision_date = fields.Date(index=True)

facts_raw = fields.Text()
facts_clean = fields.Text()
holding_masked = fields.Boolean(default=False, tracking=True)

issue_ids = fields.One2many("cheng.issue","case_id")
reasoning_ids = fields.One2many("cheng.reasoning","case_id")
rule_ids = fields.Many2many("cheng.rule", "cheng_case_rule_rel", "case_id","rule_id")
std_of_review = fields.Selection(STD, tracking=True)

axis_freedom = fields.Float(digits=(3,2))
axis_welfare = fields.Float(digits=(3,2))
axis_virtue  = fields.Float(digits=(3,2))

holding = fields.Selection([
    ('affirm','Affirmed'),
    ('reverse','Reversed'),
    ('remand','Remanded'),
    ('mixed','Mixed'),
])

consistency_score = fields.Float(digits=(4,3))
leakage_flags = fields.Integer(default=0, help="bitmask, 0 = safe")
domain_shift_score = fields.Float(digits=(4,3))
notes = fields.Html()
state = fields.Selection([
    ('draft','Draft'),
    ('cleaned','Cleaned'),
    ('reasoned','Reasoned'),
    ('validated','Validated'),
    ('published','Published'),
], default='draft', tracking=True)

@api.constrains('axis_freedom','axis_welfare','axis_virtue')
def _check_axes(self):
    for rec in self:
        for v in [rec.axis_freedom, rec.axis_welfare, rec.axis_virtue]:
            if v and (v < 0 or v > 1):
                raise ValidationError("Axes must be between 0 and 1.")

class ChengIssue(models.Model):
_name = "cheng.issue"
_description = "Cheng Issue"

case_id = fields.Many2one("cheng.case", required=True, ondelete="cascade")
title = fields.Char(required=True)
description = fields.Text()
importance = fields.Selection([
    ('low','Low'),('med','Medium'),('high','High')
], default='med')

class ChengReasoning(models.Model):
_name = "cheng.reasoning"
_description = "Cheng Reasoning"

case_id = fields.Many2one("cheng.case", required=True, ondelete="cascade")
sequence = fields.Integer(default=10)
summary = fields.Text()
axes = fields.Json()  # {"freedom":0.6,"welfare":0.8,"virtue":0.3}
tests_passed = fields.Json()  # [{"rule":"best_interest_child","ok":true}]
std_of_review_local = fields.Selection(STD)
dissent_ref = fields.Boolean(default=False)
confidence = fields.Float(digits=(3,2))

5.4 models/law_rule.py

from odoo import models, fields

class ChengRule(models.Model):
_name = "cheng.rule"
_description = "Reusable Rules/Tests"

name = fields.Char(required=True)
category = fields.Selection([
    ('contract','Contract'),('constitutional','Constitutional'),
    ('tort','Tort'),('procedural','Procedural'),('ethics','Ethics')
], default='contract')
elements_required = fields.Json()  # ["info_asymmetry","economic_coercion"]
exceptions = fields.Json()         # ["public_policy_exception"]
std_of_review = fields.Selection([
    ('strict','Strict Scrutiny'),
    ('intermediate','Intermediate'),
    ('rationality','Rational Basis'),
    ('proportionality','Proportionality')
])
authority_ids = fields.One2many("cheng.authority","rule_id")
active = fields.Boolean(default=True)

class ChengAuthority(models.Model):
_name = "cheng.authority"
_description = "Authority Citations"

rule_id = fields.Many2one("cheng.rule", required=True, ondelete="cascade")
cite_text = fields.Char(required=True)
link = fields.Char()
pinpoint = fields.Char()

5.5 models/law_guardrail.py

from odoo import models, fields

class ChengGuardrail(models.Model):
_name = "cheng.guardrail"
_description = "Consistency & Leakage Checks"

case_id = fields.Many2one("cheng.case", required=True, ondelete="cascade")
type = fields.Selection([
    ('counterfactual','Counterfactual'),
    ('leakage_scan','Leakage Scan'),
    ('domain_shift','Domain Shift')
], required=True)
payload = fields.Json()   # e.g., {"economic_coercion":0}
result_score = fields.Float(digits=(4,3))
passed = fields.Boolean(default=False)
log = fields.Html()

5.6 security/ir.model.access.csv

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_case_user,access_case_user,model_cheng_case,base.group_user,1,1,1,0
access_issue_user,access_issue_user,model_cheng_issue,base.group_user,1,1,1,0
access_reasoning_user,access_reasoning_user,model_cheng_reasoning,base.group_user,1,1,1,0
access_rule_user,access_rule_user,model_cheng_rule,base.group_user,1,1,1,0
access_authority_user,access_authority_user,model_cheng_authority,base.group_user,1,1,1,0
access_guardrail_user,access_guardrail_user,model_cheng_guardrail,base.group_user,1,1,1,0

5.7 views/cheng_case_views.xml(表單重點)

5.8 views/cheng_rule_views.xml(規則庫)

5.9 views/cheng_guardrail_views.xml(一致性/洩漏檢核)

5.10 data/ir_cron.xml(排程:自動一致性檢核)

你可以在 cheng.case 加上 def _cron_consistency_check(self): 去呼叫內部的反事實測試與洩漏掃描,把結果寫回 cheng.guardrail 與 consistency_score、leakage_flags。


  1. 欄位如何支撐「誠數據」的 AI/報表
  1. 可解釋 AI:axis_* + tests_passed = 模型可用的人文可讀特徵。

  2. 可追溯管制:holding_masked+leakage_flags 確保不偷看答案。

  3. 可遷移評估:domain_shift_score 量化在跨年度/轄區的穩定性。

  4. 可迭代教學:reasoning_ids 的段落化摘要+信心值,讓學生、助教能對照法官推理。

  5. 可治理:cheng.guardrail 保留每次檢核的設定與日誌,形成審計軌。


  1. 典型作業流程(從草稿到發布)
  1. 草稿匯入:建立 cheng.case,填 facts_raw、case_id_external。

  2. 清洗:產生 facts_clean,設 holding_masked=True,進入 state=cleaned。

  3. 補中間:標註 issue_ids、reasoning_ids、rule_ids、axis_*、std_of_review → state=reasoned。

  4. 一致性檢核:排程建立 cheng.guardrail 記錄並回填指標 → state=validated。

  5. 發布/分析:產生儀表板(Pivot/Kanban/Graph),輸出教學報告/研究圖表 → state=published。


  1. 儀表板與報表指標建議

一致性漏斗:各 state 的案件數量與通過率。

三軸雷達:按法院/年度的自由-福祉-德性分布。

規則熱度:cheng.rule 被引用次數、與勝敗關聯。

洩漏零容忍:leakage_flags=0 比例;違規清單。

遷移健康度:domain_shift_score 趨勢。


  1. 延伸:把 LLM/向量資料接到 Odoo

在 cheng.reasoning.summary 上掛語意索引(外部向量資料庫或 Odoo 第三方插件),建立多視角檢索:

主審意見 / 不同意見 / 協同意見 → 不同向量空間(消融偏差)。

建 cheng.extraction_job(略),把抽取任務、Prompt、模型版本與結果落地(MLOps 追蹤)。


  1. 結語

把「先抓中間的論證,再校正頭尾」變成 Odoo 的資料欄位與流程設計,誠數據資料庫就能同時滿足法學可讀性與AI 可計算性:

規則可重用(cheng.rule)、論證可量化(axis_* / tests_passed)、結果可隔離(holding_masked)、一致性可證明(cheng.guardrail)。
一句話:先把「道理」變資料,再讓資料推動更好的道理。


上一篇
從營運效率到社會責任:Odoo 企業資源規劃系統與企業社會責任的商業論證
系列文
以 Odoo 雲端進銷存為核心,探索小型企業數位轉型新方向: 從進銷存、CRM 到 IoT 應用結合開源50
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言