anpigon commited on
Commit
a1514be
Β·
1 Parent(s): 31d4911

chore: Update requirements.txt and add pyproject.toml file with project dependencies

Browse files
Files changed (1) hide show
  1. law-bot.ipynb +342 -0
law-bot.ipynb ADDED
@@ -0,0 +1,342 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 25,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import pickle, os, numpy as np\n",
10
+ "from tqdm import tqdm\n",
11
+ "from langchain.schema import Document\n",
12
+ "from langchain.vectorstores import FAISS\n",
13
+ "from langchain.schema import Document\n",
14
+ "from langchain_community.embeddings import HuggingFaceBgeEmbeddings\n",
15
+ "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
16
+ "from langchain_community.retrievers import BM25Retriever\n",
17
+ "from langchain.retrievers import EnsembleRetriever"
18
+ ]
19
+ },
20
+ {
21
+ "cell_type": "code",
22
+ "execution_count": 17,
23
+ "metadata": {},
24
+ "outputs": [
25
+ {
26
+ "name": "stdout",
27
+ "output_type": "stream",
28
+ "text": [
29
+ "데이터 λ‘œλ“œ 쀑...\n",
30
+ "총 2736개의 λ°°μΉ˜κ°€ λ‘œλ“œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.\n"
31
+ ]
32
+ }
33
+ ],
34
+ "source": [
35
+ "os.environ[\"TOKENIZERS_PARALLELISM\"] = \"false\"\n",
36
+ "\n",
37
+ "# cases.pkl νŒŒμΌμ—μ„œ 데이터 λ‘œλ“œ\n",
38
+ "print(\"데이터 λ‘œλ“œ 쀑...\")\n",
39
+ "with open(\"/Users/anpigon/Documents/Embed/ᄇα…₯ᆸ원ᄑᅑᆫ례/Result2.pkl\", \"rb\") as file:\n",
40
+ " data = pickle.load(file)\n",
41
+ "\n",
42
+ "print(f\"총 {len(data)}개의 λ°°μΉ˜κ°€ λ‘œλ“œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.\")"
43
+ ]
44
+ },
45
+ {
46
+ "cell_type": "code",
47
+ "execution_count": 11,
48
+ "metadata": {},
49
+ "outputs": [],
50
+ "source": [
51
+ "# μž„λ² λ”© λͺ¨λΈ μ„€μ • (μ‹€μ œλ‘œ μž„λ² λ”©ν•˜μ§€λŠ” μ•ŠμŒ)\n",
52
+ "embeddings = HuggingFaceBgeEmbeddings(model_name=\"BAAI/bge-m3\")"
53
+ ]
54
+ },
55
+ {
56
+ "cell_type": "code",
57
+ "execution_count": 18,
58
+ "metadata": {},
59
+ "outputs": [],
60
+ "source": [
61
+ "# ν…μŠ€νŠΈ λΆ„ν• κΈ° μ„€μ •\n",
62
+ "text_splitter = RecursiveCharacterTextSplitter(\n",
63
+ " chunk_size=2000,\n",
64
+ " chunk_overlap=200,\n",
65
+ " length_function=len,\n",
66
+ ")"
67
+ ]
68
+ },
69
+ {
70
+ "cell_type": "code",
71
+ "execution_count": 19,
72
+ "metadata": {},
73
+ "outputs": [
74
+ {
75
+ "name": "stdout",
76
+ "output_type": "stream",
77
+ "text": [
78
+ "λ¬Έμ„œ 처리 및 μ²­ν‚Ή 쀑...\n"
79
+ ]
80
+ },
81
+ {
82
+ "name": "stderr",
83
+ "output_type": "stream",
84
+ "text": [
85
+ "100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 2736/2736 [00:42<00:00, 64.15it/s] \n"
86
+ ]
87
+ }
88
+ ],
89
+ "source": [
90
+ "# λ¬Έμ„œ 처리 및 μ²­ν‚Ή\n",
91
+ "print(\"λ¬Έμ„œ 처리 및 μ²­ν‚Ή 쀑...\")\n",
92
+ "documents = []\n",
93
+ "text_embedding_pairs = []\n",
94
+ "\n",
95
+ "for batch in tqdm(data):\n",
96
+ " original_sentences = batch[1] # λ°°μΉ˜λ‹Ή 32개의 원본 λ¬Έμž₯\n",
97
+ " embedding_vectors = batch[0] # λ°°μΉ˜λ‹Ή 32개의 μž„λ² λ”© 벑터\n",
98
+ "\n",
99
+ " for sentence, vector in zip(original_sentences, embedding_vectors):\n",
100
+ " chunks = text_splitter.split_text(sentence)\n",
101
+ " for chunk in chunks:\n",
102
+ " doc = Document(page_content=chunk)\n",
103
+ " documents.append(doc)\n",
104
+ " text_embedding_pairs.append((chunk, vector))"
105
+ ]
106
+ },
107
+ {
108
+ "cell_type": "code",
109
+ "execution_count": 12,
110
+ "metadata": {},
111
+ "outputs": [
112
+ {
113
+ "name": "stdout",
114
+ "output_type": "stream",
115
+ "text": [
116
+ "FAISS 인덱슀 뢈러였기\n",
117
+ "FAISS 인덱슀 뢈러였기 μ™„λ£Œ\n"
118
+ ]
119
+ }
120
+ ],
121
+ "source": [
122
+ "# FAISS 인덱슀 생성\n",
123
+ "print(\"FAISS 인덱슀 뢈러였기\")\n",
124
+ "FAISS_DB_INDEX = \"./index_faiss\"\n",
125
+ "faiss_db = FAISS.load_local(\n",
126
+ " FAISS_DB_INDEX, embeddings, allow_dangerous_deserialization=True\n",
127
+ ")\n",
128
+ "faiss_retriever = faiss_db.as_retriever(search_type=\"mmr\", search_kwargs={\"k\": 10})\n",
129
+ "print(\"FAISS 인덱슀 뢈러였기 μ™„λ£Œ\")"
130
+ ]
131
+ },
132
+ {
133
+ "cell_type": "code",
134
+ "execution_count": 22,
135
+ "metadata": {},
136
+ "outputs": [
137
+ {
138
+ "name": "stdout",
139
+ "output_type": "stream",
140
+ "text": [
141
+ "BM25Retriever 뢈러였기\n",
142
+ "BM25 λ¦¬νŠΈλ¦¬λ²„ 뢈러였기 μ™„λ£Œ\n"
143
+ ]
144
+ }
145
+ ],
146
+ "source": [
147
+ "from kiwipiepy import Kiwi\n",
148
+ "from typing import List\n",
149
+ "\n",
150
+ "kiwi = Kiwi()\n",
151
+ "\n",
152
+ "\n",
153
+ "def kiwi_tokenize(text):\n",
154
+ " return [token.form for token in kiwi.tokenize(text)]\n",
155
+ "\n",
156
+ "\n",
157
+ "print(\"BM25Retriever 뢈러였기\")\n",
158
+ "# bm25_retriever = BM25Retriever.from_documents(documents, k=10)\n",
159
+ "with open(\"./index_bm25/kiwi.pkl\", \"rb\") as f:\n",
160
+ " bm25_retriever = pickle.load(f)\n",
161
+ "print(\"BM25 λ¦¬νŠΈλ¦¬λ²„ 뢈러였기 μ™„λ£Œ\")"
162
+ ]
163
+ },
164
+ {
165
+ "cell_type": "code",
166
+ "execution_count": 26,
167
+ "metadata": {},
168
+ "outputs": [],
169
+ "source": [
170
+ "ensemble_retriever = EnsembleRetriever(\n",
171
+ " retrievers=[bm25_retriever, faiss_retriever], weights=[0.7, 0.3], search_type=\"mmr\"\n",
172
+ ")"
173
+ ]
174
+ },
175
+ {
176
+ "cell_type": "code",
177
+ "execution_count": 27,
178
+ "metadata": {},
179
+ "outputs": [],
180
+ "source": [
181
+ "from operator import itemgetter\n",
182
+ "from langchain.callbacks.base import BaseCallbackHandler\n",
183
+ "from langchain_core.prompts import (\n",
184
+ " HumanMessagePromptTemplate,\n",
185
+ " SystemMessagePromptTemplate,\n",
186
+ ")\n",
187
+ "from langchain_openai import ChatOpenAI\n",
188
+ "from langchain_anthropic import ChatAnthropic\n",
189
+ "from langchain_core.output_parsers import StrOutputParser\n",
190
+ "from langchain_community.chat_message_histories import ChatMessageHistory\n",
191
+ "from langchain.schema import HumanMessage, AIMessage, SystemMessage\n",
192
+ "from langchain.schema.runnable import RunnablePassthrough\n",
193
+ "from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
194
+ "\n",
195
+ "\n",
196
+ "class StreamCallback(BaseCallbackHandler):\n",
197
+ " def on_llm_new_token(self, token: str, **kwargs):\n",
198
+ " print(token, end=\"\", flush=True)\n",
199
+ "\n",
200
+ "\n",
201
+ "# ν”„λ‘¬ν”„νŠΈ ν…œν”Œλ¦Ώ μ„€μ •\n",
202
+ "prompt_template = \"\"\"\n",
203
+ "당신은 νŒμ‚¬μ΄μž 20λ…„μ°¨ 법λ₯  μ „λ¬Έκ°€μž…λ‹ˆλ‹€. 주어진 μ§ˆλ¬Έμ— λŒ€ν•΄ λ¬Έμ„œμ˜ 정보λ₯Ό μ΅œλŒ€ν•œ ν™œμš©ν•˜μ—¬ λ‹΅λ³€ν•˜μ„Έμš”.\n",
204
+ "μ§ˆλ¬ΈμžλŠ” 자기 상황을 μ„€λͺ…ν•  것이며, 질문자의 상황과 λΉ„μŠ·ν•œ νŒλ‘€λ₯Ό μ„€λͺ…ν•΄μ€˜μ•Ό ν•˜λ©°, κ°€μž₯ 졜근 사건 순으둜 μ†Œκ°œλžλ‹ˆλ‹€.\n",
205
+ "μ΅œλŒ€ν•œ μžμ„Έν•˜κ²Œ λ‹΅λ³€ν•©λ‹ˆλ‹€. μ΄ˆλ“±ν•™μƒμ΄ 이해할 μ •λ„λ‘œ μ΄ν•΄ν•˜κΈ° 쉽도둝 λ‹΅λ³€ν•˜κ³ , ν•œκΈ€λ‘œ μž‘μ„±ν•˜μ„Έμš”.\n",
206
+ "μ§ˆλ¬Έμ— λŒ€νžŒ λ‹΅λ³€ 사, [사건λͺ… 1]..., [사건λͺ… 2]... μˆœμ„œλ‘œ μ„€λͺ…ν•΄μ•Ό ν•©λ‹ˆλ‹€.\n",
207
+ "λ¬Έμ„œμ—μ„œ 닡변을 찾을 수 μ—†λŠ” 경우, \"λ¬Έμ„œμ— 닡변이 μ—†μŠ΅λ‹ˆλ‹€.\"라고 λ‹΅λ³€ν•˜μ„Έμš”.\n",
208
+ "λ‹΅λ³€μ˜ 좜처(source)λ₯Ό λ°˜λ“œμ‹œ ν‘œκΈ°ν•΄μ£Όμ„Έμš”. μΆœμ²˜λŠ” λ©”νƒ€λ°μ΄ν„°μ˜ νŒλ‘€μΌλ ¨λ²ˆν˜Έ, 사건λͺ…, μ‚¬κ±΄λ²ˆν˜Έ 순으둜 ν‘œκΈ° ν•©λ‹ˆλ‹€.\n",
209
+ "\n",
210
+ "# 주어진 λ¬Έμ„œ:\n",
211
+ "{context}\n",
212
+ "\n",
213
+ "# 질문: {question}\n",
214
+ "\n",
215
+ "# λ‹΅λ³€:\n",
216
+ "\n",
217
+ "# 좜처:\n",
218
+ "- source1\n",
219
+ "- source2\n",
220
+ "- ...\n",
221
+ "\"\"\"\n",
222
+ "\n",
223
+ "# LLM 및 좜λ ₯ νŒŒμ„œ μ„€μ •\n",
224
+ "llm = ChatOpenAI(\n",
225
+ " model=\"gpt-4o\",\n",
226
+ " temperature=0,\n",
227
+ " streaming=True,\n",
228
+ " verbose=True,\n",
229
+ " callbacks=[StreamCallback()],\n",
230
+ ")\n",
231
+ "# llm = ChatAnthropic(model=\"claude-3-5-sonnet-20240620\", temperature=0, streaming=True, callbacks=[StreamCallback()])\n",
232
+ "\n",
233
+ "output_parser = StrOutputParser()\n",
234
+ "\n",
235
+ "# μ±„νŒ… 기둝을 μ €μž₯ν•  λ©”λͺ¨λ¦¬ μ΄ˆκΈ°ν™”\n",
236
+ "chat_history = ChatMessageHistory()\n",
237
+ "\n",
238
+ "# ν”„λ‘¬ν”„νŠΈ μ„€μ •\n",
239
+ "prompt = ChatPromptTemplate.from_messages(\n",
240
+ " [\n",
241
+ " (\"system\", prompt_template),\n",
242
+ " MessagesPlaceholder(variable_name=\"history\"),\n",
243
+ " (\"human\", \"{question}\"),\n",
244
+ " ]\n",
245
+ ").partial(history=chat_history.messages)\n",
246
+ "\n",
247
+ "# Runnable 객체 생성\n",
248
+ "runnable = RunnablePassthrough.assign(\n",
249
+ " context=itemgetter(\"question\") | ensemble_retriever,\n",
250
+ ")\n",
251
+ "# LCEL 체인 ꡬ성\n",
252
+ "chain = runnable | prompt | llm | output_parser\n",
253
+ "\n",
254
+ "\n",
255
+ "def rag_chain(question):\n",
256
+ " response = chain.invoke({\"question\": question})\n",
257
+ " chat_history.add_user_message(question)\n",
258
+ " chat_history.add_ai_message(response)\n",
259
+ " return response"
260
+ ]
261
+ },
262
+ {
263
+ "cell_type": "code",
264
+ "execution_count": 28,
265
+ "metadata": {},
266
+ "outputs": [
267
+ {
268
+ "name": "stdout",
269
+ "output_type": "stream",
270
+ "text": [
271
+ "μ•ˆλ…•ν•˜μ„Έμš”. νŒμ‚¬λ‹˜μž…λ‹ˆλ‹€. μ§ˆλ¬Έν•˜μ‹  상황과 λΉ„μŠ·ν•œ νŒλ‘€λ₯Ό μ°Ύμ•„λ³΄μ•˜μŠ΅λ‹ˆλ‹€. μ•„λž˜μ— 두 가지 사둀λ₯Ό μ†Œκ°œν•΄λ“œλ¦¬κ² μŠ΅λ‹ˆλ‹€.\n",
272
+ "\n",
273
+ "### [사건λͺ… 1] λΆˆκ³΅μ •ν•œ 법λ₯ ν–‰μœ„에 κ΄€ν•œ 법리λ₯Ό μ˜€ν•΄ν•œ μœ„λ²•μ΄ μžˆλŠ” μ‹€λ‘€\n",
274
+ "- **좜처**: 214987, 손해배상등, 68λ‹€88, 1968.07.30\n",
275
+ "- **사건 λ‚΄μš©**: 맀도인이 뢀동산을 맀도할 λ‹Ήμ‹œ, 맀수인이 λ§€λ„μΈμ˜ κΆλ°•ν•œ 사정을 μ•Œκ³  μžˆμ—ˆκ³ , 맀도인이 νŒ”κΈ°λ₯Ό κΊΌλ €ν•˜λŠ” λΆ€λΆ„κΉŒμ§€ 맀수인의 μš”κ΅¬μ— μ˜ν•΄ ν•¨κ»˜ νŒ”μ§€ μ•Šμ„ 수 μ—†μ—ˆμŠ΅λ‹ˆλ‹€. 맀맀λͺ©μ λ¬Όμ˜ κ²½κ³„ν™•μ •μΈ‘λŸ‰λ„ 맀수인이 일방적으둜 ν•˜κ³ , 뢀동산 가격도 맀우 μ €λ ΄ν•˜κ²Œ μ±…μ •λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 이 μ‚¬κ±΄μ—μ„œ 법원은 μ΄λŸ¬ν•œ λ§€λ§€ν–‰μœ„κ°€ λΆˆκ³΅μ •ν•œ 법λ₯ ν–‰μœ„에 ν•΄λ‹Ήν•œλ‹€κ³  νŒλ‹¨ν•˜μ˜€μŠ΅λ‹ˆλ‹€.\n",
276
+ "\n",
277
+ "### [사건λͺ… 2] μ›κ³ μ˜ μ£Όμž₯이 착였둜 μΈν•œ μ˜μ‚¬ν‘œμ‹œμ˜ μ·¨μ†Œλ‘œλ„ λ³΄μ—¬μ§€λ―€λ‘œ, 이λ₯Ό 석λͺ…μΉ˜ μ•Šμ€ μœ„λ²•μ΄ μžˆλŠ” 예\n",
278
+ "- **좜처**: 153300, λ§€λ§€λŒ€κΈˆλ°˜ν™˜λ“±, 66λ‹€1289, 1966.09.20\n",
279
+ "- **사건 λ‚΄μš©**: 원고가 ν”Όκ³ λ‘œλΆ€ν„° λ§€μˆ˜ν•œ λ…Ό 1,389평 쀑 μΌλΆ€λŠ” ν•˜μ²œμœΌλ‘œ λ˜μ–΄ μžˆμ–΄ κ²½μž‘ν•  수 μ—†λŠ” λ•…μ΄μ—ˆκ³ , λ‚˜λ¨Έμ§€ 땅은 이미 λ‹€λ₯Έ μ‚¬λžŒλ“€μ΄ κ²½μž‘ν•˜κ³  μžˆμ—ˆμŠ΅λ‹ˆλ‹€. μ›κ³ λŠ” μ΄λŸ¬ν•œ 사싀을 μ•Œμ§€ λͺ»ν•œ 채 맀맀계약을 μ²΄κ²°ν•˜μ˜€κ³ , λ‚˜μ€‘μ— 이λ₯Ό μ•Œκ²Œ λ˜μ–΄ 계약을 무효둜 μ£Όμž₯ν•˜μ˜€μŠ΅λ‹ˆλ‹€. 법원은 μ›κ³ μ˜ μ£Όμž₯이 착였둜 μΈν•œ μ˜μ‚¬ν‘œμ‹œμ˜ μ·¨μ†Œλ‘œλ„ λ³Ό 수 μžˆλ‹€κ³  νŒλ‹¨ν•˜μ˜€μŠ΅λ‹ˆλ‹€.\n",
280
+ "\n",
281
+ "이 두 사건 λͺ¨λ‘ 맀수인이 맀맀 λŒ€μƒ λΆ€λ™μ‚°μ˜ μ‹€μ œ μƒνƒœλ₯Ό μ œλŒ€λ‘œ μ•Œμ§€ λͺ»ν•œ 채 계약을 μ²΄κ²°ν•œ ν›„, κ·Έ 사싀을 μ•Œκ²Œ λ˜μ–΄ 법적 λΆ„μŸμ΄ λ°œμƒν•œ μ‚¬λ‘€μž…λ‹ˆλ‹€. μ§ˆλ¬Έμžλ‹˜μ˜ 상황과 μœ μ‚¬ν•œ 점이 λ§ŽμœΌλ―€λ‘œ μ°Έκ³ ν•˜μ‹œκΈ° λ°”λžλ‹ˆλ‹€.\n",
282
+ "\n",
283
+ "### μš”μ•½\n",
284
+ "- **사건λͺ… 1**: λ§€λ„μΈμ˜ κΆλ°•ν•œ 사정을 μ΄μš©ν•˜μ—¬ 뢀동산을 μ €λ ΄ν•˜κ²Œ λ§€μˆ˜ν•œ 경우.\n",
285
+ "- **사건λͺ… 2**: λ§€μˆ˜ν•œ 뢀동산이 μ‹€μ œλ‘œλŠ” κ²½μž‘ν•  수 μ—†λŠ” λ•…μ΄μ—ˆμŒμ„ λ‚˜μ€‘μ— μ•Œκ²Œ 된 경우.\n",
286
+ "\n",
287
+ "이와 같은 사둀λ₯Ό 톡해 법적 λŒ€μ‘ λ°©μ•ˆμ„ λͺ¨μƒ‰ν•΄λ³΄μ‹œκΈ° λ°”λžλ‹ˆλ‹€. 좔가적인 법적 쑰언이 ν•„μš”ν•˜μ‹œλ©΄ λ³€ν˜Έμ‚¬μ™€ μƒλ‹΄ν•˜μ‹œκΈ°λ₯Ό ꢌμž₯λ“œλ¦½λ‹ˆλ‹€.\n",
288
+ "\n",
289
+ "κ°μ‚¬ν•©λ‹ˆλ‹€.\n",
290
+ "\n",
291
+ "### 좜처\n",
292
+ "- 214987, 손해배상등, 68λ‹€88, 1968.07.30\n",
293
+ "- 153300, λ§€λ§€λŒ€κΈˆλ°˜ν™˜λ“±, 66λ‹€1289, 1966.09.20"
294
+ ]
295
+ },
296
+ {
297
+ "data": {
298
+ "text/plain": [
299
+ "'μ•ˆλ…•ν•˜μ„Έμš”. νŒμ‚¬λ‹˜μž…λ‹ˆλ‹€. μ§ˆλ¬Έν•˜μ‹  상황과 λΉ„μŠ·ν•œ νŒλ‘€λ₯Ό μ°Ύμ•„λ³΄μ•˜μŠ΅λ‹ˆλ‹€. μ•„λž˜μ— 두 가지 사둀λ₯Ό μ†Œκ°œν•΄λ“œλ¦¬κ² μŠ΅λ‹ˆλ‹€.\\n\\n### [사건λͺ… 1] λΆˆκ³΅μ •ν•œ 법λ₯ ν–‰μœ„에 κ΄€ν•œ 법리λ₯Ό μ˜€ν•΄ν•œ μœ„λ²•μ΄ μžˆλŠ” μ‹€λ‘€\\n- **좜처**: 214987, 손해배상등, 68λ‹€88, 1968.07.30\\n- **사건 λ‚΄μš©**: 맀도인이 뢀동산을 맀도할 λ‹Ήμ‹œ, 맀수인이 λ§€λ„μΈμ˜ κΆλ°•ν•œ 사정을 μ•Œκ³  μžˆμ—ˆκ³ , 맀도인이 νŒ”κΈ°λ₯Ό κΊΌλ €ν•˜λŠ” λΆ€λΆ„κΉŒμ§€ 맀수인의 μš”κ΅¬μ— μ˜ν•΄ ν•¨κ»˜ νŒ”μ§€ μ•Šμ„ 수 μ—†μ—ˆμŠ΅λ‹ˆλ‹€. 맀맀λͺ©μ λ¬Όμ˜ κ²½κ³„ν™•μ •μΈ‘λŸ‰λ„ 맀수인이 일방적으둜 ν•˜κ³ , 뢀동산 가격도 맀우 μ €λ ΄ν•˜κ²Œ μ±…μ •λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 이 μ‚¬κ±΄μ—μ„œ 법원은 μ΄λŸ¬ν•œ λ§€λ§€ν–‰μœ„κ°€ λΆˆκ³΅μ •ν•œ 법λ₯ ν–‰μœ„에 ν•΄λ‹Ήν•œλ‹€κ³  νŒλ‹¨ν•˜μ˜€μŠ΅λ‹ˆλ‹€.\\n\\n### [사건λͺ… 2] μ›κ³ μ˜ μ£Όμž₯이 착였둜 μΈν•œ μ˜μ‚¬ν‘œμ‹œμ˜ μ·¨μ†Œλ‘œλ„ λ³΄μ—¬μ§€λ―€λ‘œ, 이λ₯Ό 석λͺ…μΉ˜ μ•Šμ€ μœ„λ²•μ΄ μžˆλŠ” 예\\n- **좜처**: 153300, λ§€λ§€λŒ€κΈˆλ°˜ν™˜λ“±, 66λ‹€1289, 1966.09.20\\n- **사건 λ‚΄μš©**: 원고가 ν”Όκ³ λ‘œλΆ€ν„° λ§€μˆ˜ν•œ λ…Ό 1,389평 쀑 μΌλΆ€λŠ” ν•˜μ²œμœΌλ‘œ λ˜μ–΄ μžˆμ–΄ κ²½μž‘ν•  수 μ—†λŠ” λ•…μ΄μ—ˆκ³ , λ‚˜λ¨Έμ§€ 땅은 이미 λ‹€λ₯Έ μ‚¬λžŒλ“€μ΄ κ²½μž‘ν•˜κ³  μžˆμ—ˆμŠ΅λ‹ˆλ‹€. μ›κ³ λŠ” μ΄λŸ¬ν•œ 사싀을 μ•Œμ§€ λͺ»ν•œ 채 맀맀계약을 μ²΄κ²°ν•˜μ˜€κ³ , λ‚˜μ€‘μ— 이λ₯Ό μ•Œκ²Œ λ˜μ–΄ 계약을 무효둜 μ£Όμž₯ν•˜μ˜€μŠ΅λ‹ˆλ‹€. 법원은 μ›κ³ μ˜ μ£Όμž₯이 착였둜 μΈν•œ μ˜μ‚¬ν‘œμ‹œμ˜ μ·¨μ†Œλ‘œλ„ λ³Ό 수 μžˆλ‹€κ³  νŒλ‹¨ν•˜μ˜€μŠ΅λ‹ˆλ‹€.\\n\\n이 두 사건 λͺ¨λ‘ 맀수인이 맀맀 λŒ€μƒ λΆ€λ™μ‚°μ˜ μ‹€μ œ μƒνƒœλ₯Ό μ œλŒ€λ‘œ μ•Œμ§€ λͺ»ν•œ 채 계약을 μ²΄κ²°ν•œ ν›„, κ·Έ 사싀을 μ•Œκ²Œ λ˜μ–΄ 법적 λΆ„μŸμ΄ λ°œμƒν•œ μ‚¬λ‘€μž…λ‹ˆλ‹€. μ§ˆλ¬Έμžλ‹˜μ˜ 상황과 μœ μ‚¬ν•œ 점이 λ§ŽμœΌλ―€λ‘œ μ°Έκ³ ν•˜μ‹œκΈ° λ°”λžλ‹ˆλ‹€.\\n\\n### μš”μ•½\\n- **사건λͺ… 1**: λ§€λ„μΈμ˜ κΆλ°•ν•œ 사정을 μ΄μš©ν•˜μ—¬ 뢀동산을 μ €λ ΄ν•˜κ²Œ λ§€μˆ˜ν•œ 경우.\\n- **사건λͺ… 2**: λ§€μˆ˜ν•œ 뢀동산이 μ‹€μ œλ‘œλŠ” κ²½μž‘ν•  수 μ—†λŠ” λ•…μ΄μ—ˆμŒμ„ λ‚˜μ€‘μ— μ•Œκ²Œ 된 경우.\\n\\n이와 같은 사둀λ₯Ό 톡해 법적 λŒ€μ‘ λ°©μ•ˆμ„ λͺ¨μƒ‰ν•΄λ³΄μ‹œκΈ° λ°”λžλ‹ˆλ‹€. 좔가적인 법적 쑰언이 ν•„μš”ν•˜μ‹œλ©΄ λ³€ν˜Έμ‚¬μ™€ μƒλ‹΄ν•˜μ‹œκΈ°λ₯Ό ꢌμž₯λ“œλ¦½λ‹ˆλ‹€.\\n\\nκ°μ‚¬ν•©λ‹ˆλ‹€.\\n\\n### 좜처\\n- 214987, 손해배상등, 68λ‹€88, 1968.07.30\\n- 153300, λ§€λ§€λŒ€κΈˆλ°˜ν™˜λ“±, 66λ‹€1289, 1966.09.20'"
300
+ ]
301
+ },
302
+ "execution_count": 28,
303
+ "metadata": {},
304
+ "output_type": "execute_result"
305
+ }
306
+ ],
307
+ "source": [
308
+ "rag_chain(\n",
309
+ " \"논밭은 μ•½ 2μ²œν‰μ„ μƒ€λŠ”λ°, μ•Œκ³  λ³΄λ‹ˆ 집을 지을 수 μ—†λŠ” 땅이야. 이런 사기와 λΉ„μŠ·ν•œ κ±Έ μ•Œλ €μ€˜!\"\n",
310
+ ")"
311
+ ]
312
+ },
313
+ {
314
+ "cell_type": "code",
315
+ "execution_count": null,
316
+ "metadata": {},
317
+ "outputs": [],
318
+ "source": []
319
+ }
320
+ ],
321
+ "metadata": {
322
+ "kernelspec": {
323
+ "display_name": "langchain",
324
+ "language": "python",
325
+ "name": "python3"
326
+ },
327
+ "language_info": {
328
+ "codemirror_mode": {
329
+ "name": "ipython",
330
+ "version": 3
331
+ },
332
+ "file_extension": ".py",
333
+ "mimetype": "text/x-python",
334
+ "name": "python",
335
+ "nbconvert_exporter": "python",
336
+ "pygments_lexer": "ipython3",
337
+ "version": "3.11.9"
338
+ }
339
+ },
340
+ "nbformat": 4,
341
+ "nbformat_minor": 2
342
+ }