Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
ccran
/
lufa-contract
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
4766f9df
authored
Jul 03, 2026
by
ccran
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 麓发标准替换成通用sheet
parent
42b23279
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
40 additions
and
10 deletions
+40
-10
core/finding_preprocessor.py
+28
-8
data/benchmark/eval.py
+12
-2
data/rules.xlsx
+0
-0
No files found.
core/finding_preprocessor.py
View file @
4766f9df
...
...
@@ -11,29 +11,42 @@ if TYPE_CHECKING:
logger
=
logging
.
getLogger
(
__name__
)
FINDING_PREPROCESSOR_SYSTEM_PROMPT
=
"""你是合同审查结果文本处理助手。
你的任务是严格按照给定的处理要求修改建议文本。
只允许执行明确要求的文字调整,不得补充、删减、解释或改写其他内容。
返回 JSON 对象,格式为:{"suggestion": "处理后的建议文本"}。"""
FINDING_PREPROCESSOR_SYSTEM_PROMPT
=
"""你是合同审查建议的文本微调助手。
必须以原始建议为底稿,只对处理要求明确涉及的局部文字做细微调整。
不得重写整段建议,不得补充、删减、扩写、总结或解释其他内容。
合同原文是判断现有条款内容的唯一依据。必须区分建议中引用的原文和建议修改后的目标文本:
1. “将A修改为B”“把A替换为B”“删除A”等表述中的 A 是原文定位文本,必须是合同原文中实际存在的连续文本;
2. 如果 A 与合同原文不一致,只能依据合同原文将 A 校正为对应的原文文本,不得虚构;
3. 处理要求只作用于 B 等修改后的目标文本,不得错误修改作为定位依据的 A;
4. 建议直接给出拟新增或修改后的条款时,处理要求作用于该拟定文本。
suggestion 的值必须是连续的纯文本,不得包含标题、项目符号、编号列表、加粗、
引用、代码块、链接等任何 Markdown 格式。
只返回 JSON 对象,格式为:{"suggestion": "微调后的纯文本建议"}。"""
FINDING_PREPROCESSOR_USER_PROMPT
=
"""请处理以下合同审查建议:
审查项:{rule_title}
处理要求:{processing_requirement}
合同原文(仅供理解上下文,不得修改或输出):{original_text}
原始建议:{suggestion}
请仅返回 JSON 对象。"""
除处理要求涉及的局部文字外,字词、标点和语序均须保持不变。
请仅返回 JSON 对象,suggestion 中不得使用任何 Markdown 格式。"""
class
FindingPreprocessor
:
"""在 finding 入库前按审查项执行文本处理。"""
_LLM_PROCESSING_REQUIREMENTS
=
{
"安装调试审查"
:
"将建议文本中的“指导”替换为“支持”,其他内容保持不变。"
,
"安装调试与指导审查"
:
(
"拟新增或修改后的目标文本不得使用“指导”,应改用“支持”。"
"如果建议采用“将A修改为B”等表达,A 必须保持为合同原文中实际存在的文本,"
"只将 B 中的“指导”调整为“支持”;其他内容保持不变。"
),
}
_SUGGESTION_REPLACEMENTS
=
{
"安装调试审查"
:
{
"安装调试
与指导
审查"
:
{
"指导"
:
"支持"
,
},
}
...
...
@@ -41,13 +54,16 @@ class FindingPreprocessor:
def
__init__
(
self
,
llm_tool
:
LLMTool
|
None
=
None
)
->
None
:
self
.
_llm_tool
=
llm_tool
def
process
(
self
,
finding
:
Finding
,
use_rule
=
Tru
e
)
->
Finding
:
def
process
(
self
,
finding
:
Finding
,
use_rule
:
bool
=
Fals
e
)
->
Finding
:
"""优先使用 LLM 处理,调用失败时回退到确定性规则。"""
if
use_rule
:
return
self
.
process_with_rules
(
finding
)
return
self
.
process_with_llm
(
finding
)
def
process_with_llm
(
self
,
finding
:
Finding
)
->
Finding
:
if
finding
.
result
!=
"不合格"
:
return
finding
rule_title
=
(
finding
.
rule_title
or
""
)
.
strip
()
requirement
=
self
.
_LLM_PROCESSING_REQUIREMENTS
.
get
(
rule_title
)
if
not
requirement
or
not
finding
.
suggestion
:
...
...
@@ -56,6 +72,7 @@ class FindingPreprocessor:
user_content
=
FINDING_PREPROCESSOR_USER_PROMPT
.
format
(
rule_title
=
rule_title
,
processing_requirement
=
requirement
,
original_text
=
json
.
dumps
(
finding
.
original_text
or
""
,
ensure_ascii
=
False
),
suggestion
=
json
.
dumps
(
finding
.
suggestion
,
ensure_ascii
=
False
),
)
...
...
@@ -80,6 +97,9 @@ class FindingPreprocessor:
return
self
.
process_with_rules
(
finding
)
def
process_with_rules
(
self
,
finding
:
Finding
)
->
Finding
:
if
finding
.
result
!=
"不合格"
:
return
finding
replacements
=
self
.
_SUGGESTION_REPLACEMENTS
.
get
(
(
finding
.
rule_title
or
""
)
.
strip
(),
{}
)
...
...
data/benchmark/eval.py
View file @
4766f9df
...
...
@@ -2,6 +2,7 @@ from __future__ import annotations
import
argparse
import
re
from
contextlib
import
redirect_stdout
from
pathlib
import
Path
from
typing
import
Iterable
...
...
@@ -86,8 +87,17 @@ def extract_annotaion(
def
compare_annotaion
(
val_dir
:
Path
,
answer_dir
:
Path
)
->
None
:
"""Run benchmark comparison on extracted annotations."""
output_excel
=
compare
(
val_dir
=
val_dir
,
answer_dir
=
answer_dir
)
log_file
=
val_dir
.
with_suffix
(
".log"
)
log_file
.
parent
.
mkdir
(
parents
=
True
,
exist_ok
=
True
)
with
log_file
.
open
(
"w"
,
encoding
=
"utf-8"
)
as
log_output
:
with
redirect_stdout
(
log_output
):
output_excel
=
compare
(
val_dir
=
val_dir
,
answer_dir
=
answer_dir
,
print_result
=
True
,
)
print
(
f
"Compare result written to: {output_excel}"
)
print
(
f
"Compare log written to: {log_file}"
)
def
_strip_suffix_once
(
stem
:
str
,
suffixes
:
Iterable
[
str
])
->
str
:
...
...
@@ -121,7 +131,7 @@ def _parse_args() -> argparse.Namespace:
parser
.
add_argument
(
"--datasets-dir"
,
type
=
Path
,
default
=
base
/
"results"
/
"jp-output-
lufa-20260514-182859
"
,
default
=
base
/
"results"
/
"jp-output-
20260701-144647-280297
"
,
help
=
"Directory containing Word files with annotations."
,
)
parser
.
add_argument
(
...
...
data/rules.xlsx
View file @
4766f9df
No preview for this file type
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment