sesac-NoF / NoF

0 stars 0 forks source link

법률서비스 전체코드 #21

Open ykdb opened 1 day ago

ykdb commented 1 day ago

법률서비스 전체코드 흐름도

법률 서비스에서 검색 입력부터 판례 검색 및 참조 조문 제시까지 전체적인 기능을 구현하기 위한 예시 코드를 제시하겠습니다. 이 코드는 Flask 백엔드와 KoBERT를 사용한 법적 질문 분석, Elasticsearch를 사용한 판례 검색, PostgreSQL을 사용한 데이터베이스 연동, 그리고 React 프론트엔드를 통합한 구조로 구성됩니다.

구성 요소:

  1. 백엔드 (Flask + KoBERT + PostgreSQL)

(1) Flask API 서버 app.py (Flask API 서버)

python
코드 복사
from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
from transformers import BertTokenizer, BertModel
import torch
from elasticsearch import Elasticsearch

app = Flask(__name__)
CORS(app)

# 데이터베이스 설정
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:password@localhost/lawdb'
db = SQLAlchemy(app)

# Elasticsearch 설정
es = Elasticsearch(['http://localhost:9200'])

# KoBERT 설정
tokenizer = BertTokenizer.from_pretrained('monologg/kobert')
model = BertModel.from_pretrained('monologg/kobert')

# 판례 데이터베이스 모델
class CaseLaw(db.Model):
    __tablename__ = 'case_law'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(255))
    summary = db.Column(db.Text)
    full_text = db.Column(db.Text)
    court = db.Column(db.String(100))
    date = db.Column(db.Date)
    related_laws = db.Column(db.String(255))  # 참조된 법 조문

# 법 조문 데이터베이스 모델
class Law(db.Model):
    __tablename__ = 'laws'
    id = db.Column(db.Integer, primary_key=True)
    law_number = db.Column(db.String(50))
    law_title = db.Column(db.String(255))
    law_text = db.Column(db.Text)

# 판례 검색 엔드포인트
@app.route('/search_cases', methods=['POST'])
def search_cases():
    query = request.json.get('query')

    # KoBERT로 질문 분석
    inputs = tokenizer(query, return_tensors="pt", padding=True, truncation=True)
    outputs = model(**inputs)
    question_embedding = outputs.last_hidden_state.mean(dim=1).detach().numpy()

    # Elasticsearch로 판례 검색
    res = es.search(index="case_law", body={
        "query": {
            "match": {
                "summary": query
            }
        }
    })
    cases = [{
        'id': hit['_source']['id'],
        'title': hit['_source']['title'],
        'summary': hit['_source']['summary'],
        'court': hit['_source']['court'],
        'date': hit['_source']['date'],
        'related_laws': hit['_source']['related_laws']
    } for hit in res['hits']['hits']]

    return jsonify(cases)

# 판례 세부 정보 및 참조 법령 제공
@app.route('/case/<int:id>', methods=['GET'])
def get_case(id):
    case = CaseLaw.query.get(id)
    if case:
        related_laws = case.related_laws.split(",")
        laws = Law.query.filter(Law.law_number.in_(related_laws)).all()
        law_data = [{'law_number': law.law_number, 'law_title': law.law_title, 'law_text': law.law_text} for law in laws]
        return jsonify({
            'title': case.title,
            'summary': case.summary,
            'full_text': case.full_text,
            'court': case.court,
            'date': case.date,
            'related_laws': law_data
        })
    return jsonify({'error': 'Case not found'}), 404

if __name__ == '__main__':
    app.run(debug=True)

(2) Elasticsearch 설정 및 데이터 인덱싱 index_data.py (Elasticsearch 인덱싱)

python
코드 복사
from elasticsearch import Elasticsearch

es = Elasticsearch(['http://localhost:9200'])

# 판례 데이터 Elasticsearch에 인덱싱
case_data = [
    {
        "id": 1,
        "title": "계약 불이행 판례",
        "summary": "계약 불이행 관련 판례입니다.",
        "court": "서울고등법원",
        "date": "2021-06-18",
        "related_laws": "375"
    },
    {
        "id": 2,
        "title": "부동산 거래 관련 판례",
        "summary": "부동산 거래 분쟁 판례입니다.",
        "court": "대법원",
        "date": "2020-11-05",
        "related_laws": "250, 128"
    }
]

for case in case_data:
    es.index(index="case_law", id=case['id'], body=case)
  1. 데이터베이스 (PostgreSQL) (1) 판례 및 법 조문 테이블 생성 models.py
sql
코드 복사
CREATE TABLE case_law (
    id SERIAL PRIMARY KEY,
    title VARCHAR(255),
    summary TEXT,
    full_text TEXT,
    court VARCHAR(100),
    date DATE,
    related_laws VARCHAR(255)  -- 참조된 법 조문 목록 (쉼표로 구분)
);

CREATE TABLE laws (
    id SERIAL PRIMARY KEY,
    law_number VARCHAR(50),
    law_title VARCHAR(255),
    law_text TEXT
);
  1. 프론트엔드 (React) (1) 판례 검색 및 상세 정보 표시 App.js
javascript
코드 복사
import React, { useState } from 'react';
import axios from 'axios';

const App = () => {
  const [query, setQuery] = useState('');
  const [cases, setCases] = useState([]);
  const [selectedCase, setSelectedCase] = useState(null);

  const searchCases = () => {
    axios.post('http://localhost:5000/search_cases', { query })
      .then(response => setCases(response.data))
      .catch(error => console.error(error));
  };

  const fetchCaseDetails = (id) => {
    axios.get(`http://localhost:5000/case/${id}`)
      .then(response => setSelectedCase(response.data))
      .catch(error => console.error(error));
  };

  return (
    <div>
      <h1>법률 검색 서비스</h1>
      <input 
        type="text" 
        value={query} 
        onChange={(e) => setQuery(e.target.value)} 
        placeholder="법적 질문 입력"
      />
      <button onClick={searchCases}>검색</button>

      {cases.length > 0 && (
        <div>
          <h2>검색 결과:</h2>
          <ul>
            {cases.map((caseItem) => (
              <li key={caseItem.id} onClick={() => fetchCaseDetails(caseItem.id)}>
                {caseItem.title} - {caseItem.court} ({caseItem.date})
              </li>
            ))}
          </ul>
        </div>
      )}

      {selectedCase && (
        <div>
          <h2>{selectedCase.title}</h2>
          <p>{selectedCase.summary}</p>
          <p>{selectedCase.full_text}</p>
          <h3>참조 법령:</h3>
          <ul>
            {selectedCase.related_laws.map((law, index) => (
              <li key={index}>
                {law.law_number}: {law.law_title} - {law.law_text}
              </li>
            ))}
          </ul>
        </div>
      )}
    </div>
  );
};

export default App;
  1. 실행 및 테스트

(1) 백엔드 실행

bash
코드 복사
cd backend
python app.py

(2) Elasticsearch 인덱싱

bash
코드 복사
python index_data.py

(3) 프론트엔드 실행

bash
코드 복사
cd frontend
npm start
  1. 결론 위의 코드는 Flask 백엔드, KoBERT 모델을 통한 질문 분석, Elasticsearch를 통한 판례 검색, 그리고 PostgreSQL을 활용한 참조 법령 제공 기능을 모두 포함한 기본적인 법률 서비스 시스템의 구현 예시입니다. 프론트엔드(React)에서 사용자가 입력한 법적 질문을 백엔드로 전송하고, KoBERT를 통해 분석된 결과를 바탕으로 Elasticsearch에서 검색된 판례와 참조 조문을 표시합니다.
ykdb commented 1 day ago

검색어 입력부터 판례 출력까지의 과정 설계도

검색어가 입력된 후 법률 서비스에서 판례 출력까지의 전체 과정을 도식화하여 나타낸 설계도입니다. 이 과정은 사용자로부터 검색어가 입력된 후, 백엔드 서버에서 처리하고 KoBERT 및 Elasticsearch를 사용해 판례를 분석 및 검색한 후 프론트엔드로 출력하는 흐름을 포함합니다.

javascript
코드 복사
┌─────────────────────────────────────────────────────────────┐
│                      사용자 (프론트엔드 UI)                  │
│─────────────────────────────────────────────────────────────│
│ 1. 검색어 입력:                                              │
│    - 사용자가 법적 질문 입력 (검색창)                        │
│    - 예: "계약 불이행 관련 판례"                             │
│                                                             │
│ 2. "검색" 버튼 클릭 → API 호출                               │
└─────────────────────────────┬───────────────────────────────┘
                              │ (HTTP POST 요청: 검색어 전달)
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                백엔드 API 서버 (Flask, FastAPI)              │
│─────────────────────────────────────────────────────────────│
│ 3. 요청 수신:                                                │
│    - 백엔드 서버에서 검색어를 수신                           │
│    - 입력된 검색어를 KoBERT로 전달                           │
│                                                             │
│ 4. KoBERT를 통한 질문 분석 및 키워드 추출                    │
│    - KoBERT를 사용해 검색어 임베딩                           │
│    - 주요 키워드 및 벡터 생성                               │
│                                                             │
│ 5. Elasticsearch로 판례 검색 요청                            │
│    - 키워드를 사용해 Elasticsearch에 판례 검색 요청          │
│                                                             │
│ 6. Elasticsearch에서 판례 검색                               │
│    - BM25 알고리즘으로 판례와 키워드 간 유사도 분석          │
│    - 가장 관련성 높은 판례를 반환                           │
│                                                             │
│ 7. 판례 데이터 가공 및 반환                                   │
│    - 판례 요약본 및 참조 법조문 데이터 반환                  │
│                                                             │
│ 8. 프론트엔드로 검색 결과 전송                               │
│    - JSON 형식으로 판례 데이터 전달                          │
└─────────────────────────────┬───────────────────────────────┘
                              │ (HTTP 응답: 판례 데이터 전달)
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                  프론트엔드 (React, Vue.js)                  │
│─────────────────────────────────────────────────────────────│
│ 9. 판례 데이터 수신 및 화면에 렌더링                          │
│    - React.js 또는 Vue.js로 UI에 판례 결과 표시              │
│    - 판례 리스트와 요약 정보 출력                            │
│                                                             │
│ 10. 사용자 상호작용                                          │
│    - 사용자는 판례 리스트에서 특정 판례를 선택하여 상세 정보│
│      조회 가능                                               │
│    - 상세 정보에 참조 법조문 표시                            │
└─────────────────────────────────────────────────────────────┘

세부 과정 설명

  1. 프론트엔드 (검색어 입력 및 전송): 사용자는 검색창에 법적 질문 또는 검색어를 입력하고, "검색" 버튼을 클릭합니다. 프론트엔드에서 이 입력을 백엔드 서버로 전달하기 위해 HTTP 요청을 보냅니다.

  2. 백엔드 서버 (검색어 분석 및 처리): Flask 또는 FastAPI에서 요청을 수신하고, KoBERT 모델을 통해 입력된 검색어를 분석합니다. KoBERT는 질문의 키워드를 추출하고, 벡터화를 통해 검색어와 관련된 의미를 이해합니다.

  3. Elasticsearch (판례 검색): KoBERT가 생성한 임베딩 벡터 및 키워드를 사용하여 Elasticsearch에서 판례를 검색합니다. Elasticsearch는 BM25 알고리즘을 사용하여 저장된 판례와 검색어 간의 유사도를 계산하고, 가장 관련성이 높은 판례를 반환합니다.

  4. 백엔드 처리 및 결과 반환: 백엔드는 Elasticsearch에서 받은 판례 데이터를 가공하여, 프론트엔드가 쉽게 처리할 수 있는 JSON 형식으로 변환한 후 이를 반환합니다.

  5. 프론트엔드 (결과 렌더링 및 출력): 프론트엔드는 백엔드에서 받은 판례 리스트와 요약본을 사용자 화면에 표시합니다. 사용자는 관련 판례 리스트에서 특정 판례를 선택하여 세부 정보를 확인하고, 판례에서 인용된 참조 법조문도 함께 확인할 수 있습니다.

기술 스택 요약

프론트엔드 (React, Vue.js):

사용자 입력 및 판례 데이터 표시. API와 통신하여 판례 검색 결과를 UI에 출력.

백엔드 (Flask, FastAPI):

사용자의 질문을 받아 KoBERT와 Elasticsearch로 처리 후 결과 반환.

KoBERT: 법적 질문을 분석하고, 핵심 키워드를 추출한 후 Elasticsearch로 검색어 전송.

Elasticsearch: 판례 데이터베이스에서 관련 판례를 검색하고 유사도에 따라 결과를 반환.

PostgreSQL: 판례와 법조문 데이터베이스로, 검색된 판례와 참조 법조문 정보를 제공.