forked from Miracle-2001/SimCourt_old
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathagent.py
More file actions
799 lines (690 loc) · 50.4 KB
/
agent.py
File metadata and controls
799 lines (690 loc) · 50.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
from typing import List, Dict, Any, Tuple
import re
import json
from LLM.deli_client import search_law
import uuid
import logging
import requests
from langchain_community.vectorstores import Chroma
from langchain_huggingface import HuggingFaceEmbeddings
from frontEnd import simplify
import sys
import os
# sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
law_repository={}
with open(os.path.abspath(os.path.join(os.path.dirname(__file__),"resource/law.json")), 'r', encoding='utf-8') as f:
law_repository=json.load(f)
def extract_bracket_content(text):
# 정규 표현식으로 【】 및 내부 내용 매치
pattern = r'【(.*?)】'
# findall 메서드를 사용하여 모든 매치되는 내용 찾기
contents = re.findall(pattern, text)
return contents
class Context:
def __init__(self,content):
self.content=content
self.evidence={
"검찰":"",
"변호인":""
}
def add_prosecution_evidence(self,item:str):
if isinstance(item, list):
item = "".join(str(x) for x in item)
self.evidence["검찰"] += item
def add_advocate_evidence(self,item:str):
if isinstance(item, list):
item = "".join(str(x) for x in item)
self.evidence["변호인"] += item
class Agent:
def __init__(
self,
id: int,
name: str,
role: str,
description: str,
llm: Any,
# db: Any,
# log_think=False,
):
self.id = id
self.name = name
self.role = role
self.basic_description = description
self.instruction=description
self.llm = llm
self.goal=""
CHROMA_PATH = "./resource/chroma"
# embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2")
# self.db= Chroma(persist_directory=CHROMA_PATH, embedding_function=embeddings)
self.evidence_pool={
"검찰이 제시한":"",
"변호인이 제시한":""
}
self.memory=""
# {
# "재판장":"",
# "검사":"",
# "변호인":"",
# "피고인":""
# }
self.search_pool=None
self.crime3aspect="""
피고인이 범죄를 저질렀는지 판단할 때는 다음 세 가지 관점을 고려해야 합니다:
**세 관점이 모두 성립하고, 직접적인 인과관계가 있을 때만 죄명이 진정 성립됩니다**
1. 구성요건 해당성:
행위주체:1、3단계이론은 연령, 책임능력을 구분하지 않음;2、신분범의 개념. 진정신분범:신분은 범죄구성조건, 예를 들어 횡령죄. 부진정신분범, 신분은 양형에 영향을 주는 조건, 예를 들어 감금죄. 3、단위:주관:전체의지;객관:전체를 위한 이익추구, 예를 들어 국유재산 사분
행위:(1)작위(2)부작위:의무출처:1.위험원에 대한 감독의무, 관리 담당 위험물, 감독의무자의 행동. 자신의 선행행위. 2.법익에 대한 보호의무의 특정관계. 법률규정 특정관계, 계약관계, 직무업무 설립, 자발적 수락행위. (독일은 피해자 자초위험 배제) 3、특정영역, 관리자와 의존관계 발생.
결과:고의범죄:위험발생은 성립조건, 결과발생은 기수조건. 과실범죄 실해결과는 범죄성립조건
인과관계:1.법률이 허용하지 않는 위험을 조성;2.형법이 방지하려는 결과발생;3.위험의 실현:개입요소가 존재한다면, 개입요소와 선행행위의 관계, 중첩관계인지 독립관계인지 분석해야 함?
2. 위법성
정당방위:(1)정당방위의 조건:1.기인조건:불법적이고, "현실적이며", 긴박한 불법침해여야 함. 2、불법침해자를 대상으로 실시. 불법침해가 진행 중임을 인식하고, 의식적으로 불법침해에 반격. 3명백히 필요한 한도를 초과하면 안됨. (2)특수방위:행위제한은 진행 중인 행흉, 강도, 강간, 납치 및 기타 신체안전을 심각히 위협하는 폭력범죄로, 불법침해자에게 상해를 입히거나 사망케 한 경우, 방위과당에 속하지 않음.
긴급피난:(1)조건:1.기인조건:객관적이고 구체적인 법익위험, 국가·공공이익도 가능;현재성 보유:긴박하게 즉시 발생할 위험, 및 일정시간 내 언제든 발생가능한 지속성 위험. 행위조건:다른 법익을 희생하는 행위가 위험을 피하기 위해 필요하며 보충성 요건. 피난의식:객관적 위법론:피난의식 고려하지 않음, 우연피난도 긴급피난에 속함. 주관적 위법론:위험 및 피난을 통해 법익손실을 피할 수 있다는 사실에 대한 인식을 요구.
기타:(1)자구행위(2)정당업무행위(3)의무충돌(4)피해자승낙
3. 책임
주관적 요건: (1) 범의:자신의 행위가 사회에 해로운 결과를 발생시킬 것임을 알면서도 그러한 결과의 발생을 희망하거나 방임하는 것. (2) 과실:자신의 행위가 사회에 해로운 결과를 발생시킬 가능성이 있음을 예견할 수 있었음에도 소홀히 하여 예견하지 못했거나, 이미 예견했으나 경솔히 피할 수 있다고 생각하여 그러한 결과를 발생시킨 것.
책임조각사유:(1)책임연령:【연령이 책임능력에 미치는 영향】만 16세에 달한 자가 범죄를 저지른 때에는 형사책임을 져야 함.
만 14세 이상 16세 미만인 자가 고의살인, 고의상해치사상, 강간, 강도, 마약판매, 방화, 폭발, 위험물질투방죄를 저지른 때에는 형사책임을 져야 함. 만 14세 이상 18세 미만인 자가 범죄를 저지른 때에는 경감하거나 감경처벌해야 함. 만 16세 미만으로 형사처벌하지 않는 경우, 그의 가장이나 후견인이 관교하도록 책임지우며: 필요시 정부가 수용교양할 수도 있음.
>제17조의1【연령이 고령자 책임능력에 미치는 영향】만 75세에 달한 자가 고의범죄를 저지른 때에는 경감하거나 감경처벌할 수 있음: 과실범죄의 경우에는 경감하거나 감경처벌해야 함. (2)책임능력:제18조 【정신장애가 책임능력에 미치는 영향】정신병자가 자신의 행위를 변별하거나 통제할 수 없는 상태에서 해로운 결과를 야기한 경우, 법정절차에 의해 감정확인되면 형사책임을 지지 않되, 그의 가족이나 후견인이 엄격히 감시하고 치료하도록 책임져야 하며; 필요시 정부가 강제치료함. 간헐성 정신병자가 정신이 정상인 때 범죄를 저지른 경우에는 형사책임을 져야 함. 아직 완전히 자신의 행위를 변별하거나 통제할 능력을 상실하지 않은 정신병자가 범죄를 저지른 때에는 형사책임을 져야 하되, 경감하거나 감경처벌할 수 있음. 취중인 자가 범죄를 저지른 때에는 형사책임을 져야 함. 제19조 【청각·시각기능이 책임능력에 미치는 영향】농아인이나 맹인이 범죄를 저지른 때에는 경감, 감경하거나 처벌을 면제할 수 있음. (3)위법성인식착오:행위자가 위법을 인식할 능력을 보유하고, 행위자가 법적 속성을 고찰할 기회를 보유; 행위자가 위법성을 인식할 가능성을 이용하기를 기대할 수 있음. (4)기대가능성:사회 통상인의 상황에 근거하여, 당시 환경에서 행위자와 동일한 행위를 할 수 있는지를 판단기준으로 하는 것이 상대적으로 합리적임.
"""
self.current_plan=None
self.current_answer=None
# self.db = db
# self.log_think = log_think
# self.instruction=None
# self.logger = logging.getLogger(__name__)
def set_instruction(self,text):
self.instruction=self.basic_description+text
def __str__(self):
return f"{self.name} ({self.role})"
def update_evidence(self,context:Context):
return
self.evidence_pool["검찰이 제시한"]+=context.evidence["검찰"]
self.evidence_pool["변호인이 제시한"]+=context.evidence["변호인"]
def check_hallucination(self,context:Context):
self.strategy=self.speak("최신의 법정기록:"+context.content+"법정인원 발언기록 요약:"+str(self.memory)+"현재의 증거:"+str(self.evidence_pool)+"현재의 전략:"+str(self.strategy),
"""
법정에서는 사실을 있는 그대로 말해야 합니다! 무중생유해서는 안 됩니다! 언급되지 않은 내용은 증거로 사용할 수 없고, 전략으로 사용할 수도 없습니다!
최신 법정기록, 발언기록 요약, 증거에 근거하여 【현재의 전략】에서 무중생유하거나 사실을 조작한 발언이 있는지 검토하시오.
예를 들어, 피고인이 손해를 배상하거나 용서를 받았다는 정보가 없다면, 해당하는 전략이 있어서는 안 됩니다!
만약 있다면, 관련 내용을 직접 삭제하시오.
만약 어떤 전략의 관련 허위 내용을 삭제한 후, 해당 항목에 실질적인 내용이 없다면, 그 항목도 함께 삭제하시오.
만약 무중생유하거나 사실을 조작한 발언을 발견하지 못했다면, 수정할 필요가 없습니다.
수정 흔적을 남기지 마시오! 추가 설명이나 주석도 필요 없습니다!
수정이 완료된 전략을 답변하시오. (여전히 항목별로 구분)
원래 형식을 그대로 유지하시오:
공격전략:1.xxx2.xxx3.xxx
방어전략:1.xxx2.xxx3.xxx
"""
)
def check_speak_hallucination(self,context,response):
res=self.speak("최신의 법정기록:"+context+"법정인원 발언기록 요약:"+str(self.memory)+"현재의 증거:"+str(self.evidence_pool)+"예정된 발언내용:"+response,
"""
법정에서는 사실을 있는 그대로 말해야 합니다! 무중생유해서는 안 됩니다! 논증되지 않은 내용은 발언내용으로 사용할 수 없습니다!
최신 법정기록, 발언기록 요약, 증거에 근거하여 【예정된 발언내용】에서 무중생유하거나 사실을 조작한 발언(즉 환각)이 있는지 검토하시오.
예를 들어, 피고인이 손해를 배상하거나 용서를 받았다는 정보가 없는데 【예정된 발언내용】에 해당하는 문구가 나타났다면, 환각이 발생했음을 나타냅니다.
또는 수액과 증거 및 앞선 토론내용이 일치하지 않는다면, 환각이 발생했음을 나타냅니다.
환각이 있으면 '있음' 한 글자를, 없으면 '없음' 한 글자를 반환하시오 (따옴표 없이)
불필요한 말은 하지 마시오!
""",check=False
)
return res
# --- Plan Phase --- #
def reflect_and_update(self,context:Context,summary=True):
if self.role=="재판장":
# res=self.speak("最新的庭审记录:"+context.content+"法庭人员发言记录总结:"+str(self.memory)+"目前的证据:"+str(self.evidence_pool)+"目前的辩论焦点:"+str(self.debate_focus),
# """
# 你要根据输入的信息,进一步调整/更新辩论焦点。
# """+self.strategy_prompt+
# """
# 辩论焦点从1开始编号
# 请严格按照以下格式回复:
# 1.法庭辩论焦点2.法庭辩论焦点3.法庭辩论焦点
# """
# )
info="기소서:"+self.prosecution_statement+"피고인 정보:"+self.defendant_information+"법정인원 발언기록 요약:"+str(self.memory)+"최신의 법정기록:"+context.content+"현재의 증거:"+str(self.evidence_pool)+"현재의 논쟁쟁점과 확명상황:"+str(self.debate_focus)
task="""
재판장으로서 귀하는 사건의 사실을 확명해야 합니다. 귀하의 임무는 다음과 같습니다:
(1) 귀하는 입력된 정보, 현재의 논쟁쟁점과 확명상황에 근거하여 논쟁쟁점을 추가로 조정/업데이트해야 합니다.
"""+self.strategy_prompt+"""
(2) 논쟁쟁점을 조정/업데이트하는 것 외에도, 귀하는 입력된 정보, 업데이트된 논쟁쟁점, 이전의 확명상황에 근거하여 현재 각 쟁점의 **확명상황**을 요약해야 합니다.
"""
QA_pair=self.plan(info+task)
self.init_QA_pair.update(QA_pair)
res=self.speak(info+"참고자료:"+str(self.init_QA_pair),
"""
재판장으로서 귀하는 사건의 사실을 확명해야 합니다. 귀하의 임무는 다음과 같습니다:
(1) 귀하는 입력된 정보, 현재의 논쟁쟁점과 확명상황에 근거하여 논쟁쟁점을 추가로 조정/업데이트해야 합니다.
"""+self.strategy_prompt+
"""
(2) 논쟁쟁점을 조정/업데이트하는 것 외에도, 귀하는 입력된 정보, 업데이트된 논쟁쟁점, 이전의 확명상황에 근거하여 현재 각 쟁점의 **확명상황**을 요약해야 합니다.
**확명상황**은 공소측과 변호측이 이 쟁점에 대한 토론 상황의 개요, 토론이 충분한지 여부, 그리고 재판장으로서의 귀하의 소견입니다.
**간략하게 설명하시면 됩니다.**
최종적으로 엄격히 다음 형식에 따라 답변하시오:
논쟁쟁점은 1번부터 번호를 매기고, 확명상황을 바로 이어 작성합니다.
엄격히 다음 형식에 따라 답변하시오:
1.법정 논쟁쟁점. 확명상황.
2.법정 논쟁쟁점. 확명상황.
3.법정 논쟁쟁점. 확명상황.
예시:
1.피고인의 자수 성립 여부...공소인은 자수가 성립하지 않는다고 보며, xxx를 통해 입증; 변호인은 자수가 성립한다고 하며, xxx를 제시. 재판장은 피고인의 자수가 성립한다고 보는데, 이는 xxx 때문
2.증거 xx에서 언급된 xxx와 본 사건의 관련성 여부에 대해, 공범 양측이 각각 xxx로 인식하고 있으며, 재판장은 추가 토론이 필요하다고 보고 있음.
"""
)
self.debate_focus=res
else:
info="기소서:"+self.prosecution_statement+"피고인 정보:"+self.defendant_information+"이전 법정인원 발언기록 요약:"+str(self.memory)+"최신의 법정기록:"+context.content+"현재의 증거:"+str(self.evidence_pool)+"설정된 목표:"+self.goal+"현재의 전략:"+str(self.strategy)
task="""
귀하는 입력된 정보에 근거하여 전략을 추가로 조정/업데이트해야 합니다.
"""+self.strategy_prompt
QA_pair=self.plan(info+task)
self.init_QA_pair.update(QA_pair)
res=self.speak(info+"참고자료:"+str(self.init_QA_pair),
"""
귀하는 입력된 정보에 근거하여 전략을 추가로 조정/업데이트해야 합니다.
"""+self.strategy_prompt+
"""
귀하의 답변은 엄격히 다음 형식에 따라야 합니다(항목별 기술):
공격전략:1.xxx2.xxx3.xxx
방어전략:1.xxx2.xxx3.xxx
각 항목의 형식은 다음과 같습니다:
xxx(전략내용), 참고법조:xxx(법조명칭 및 내용요약), 참고사례:xxx(사례번호 및 내용요약)
법조와 사례가 없거나, 관례상 일반적인 전략의 경우에는 이러한 참고를 추가할 필요가 없습니다.
【주의】
1.주의하시오, 전략은 실사구시하고 실제에 부합해야 합니다! 무중생유해서는 안 됩니다!
2.형식에 따라 직접 반환하시오, 불필요한 말은 하지 마시오
3.각 전략에 대해, **해당 전략을 뒷받침할 수 있는 참고법조 및 유사사례 정보를 붙이시오**, (제공된 참고자료에서 가져오며, 없으면 추가하지 말아도 됨)
4.전략을 추가로 조정하되, 이전 전략과 합리적으로 수정하여야 하며, 단순히 복사하거나 전면 부정해서는 안 됩니다.
"""
)
self.strategy=res
self.check_hallucination(context)
if self.role=="재판장" or simplify==False:
# tmp=""
# if self.memory!="":
# tmp+="之前的庭审总结"+str(self.memory)
tmp="최신의 법정기록:"+context.content
res=self.speak(tmp,
"""
귀하는 최신 법정기록에 근거하여 이 부분의 법정요약을 작성해야 합니다.
(1) 법정요약에는 다음이 포함되어야 합니다: 시간순서대로 발생한, 【최종 유죄양형에 영향을 줄 수 있는 사건】의 개요와 요약.
절차적, 반복적, 사건과 무관, 재판장의 정리발언 등 【실질적 내용이 없는 발언】은 생략해야 합니다!
예시:
법정준비단계, 재판장이 피고인 xxx에 대해 문의, 피고인이 xx라고 답변
법정조사단계, 공소인이 차례로 xxx에 대해 질문, 피고인이 xxx라고 답변, 변호인이 xxx에 대해 질문, 피고인이 xxx라고 답변
**주의:**
1.이 단계의 요약만 반환하시면 됩니다.
2.최종 유죄상황에 영향을 줄 중요한 숫자, 중요 정보를 보존해야 합니다! 예: 배상금액, 경상/중상 판정 등.
3.양측에 이견이 있는 사안도 요약하여 보존해야 하며, 버려서는 안 됩니다.
"""
)
self.memory+="\n\n"+res
def yilvkezhi_retriever(self,prompt):
url = "http://web.megatechai.com:33615/test_case_app/wenshu_search/search_and_answer"
payload = json.dumps({
"query": prompt,
"need_answer": 1
})
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
try:
response=json.loads(response.text)
except:
print("Error!",response.text)
return None
# print(response)
answer=response["data"]["answer"]
sim_cases=extract_bracket_content(answer)
anhao={}
for js in response["data"]["wenshu_results"]:
anhao[js['anhao']]=js
sim_cases_text="类似案件为:"
fl=0
for case in sim_cases:
if case=="" or case is None:
continue
if case in anhao:
if anhao[case]['caipanliyou']!="" and anhao[case]['caipanjieguo']!="":
if anhao[case]['caipanliyou'] is not None and anhao[case]['caipanjieguo'] is not None:
fl+=1
sim_cases_text+="\n"+"【"+case+"】:"+anhao[case]['caipanliyou']+anhao[case]['caipanjieguo']
if fl==1: #only 1 cases
break
if fl!=0:
answer+="\n\n#####\n"+sim_cases_text
return answer
def law_retriever(self,query_text):
if query_text in law_repository:
return law_repository[query_text]
return None
def _get_plan(self,context,hint=""):
prompt = """
이제 더 나은 업무 완수를 위해 두 가지 도구를 사용할 수 있습니다.
1.법조검색고. 중화인민공화국의 모든 법조를 포함하며, 형법, 민법전, 민사소송법 등이 포함됩니다. 조회 내용에 따라 법조 내용을 반환할 수 있습니다. 동시에 일부 법률법규와 사법해석도 포함됩니다.
2.'일률가지'. 법률 문제, 법률 사실, 쟁의 쟁점, 사례 정보를 입력하여 관련 사례 및 전문적인 분석 답변을 얻을 수 있습니다.
귀하의 업무 목표와 현재 정보에 근거하여 이 두 도구를 사용할지, 그리고 무엇을 질문할지 결정하시오.
한 번에 여러 문제를 조회할 수 있으며, 여러 문제는 list에 넣으시오.
【주의!!】
1.법조검색고에 입력하는 법률명칭은 반드시 전체명칭이어야 하며, 줄임말을 사용할 수 없습니다. 예를 들어 반드시 "중화인민공화국형법 제1조", "중화인민공화국형법 제120조의2", "최고인민법원 미성년자형사사건심리에관한법률적용의구체적문제에대한해석 제15조" 등으로 명시해야 합니다.
2.관, 항을 쓰지 마시오! 법조의 전체명만 명시하시오. 예를 들어, "중화인민공화국형법 제134조 제1관"이라고 쓰지 말고, "중화인민공화국형법 제134조"라고만 쓰시오.
귀하의 답변은 엄격히 다음 형식에 따라야 합니다(불필요한 말은 하지 마시오! 다른 답변은 필요 없습니다!!):
{
"법조":{
"사용":0은 사용하지 않음, 1은 사용함을 의미.
"질문":[질문하려는 문제1,질문하려는 문제2]
},
"일률가지":{
"사용":0은 사용하지 않음, 1은 사용함을 의미.
"질문":[질문하려는 문제1,질문하려는 문제2]
}
}
예시:
{
"법조":{
"사용":1,
"질문":["중화인민공화국민법전 제469조","중화인민공화국형법 제5조","최고인민법원 미성년자형사사건심리에관한법률적용의구체적문제에대한해석 제15조"]
},
"일률가지":{
"사용":1,
"질문":["고객정보는 회사의 상업비밀에 속하는가?","단위는 말위도태제도를 이용하여 직원과 노동계약을 해제할 수 있는가?"]
}
}
"""+hint
response = self.speak(
context,
prompt,
check=False
)
print("Queries",self.role,response)
return response
def plan(self, context,hint=""):
now_plan=self._get_plan(context,hint=hint)
now_plan=json.loads(now_plan)
laws=""
QA_pair={}
if now_plan["一律可知"]["使用"]==1:
for query in now_plan["一律可知"]["询问"]:
answer=self.yilvkezhi_retriever(query)
if answer is not None:
QA_pair.update({query:answer})
now_plan["一律可知"].update({query:answer})
pattern = r"### 核心法条\n(.*?)\n\n###"
core_statutes = re.search(pattern, answer, re.S)
core_statutes_content = core_statutes.group(1) if core_statutes else ""
laws+=core_statutes_content
if now_plan["법조"]["사용"]==1:
prompt = """
주어진 텍스트에서 모든 법조, 법규, 사법해석의 명칭 및 구체적 조목을 추출하시오.
법조에는 형법, 민법전, 민사소송법 등이 포함됩니다. 동시에 일부 법률법규와 사법해석도 포함됩니다.
【주의!!】
1.각 법률법규 사법해석은 반드시 전체명칭이어야 하며, 줄임말을 사용할 수 없습니다. 예를 들어 반드시 "중화인민공화국형법 제1조", "중화인민공화국형법 제120조의2", "최고인민법원 미성년자형사사건심리에관한법률적용의구체적문제에대한해석 제15조" 등으로 명시해야 합니다.
2.관, 항을 쓰지 마시오! 법조의 전체명만 명시하시오(즉 제xx조까지 정확하게). 예를 들어, "중화인민공화국형법 제134조 제1관"이라고 쓰지 말고, "중화인민공화국형법 제134조"라고만 쓰시오.
3.추출된 결과를 직접 반환하고, 인접한 두 조목 사이는 |로 구분하시오.
4.법조법규에 책명호를 붙이지 마시오! 제x조와 직접 연결하시오.
【반환형식】
법조법규1|법조법규2|법조법규3|법조법규4
예시:
중화인민공화국형법 제1조|중화인민공화국형법 제120조의2|최고인민법원 미성년자형사사건심리에관한법률적용의구체적문제에대한해석 제15조
"""
response = self.speak(
laws+str(now_plan["법조"]["질문"]),
prompt,
check=False
)
response=response.split("|")
for query in response:
answer=self.law_retriever(query)
if answer is not None:
QA_pair.update({query:answer})
now_plan["法条"].update({query:answer})
self.current_plan=now_plan
self.current_answer=QA_pair
print("Generate QA_pair",self.role,QA_pair)
return QA_pair
# --- Do Phase --- #
def execute(
self, plan: Dict[str, Any], history_list: List[Dict[str, str]], prompt: str, simple:int
) -> str:
history_context = self.prepare_history_context(history_list)
self.history_context=history_context
if simple==1: #审判长宣读辩论焦点
return self.speak("当前庭审记录:"+history_context, prompt,check=True)
elif simple==2: # 最后判决
context="目前的辩论焦点和查明情况:"+str(self.debate_focus)+"法庭发言记录总结:"+str(self.memory)
# QA_pair=self.plan(context+prompt.split("#####")[0],hint="提示,可以搜索类似案件判决情况,关注刑期长短,关注社会评价与社会影响,关注是否适用缓刑,是否需要赔偿、处罚罚金,以及具体数值等。**建议至少查询类似案件、实刑刑期长度、缓刑适用、罚金数额!**")
# self.init_QA_pair.update(QA_pair)
# print("参考资料:"+str(self.init_QA_pair), context+prompt)
return self.speak("", context+prompt,check=True)
elif simple==6: # 判决书生成
context="庭审记录总结:"+str(self.memory)+"目前的辩论焦点和查明情况:"+str(self.debate_focus)
return self.speak(context, prompt,check=True)
elif simple==5: # 被告人回答是否之前有过其他法律处分/法官宣读庭审启动
return self.speak("", prompt)
if self.role=="재판장":
context="之前法庭人员发言记录总结:"+str(self.memory)+"目前的证据:"+str(self.evidence_pool)+"目前的辩论焦点和查明情况:"+str(self.debate_focus)+"最新的庭审记录:"+history_context
elif self.role=="피고인":
context="目前的策略:"+str(self.strategy)+"最新的庭审记录:"+history_context
prompt+="被告人请按实际情况诚实回答,无中生有可能会加重判罚。例如,如果没有赔偿,或没有取得谅解,就要如实回答没有。"
else:
# context="之前法庭人员发言记录总结:"+str(self.memory)+"目前的证据:"+str(self.evidence_pool)+"目前的策略:"+str(self.strategy)+"最新的庭审记录:"+history_context
context="之前法庭人员发言记录总结:"+str(self.memory)+"目前的证据:"+str(self.evidence_pool)
if hasattr(self, 'strategy'):
context+="目前的策略:"+str(self.strategy)+"最新的庭审记录:"+history_context
else:
context+="最新的庭审记录:"+history_context
if simple==3: #公诉人/辩护人 法庭调查的提问
context+="拟询问的问题(仅供参考),注意不要和之前问题重复:"+str(self.questions)
if simple==4: #审判长打断选项
return self.speak(context, prompt)
if simple==7: #审判长判断有没有认罪认罚具结书
return self.speak(context, prompt)
# QA_pair=self.plan(context)
# return self.speak(context+"参考资料:"+str(QA_pair), prompt)
return self.speak(context, prompt,check=True)
def pure_final_judge(self,context,prompt):
QA_pair=self.plan(context+prompt,hint="提示,可以搜索类似案件判决情况,关注刑期长短,关注社会评价与社会影响,关注是否适用缓刑,是否需要赔偿、处罚罚金,以及具体数值等。**建议至少查询类似案件、实刑刑期长度、缓刑适用、罚金数额!**")
return self.speak("案件事实"+context+"参考资料:"+str(QA_pair), prompt)
# return self.speak(context, prompt)
def speak(self, context: str, prompt: str, max_tokens=4096,check=False) -> str:
instruction = f"{self.instruction}\n\n**중요: 모든 응답은 반드시 한국어로 해주세요. 중국어나 다른 언어로 답변하지 마시고, 오직 한국어만 사용하여 응답해 주시기 바랍니다.**\n\n"
full_prompt = f"{context}\n\n{prompt}"
hint=""
# if check==False:
return self.llm.generate(instruction=instruction, prompt=full_prompt+hint,max_tokens=max_tokens)
# for i in range(2):
# response=self.llm.generate(instruction=instruction, prompt=full_prompt+hint,max_tokens=max_tokens)
# check_res=self.check_speak_hallucination(self.history_context,response)
# if check_res[0]=='无':
# return response
# hint="请仔细查看证据信息,务必遵循证据事实,确保不要无中生有!你已经出现了一次幻觉!"
# print("HALLUCINATION!")
# return "【HALLUCINATION!】"+response
# --- Reflect Phase --- #
def prepare_history_context(self, history_list: List[Dict[str, str]]) -> str:
formatted_history = ["当前庭审记录:"]
for entry in history_list:
role = entry["role"]
content = entry["content"].replace("\n", "\n ")
formatted_entry = f"\\role{{{role}}}\n {content}"
formatted_history.append(formatted_entry)
return "\n\n".join(formatted_history)
class Agent_litigants(Agent):
def __init__(
self,
id: int,
name: str,
role: str,
description: str,
llm: Any,
fact=None
):
super().__init__(id,name,role,description,llm)
self.strategy=""
# {
# "攻击策略":"",
# "防御策略":""
# }
self.questions=""
self.fact=fact
def call_thought(self,save_only=False):
res={}
res.update({
"策略":self.strategy,
"记忆":self.memory,
})
if self.role!="被告人":
res.update({
"规划":self.current_plan,
})
if save_only==True:
res.update({
"目标":self.goal
})
if self.role!="被告人":
res.update({
"询问":self.questions
})
return res
def preparation(self,prosecution_statement,defendant_information,evidence):
# term_mention=f"""
# 被告人被指控的罪名有:{all_term}
# 你的策略应当针对该罪名的定罪、量刑进行制定。一定要有针对性。
# """
self.defendant_information=defendant_information
self.prosecution_statement=prosecution_statement
self.evidence_pool=evidence
all_input=self.crime3aspect
if self.role=="公诉人":
self.strategy_prompt="""
【攻击策略】公诉人需要制定自己的攻击策略,包含被告人犯罪的证据链(通过对证据、法律条文的精准解读说明为什么被告人犯罪),质疑辩护人的证据的关联性与证明效力(例如辩护人出示自首证据,可以质疑是否真的自首),以及论述为什么足以判处起诉状中的刑期(比如社会危害度,可改造程度等)等。
【防御策略】公诉人需要制定自己的防御策略,包含如何维护自身证据的关联性和证明效力,以应对辩护人和被告人潜在的对证据的质疑。
你的策略应当参考被告人信息、被告人的诉求!
此外要注意,**公诉人的目的是协助法官查明真相,对被告人进行公正的判罚**,所以对于**你认可的被告人能够从轻处罚的情节**,也可以加入到策略之中,而非机械地反对被告人/辩护人的一切观点与诉求。
你的策略可以晓之以理动之以情,可以换位思考,站在被告人的角度,事实经过的角度去制定策略。
"""
info="起诉状:"+prosecution_statement+"被告人信息:"+defendant_information+"证据:"+evidence
task="""
在庭审开始前,你要根据起诉状、被告人信息、证据条目,制定自己本次出庭的目标、攻击策略、防御策略。
"""+all_input+"""
**再次注意,只有当三个角度都成立,且具有直接因果关系时,罪名才真正成立**
**所以你的策略应当围绕论证犯罪的定义成立,且因果成立的角度。**
越具体越好!
"""+"""
【目标】公诉人的目标通常为保证准确、及时地查明犯罪事实,正确应用法律,惩罚犯罪分子,保障无罪的人不受刑事追究。具体地,你的目标还应当包含期望法庭给被告人处以的罪名、刑期和罚金。
"""+self.strategy_prompt
# QA_pair=self.plan(info+task)
# res=self.speak(info+"参考资料:"+str(QA_pair),
# task+
# """
# 你的回复应当严格按照如下格式:
# [一句话总结目标]|[攻击策略,直接分条回复。1.xxx2.xxx3.xxx]|[防御策略,分条回复。1.xxx2.xxx3.xxx]
# 回复时不要包含[]
# 例如:
# 请求法院判处被告人xxx|1.证据xxx证明2.被告人的自首系xxx3.社会危害性xxx|1.证据xxx是由xxx,具有法律效力2.xxx
# 其中每一条的格式为:
# xxx(策略内容),参考法条:xxx(法条名称及内容概括),参考案例:xxx(案例编号及内容概括)
# 法条和案例如果没有,或对于约定俗成的常见策略,则不必添加这些参考。
# 【注意】
# 1.注意,策略要实事求是符合实际!不能无中生有!
# 2.直接按照格式返回,不要说多余的话
# 3.每一个策略下,**要附带能支撑该策略的参考法条以及类案信息**,(从给你的参考资料中取,如果没有则不用带)
# 4.你要进一步调整策略,要和之前的策略进行合理地修改,而非照搬或者全盘否定。
# """
# )
elif self.role=="辩护人":
info="起诉状:"+prosecution_statement+"被告人信息:"+defendant_information+"证据:"+evidence
self.strategy_prompt="""
【攻击策略】辩护人需要制定自己的攻击策略,质疑公诉人的证据(例如说明公诉人的证据与本案件的不具备关联性,或证明效力不够充分),指出其证据不足或推理不合理。
【防御策略】辩护人需要制定自己的防御策略,以减轻被告人的罪责。包含寻找有利证据、构建合理故事、法律条文的精准解读、强调案件特殊情节、强调积极态度与悔悟等为被告人进行开脱,同时,也可以强调被告人的学历认知受限、家庭困难等客观因素,争取减轻判罚。此外,还要维护自身证据与案件事实的关联性,以应对公诉人潜在的对证据的质疑。
你的策略整体上要围绕定罪、量刑、缓刑、罚金展开,应当参考被告人信息、被告人的诉求!
例如被告人家庭经济条件不好,则应当尝试减少罚金,争取缓刑等;被告人提出希望缓刑,则应当争取缓刑。
你的策略可以晓之以理动之以情,可以换位思考,站在被告人的角度,事实经过的角度去制定策略。
"""
task="""
在庭审开始前,你要根据起诉状、被告人信息、证据条目,制定自己本次出庭的目标、攻击策略、防御策略。
"""+all_input+"""
**再次注意,只有当三个角度都成立,且具有直接因果关系时,罪名才真正成立**
**所以你的策略应当围绕论证犯罪的定义不成立,或者因果不完全成立的角度。**
越具体越好!
"""+"""
【目标】辩护人的责任是根据事实和法律,提出犯罪嫌疑人、被告人无罪、罪轻或者减轻、免除其刑事责任的材料和意见,维护犯罪嫌疑人、被告人的诉讼权利和其他合法权益。具体地,你的目标应还当包含期望法庭给被告人处以的罪名、刑期和罚金。(要低于起诉状中的罪情)
"""+self.strategy_prompt
# QA_pair=self.plan(info+task)
# res=self.speak(info+"参考资料:"+str(QA_pair),
# task+
# """
# 你的回复应当严格按照如下格式:
# [一句话总结目标]|[攻击策略,直接分条回复。1.xxx2.xxx3.xxx]|[防御策略,分条回复。1.xxx2.xxx3.xxx]
# 回复时不要包含[]
# 例如:
# 请求法院判处被告人xxx|1.证据xxx不足以xxx2.xxx处推理不合理|1.证据xxx是由xxx,具有法律效力2.被告人态度良好xxx
# 其中每一条的格式为:
# xxx(策略内容),参考法条:xxx(法条名称及内容概括),参考案例:xxx(案例编号及内容概括)
# 法条和案例如果没有,或对于约定俗成的常见策略,则不必添加这些参考。
# 【注意】
# 1.注意,策略要实事求是符合实际!不能无中生有!
# 2.直接按照格式返回,不要说多余的话
# 3.每一个策略下,**要附带能支撑该策略的参考法条以及类案信息**,(从给你的参考资料中取,如果没有则不用带)
# 4.你要进一步调整策略,要和之前的策略进行合理地修改,而非照搬或者全盘否定。
# """
# )
# res=res.split("|")
self.goal=""#res[0]
self.strategy=""#f"攻击策略:{res[1]}"+ "\n"+ f"防御策略:{res[2]}"
self.init_QA_pair=""# QA_pair
if self.role=="公诉人":
self.questions=""
# self.speak("起诉状:"+prosecution_statement+"被告人信息:"+defendant_information+"证据:"+evidence+"最终目标:"+self.goal+"策略: "+self.strategy+"参考资料:"+str(QA_pair),
# """
# 在法庭调查阶段,作为公诉人,你要围绕定罪量刑相关问题对被告人进行发问。
# 比如针对案件事实,犯罪动机,犯罪情节等。
# 现在请你根据起诉状、被告人信息、证据条目、本次出庭的目标、攻击策略、防御策略,制定法庭调查阶段拟询问被告人的问题。
# 问题应当涵盖多个角度,而总数不要太多!
# """+
# all_input+
# """
# 请分条回复。**按照重要性先后顺序!**
# 例如
# 1.xxxx
# 2.xxxx
# 3.xxxx
# """)
elif self.role=="辩护人":
self.questions=""
# self.speak("起诉状:"+prosecution_statement+"被告人信息:"+defendant_information+"证据:"+evidence+"最终目标:"+self.goal+"策略:"+self.strategy+"参考资料:"+str(QA_pair),
# """
# 在法庭调查阶段,作为辩护人,你要围绕定罪量刑相关问题对被告人进行发问。
# 比如针对案件事实,犯罪动机,犯罪情节等。
# 现在请你根据起诉状、被告人信息、证据条目、本次出庭的目标、攻击策略、防御策略,制定法庭调查阶段拟询问被告人的问题。
# 问题应当涵盖多个角度,而总数不要太多!
# """+
# all_input+
# """
# 请分条回复。**按照重要性先后顺序!**
# 例如
# 1.xxxx
# 2.xxxx
# 3.xxxx
# """)
def for_defendant(self,prosecution_statement,defendant_information,evidence):
# 辩护人和被告人商议最终目标
# term_mention=f"""
# 被告人被指控的罪名有:{all_term}
# 你的策略应当针对该罪名的定罪、量刑进行制定。一定要有针对性。
# """
defendant_strategy_prompt="""
【防御策略】被告人需要制定自己的防御策略,以减轻自己的罪责。如果目标是带来减刑,则应当表示认罪认罚悔罪态度;若目标是否认指控自证无罪,则应当坚定地声称自身的清白。
"""
# res=self.speak("起诉状:"+prosecution_statement+"被告人信息:"+defendant_information+"证据:"+evidence+"参考资料:"+str(self.init_QA_pair),
# """
# 你是辩护人,你的当事人(被告人)被指控犯罪。
# 在庭审开始前,你要根据起诉状、被告人信息、证据条目,帮助被告人制定其在本次出庭的目标、防御策略。
# 如果被告人提出了诉求,那么诉求中的内容应当出现在被告人的目标与策略中。
# """
# +term_mention+
# """
# 【目标】被告人的目标是在已知信息的范围内,维护自己的利益。良好的认罪认罚态度有可能带来减刑,直接否认指控自证无罪可能会免除罪责,也有可能会罪加一等。
# """
# +defendant_strategy_prompt+
# """
# 此前,作为辩护人,你自己制定的目标和策略是:
# """+
# "辩护目标:"+self.goal+"辩护策略"+str(self.strategy)+
# """
# **注意,你代表被告人的利益,所以给被告人制定的策略要和你自己制定的辩护策略相一致。**
# **注意,策略必须要符合实际,如果证据中没有提及赔偿、谅解等情节,则不应该有这部分策略!**
# **反之,如果被告人做出了赔偿、征得了谅解,则应当有这部分的策略**
# **如果被告人提出了诉求,那么诉求中的内容应当出现在被告人的目标与策略中。**
# 你的回复应当严格按照如下格式:
# [一句话总结目标]|[防御策略,分条回复。1.xxx2.xxx3.xxx]
# 回复时不要包含[]
# 例如:
# 希望以悔罪的态度争取xxxx|1.积极悔罪xxx2.说明自身自首xxx
# """
# )
# res=res.split("|")
return defendant_strategy_prompt,"",""
# def think_answer(self,questions):
# self.answer=self.speak("出庭目标:"+self.goal+self.strategy+"辩护人询问的问题:"+self.questions,
# """
# 在法庭调查阶段,辩护人可能会向被告人询问一些问题。
# 作为被告人,请你根据你的出庭目标、防御策略,针对辩护人打算询问的问题依次做出回复。
# 你的回复应当严格按照如下形式:
# 1.xxxx
# 2.xxxx
# 3.xxxx
# """
# )
def set_strategy(self,strategy_prompt,goal,strategy,prosecution_statement,defendant_information,evidence):
# self.all_term=all_term
self.prosecution_statement=prosecution_statement
self.defendant_information=defendant_information
self.evidence_pool=evidence
self.strategy_prompt=strategy_prompt
self.goal=goal
self.strategy=strategy
class Agent_Judge(Agent):
def __init__(
self,
id: int,
name: str,
role: str,
description: str,
llm: Any,
):
super().__init__(id,name,role,description,llm)
self.debate_focus=""
# self.conclusion=""
def call_thought(self,save_only=False):
res={}
res.update({"辩论焦点与查明情况":self.debate_focus,
"记忆":self.memory,
"规划":self.current_plan})
return res
def preparation(self, prosecution_statement, defendant_information, evidence):
self.evidence_pool=evidence
self.prosecution_statement=prosecution_statement
self.defendant_information=defendant_information
# term_mention=f"""
# 被告人被指控的罪名有:{all_term}
# 你所要查明的事实也应当针对该罪名的定罪、量刑进行制定。一定要有针对性。
# """
self.strategy_prompt="""
作为审判长,你需要查明案件的事实,所以辩论焦点还要考虑涵盖以下几个角度的内容:
辩论焦点包括:
定罪与否、责任认定情况(比如年龄是不是符合,主责或次责等)、量刑情况(是否有一些从轻或从重处罚的情节,是否自首,是否取得被害人原谅)
还应当包括应当查明但双方还没有讨论清楚的内容,你认为对定罪量刑有价值的问题。
辩论焦点应当具体且灵活。
"""
info="起诉状:"+prosecution_statement+"被告人信息:"+defendant_information+"证据:"+evidence
task="""
在庭审开始前,你要根据起诉状、被告人信息、证据条目,生成本案可能的辩论焦点。
"""+self.crime3aspect+"""
**只有当三个角度都成立,且具有直接因果关系时,罪名才真正成立**
所以你的辩论焦点也应该围绕这三个角度。越具体越好!
"""+self.strategy_prompt
self.init_QA_pair=""# self.plan(info+task)
# res=self.speak(info+"参考资料:"+str(self.init_QA_pair),
# task+
# """
# 辩论焦点从1开始编号
# 例如:1.是否构成故意伤害罪。需要讨论直到被告表示认罪受罚,或证明被告罪行不满足故意伤害罪条件。若此前被告已经明确表示认罪,则无需进行辩论。2.是否构成自首。3.是否征得被害人谅解。
# 请严格按照以下格式回复:
# 1.法庭辩论焦点2.法庭辩论焦点3.法庭辩论焦点
# """
# )
self.debate_focus=""
self.questions=""
# self.speak("起诉状:"+prosecution_statement+"被告人信息:"+defendant_information+"证据:"+evidence+"辩论焦点:"+self.debate_focus+"参考资料:"+str(self.init_QA_pair),
# """
# 在法庭调查阶段,作为审判长,你要查清案件事实,围绕定罪量刑相关问题对被告人进行发问。
# 比如针对案件事实,犯罪动机,犯罪情节等。
# 现在请你根据起诉状、被告人信息、证据条目、辩论焦点制定法庭调查阶段拟询问被告人的问题。
# 问题应当涵盖多个角度,而总数不要太多!
# 请分条回复。**按照重要性先后顺序!**
# 例如
# 1.xxxx
# 2.xxxx
# 3.xxxx
# """)