Ⅰ. 오전 수업
A. 1교시
1. 지난 시간 복습
2. 회원 관리 구현
B. 2교시
1. 회원 관리 구현 (cont.)
C. 3교시
1. DB 연결 3가지 프로세스
Ⅱ. 오후 수업
A. 4교시
1. 지난 시간 복습
2. RAG 평가 지표 알아보기
B. 5교시
1. RAGAS
2. RAG 평가용 데이터셋 비교
C. 6교시
1. Human-labeled
2. RAGAS Score 계산
Ⅲ. CAREER UP
오늘 학습한 내용 복습
Ⅳ. 하루 돌아보기
a href="/esports/lol")


node 서버와 DB 서버 연결하기



<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>회원 관리 시스템입니다!</h1>
<a href="">회원 가입 페이지</a>
</body>
</html>






action="http://localhost:3000/join" 입력 → 오류 발생

action="http://localhost:3000/db/join"
const dbRouter = require("./routes/dbRouter");app.use("/db",dbRouter);
npm i mysql2 설치


conn.connect();module.exports = conn;

let {id,pw,nick} = req.body;: 이름과 순서가 일치해야 함Destructuring assignment
객체 비구조화 할당(=구조 분해 할당)은 객체의 속성 값을 해체하여 원하는 변수에 할당하는 JavaScript 문법으로, 객체 리터럴 안에 {} 중괄호를 사용하고, 변수 이름은 객체의 속성 이름과 같게 작성하면 됩니다. 예를 들어, { name, age } = user와 같이 작성하여 객체 user의 name과 age 속성을 각각 name과 age 변수에 할당할 수 있습니다.
let sql = "insert into member values (?,?,?);";?의 의미: 아직 어떤 값을 넣을지 모른다는 의미
conn.query(sql,[id,pw,nick],);: sql 변수에 있는 쿼리문 쓸 건데 물음표에 [] 안의 변수를 넣어달라는 뜻





sendFile() 쓰면 안 되는 이유
sendFile() 쓰면 경로는 안 바뀌었는데 화면은 바뀜
문제점: 새로고침 10번 하면 10번 가입됨 → 쿼리문에 영향을 주기 때문
http://localhost:3000 메인 입장/db 있어요? → 없어요 → pageRouter.js 실행:3000 뒤에 뭐 있어요? → 없어요 → main.html 리턴/db 있어요? → 없어요 → pageRouter.js 실행:3000 뒤에 뭐 있어요? → /join 있어요 → join.html 리턴http://localhost:3000/db/join에 post 방식으로 값 전송
/db 있어요? → 네 → dbRouter.js 실행/db 뒤에 뭐 있어요? → post로 /join 왔어요 → 로직 실행conn.query: db랑 연결되었으면 쿼리문 돌리자 → sql 변수에 들어 있는 쿼리문!(insert)
| 지표 | 특징 | 장점 | 단점 | 점수 범위 | 해석 | 좋은 점수 기준 | 주의사항 |
|---|---|---|---|---|---|---|---|
| BLEU | 기계 번역 평가용, n-그램 일치율 기반 | 계산 간단, 전통적으로 많이 사용 | 의미 같아도 표현 다르면 낮음 | 0 ~ 1 | 참조와 단어 수준 유사도 | ≥ 0.5: 꽤 유사, ≥ 0.7: 매우 유사 | 어휘 다양성 높은 경우 과소평가 가능 |
| ROUGE | 요약 평가에 특화, n-그램/구절/최장 공통 부분 수열 | 요약 핵심어 커버 잘 측정 | 단어 겹침 위주, 의미는 반영 약함 | 0 ~ 1 | 참조 요약과 단어·구절 겹침 정도 | ≥ 0.5: 주요 내용 커버, ≥ 0.7: 매우 좋음 | 의미 다르더라도 단어 겹치면 점수 높을 수 있음 |
| METEOR | BLEU 보완, 동의어·어간·형태 고려 | 인간 평가와 상관도 높음 | 계산 복잡, 언어 자원 필요 | 0 ~ 1 | 참조와 어휘적·의미적 유사도 | ≥ 0.6~0.7: 꽤 좋은 결과 | 지원 언어 한정, 속도 느릴 수 있음 |
| SemScore | 임베딩 기반 의미 유사도 | 표현 달라도 의미 같으면 높음 | 임베딩 모델 품질에 의존 | -1 ~ 1 (보통 0~1) | 의미적 유사도 (코사인 유사도) | ≥ 0.7: 유사, ≥ 0.85: 거의 동일 | 모델 성능·도메인에 따라 점수 신뢰도 달라짐 |
→ 여러 평가 지표를 확인해서 적당한 걸 선택하는 게 중요
점수가 낮게 나왔다면 낮게 나온 이유를 분석하기!
METEOR에서 사용한 wordnet에 문제가 있다는 제보가 들어왔음:
wordnet이 영어만 지원된다고 함 → 한국어 워드넷 받아서 쓰는 법 알아오기!
wordnet이란?
Wordnet with NLTK
자연어 처리 - Word Embedding(WordNet)
NLTK에서 WordNet의 다국어 확장인 omw-1.4 (Open Multilingual Wordnet) 리소스를 별도로 다운로드 (nltk.download('omw-1.4'))해 다른 언어의 레마(lemma)를 조회해 보았는데 한국어는 없음😭

추가: Wordnet 관련
한국어에 대해 NLTK WordNet은 공식적으로 지원하지 않습니다. WordNet은 주로 영어 어휘에 대해 동의어, 어간(stemming), 형태 변화를 처리하기 위한 자원으로 설계되었고, NLTK에 포함된 WordNet도 영어에 최적화되어 있습니다. 따라서 NLTK WordNet의 동의어 사전이나 어간 매칭 기능은 한국어에 적용되지 않습니다.
METEOR 평가지표 자체는 동의어, 어간 추출, 그리고 형태 변화를 반영하는 장점이 있지만, 그 기반이 되는 WordNet 등의 언어자원이 지원하는 언어에 한정됩니다. 한국어의 경우 공식적인 WordNet 지원이 없기 때문에, NLTK의 meteor_score 함수가 WordNet을 사용해 동의어, 어간, 형태 변화 매칭을 수행하지 않고 단순 토큰 매칭 위주로 평가가 진행될 가능성이 높습니다.
meteor_score 함수 내 자동 WordNet 활용은 영어 텍스트에는 동작하지만, 한국어 텍스트에서는 동의어·어간·형태소 변화를 고려하지 않고 단순 토큰 매칭만으로 평가가 이루어집니다. 한국어에 특화된 언어자원이나 형태소 분석기를 이용하거나, 한국어 WordNet(다수 비공식/개별 프로젝트 존재)을 연동해야 METEOR와 유사한 의미 기반 평가가 가능해집니다.
요약하면:
① NLTK WordNet은 영어 중심이며 한국어 지원이 없습니다.
② NLTK meteor_score 함수는 WordNet에 기반하여 동의어/어간 매칭을 수행하나, 한국어에서는 이를 활용할 수 없습니다.
③ 따라서 한국어 문장에 대해선 동의어, 어간, 형태 변화 고려 없이 단순 토큰 매칭으로 METEOR 점수가 계산됩니다.
④ 한국어 평가를 위해선 한국어 형태소 분석기 또는 별도 한국어 WordNet 자원이 필요합니다.
한국어 WordNet 자원을 별도로 사용하려면, 국내에서 개발된 한국어 WordNet 프로젝트(예: KAIST 오픈 한국어 워드넷(KWN))나 비슷한 형태의 한국어 유의어/동의어 사전을 활용해야 합니다. NLTK 기본 WordNet은 영어 전용이므로, 이와 별개로 아래와 같은 절차가 필요합니다.
- 한국어 WordNet 자원 연동 방법 개요
- 한국어 WordNet 데이터 확보
- KAIST 오픈 한국어 워드넷(KWN) 프로젝트(https://koasas.kaist.ac.kr 등)에서 데이터셋을 내려받거나 API를 연동.
- 또는 공개된 한국어 유의어/동의어 사전 파일 활용.
- 데이터 파싱 및 연동 라이브러리 준비
- JSON, XML, CSV 등 형태로 된 WordNet 데이터를 파이썬에서 파싱.
- 필요시 한국어 형태소 분석기(KoNLPy, Kkma, Komoran, Kiwi 등)를 사용해 토큰화, 어간 추출.
- 자주 쓰이는 것은 데이터 구조를 클래스/함수로 Wrapping해서 동의어 집합 추출 함수 등 개발.
- METEOR 함수 내 동의어 매칭 모듈 교체 또는 확장
- 표준
meteor_score함수는 영어 WordNet에 묶여 있으므로, 한국어 동의어 검사 로직을 별도로 구현해 평가 코드에 통합.- 예를 들어, 토큰별로 한국어 WordNet 기반 동의어 목록을 조회해 매칭 점수를 조정.
- 예시 코드 구성
- 한국어 문장을 형태소 단위로 토큰화 후, 각 토큰의 동의어를 한국어 WordNet에서 조회.
- 기존 meteor_score 내부에서 영어 WordNet을 참조하는 부분을 대체 또는 병행 적용.
- 참고할만한 라이브러리 및 도구
- KAIST Open Korean WordNet (KWN)
- KoNLPy: 한국어 형태소 분석기 (예: Komoran, Kkma, Hannanum, Kiwi)
- Soynlp: 한국어 문장 분리 및 단어 추출 도구
- 직접 구축한 유의어 사전 또는 DB와 연동
- 이 방식으로 METEOR 평가 시 동의어 매칭을 실제 한국어 WordNet 데이터 기반으로 확장할 수 있습니다. 다만 구현 난이도가 있으므로, 완전한 동의어 기반 METEOR 지원은 추가 개발이 필요하며 기존 python-nltk meteor_score 함수 대신 커스텀 구현이나 확장 패키지를 고려하는 것이 좋습니다.
import os
with open('./key/.openai_api_key','r') as f:
api_key = f.read().strip()
# 환경변수 설정 (딕셔너리형태)
os.environ['OPENAI_API_KEY'] = api_key
import os
if not os.path.exists("./module"):
os.mkdir("./module")
%%writefile module/PDFRAG.py
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.prompts.chat import ChatPromptTemplate
from langchain.chains import RetrievalQAWithSourcesChain
from langchain_openai import ChatOpenAI
def load_pdf(file_path):
""" PDF 파일 로드 및 텍스트 분할"""
loader = PyPDFLoader(file_path)
return loader.load()
def text_split(doc) :
""" 텍스트 분할 """
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50,
length_function = len)
texts = text_splitter.split_documents(doc)
return texts
def create_retriever(texts, file_name, num) :
""" 벡터 DB 저장하고 검색기 설정 """
vec_db = FAISS.from_documents(documents=texts, embedding=OpenAIEmbeddings())
vec_db.save_local("./db/" + file_name) # 만든 FAISS 벡터 DB를 ./db/faiss02 같은 폴더에 저장.
# 매번 PDF를 읽고 임베딩을 새로 만들면 시간·비용 낭비 → 한 번 만들어 저장해두면 다음에 바로 로드 가능.
# 방금 저장한 벡터 DB를 다시 불러옴
vec_db2 = FAISS.load_local("./db/" + file_name, OpenAIEmbeddings(),
allow_dangerous_deserialization=True)
#FAISS DB를 retriever(검색기) 객체로 변환.
retriever = vec_db2.as_retriever(search_kwargs={"k": num})
return retriever
def create_chain(retriever) :
""" 대화형 프롬프트 템플릿 설정 """
prompt = ChatPromptTemplate.from_messages([
('system', "{summaries}"),
("user", "{question}")
])
llm = ChatOpenAI(model_name="gpt-4o", temperature=0)
chain = RetrievalQAWithSourcesChain.from_chain_type(
llm=llm,
chain_type="stuff",
retriever = retriever,
return_source_documents=False,
chain_type_kwargs={"prompt": prompt}
)
return chain
Writing module/PDFRAG.py
# 위에서 생성한 모듈 불러와 사용하기
from module.PDFRAG import load_pdf, text_split, create_retriever, create_chain
# 파일 읽기
documents = load_pdf("./data/SPRi_AI_Brief_8월호_산업동향.pdf")
# 표지, 차례, 간지 삭제
documents = documents[3:]
# 텍스트 분리
texts = text_split(documents)
# 벡터 DB 저장하고 검색기 설정
retriever = create_retriever(texts, "faiss_db_01", 2)
# 대화형 프롬프트 템플릿 설정
chain = create_chain(retriever)
# 체인 실행
result = chain.invoke("AI가 일자리를 줄이는 대신 창출하는 영역은?")
print(result)
{'question': 'AI가 일자리를 줄이는 대신 창출하는 영역은?', 'answer': 'AI는 여러 분야에서 새로운 일자리를 창출할 수 있는 잠재력을 가지고 있습니다. 다음은 AI가 일자리를 창출할 수 있는 몇 가지 영역입니다:\n\n1. **AI 개발 및 연구**: AI 시스템을 개발하고 개선하기 위한 연구자, 엔지니어, 데이터 과학자 등의 수요가 증가하고 있습니다.\n\n2. **데이터 분석 및 관리**: AI 시스템이 작동하기 위해서는 대량의 데이터가 필요하며, 이를 수집, 정리, 분석하는 데이터 전문가의 역할이 중요해지고 있습니다.\n\n3. **AI 유지보수 및 운영**: AI 시스템의 유지보수, 운영, 모니터링을 담당하는 직무가 필요합니다.\n\n4. **교육 및 훈련**: AI 기술을 이해하고 활용할 수 있도록 교육하고 훈련하는 직무가 증가하고 있습니다.\n\n5. **AI 윤리 및 규제**: AI의 윤리적 사용과 관련된 정책 개발 및 규제 업무를 담당하는 직무가 필요합니다.\n\n6. **고객 지원 및 서비스**: AI 기반 제품 및 서비스를 사용하는 고객을 지원하는 역할이 중요해지고 있습니다.\n\n이러한 영역들은 AI 기술의 발전과 함께 지속적으로 성장할 것으로 예상됩니다.', 'sources': ''}
print(result["answer"])
AI는 여러 분야에서 새로운 일자리를 창출할 수 있는 잠재력을 가지고 있습니다. 다음은 AI가 일자리를 창출할 수 있는 몇 가지 영역입니다:
1. **AI 개발 및 연구**: AI 시스템을 개발하고 개선하기 위한 연구자, 엔지니어, 데이터 과학자 등의 수요가 증가하고 있습니다.
2. **데이터 분석 및 관리**: AI 시스템이 작동하기 위해서는 대량의 데이터가 필요하며, 이를 수집, 정리, 분석하는 데이터 전문가의 역할이 중요해지고 있습니다.
3. **AI 유지보수 및 운영**: AI 시스템의 유지보수, 운영, 모니터링을 담당하는 직무가 필요합니다.
4. **교육 및 훈련**: AI 기술을 이해하고 활용할 수 있도록 교육하고 훈련하는 직무가 증가하고 있습니다.
5. **AI 윤리 및 규제**: AI의 윤리적 사용과 관련된 정책 개발 및 규제 업무를 담당하는 직무가 필요합니다.
6. **고객 지원 및 서비스**: AI 기반 제품 및 서비스를 사용하는 고객을 지원하는 역할이 중요해지고 있습니다.
이러한 영역들은 AI 기술의 발전과 함께 지속적으로 성장할 것으로 예상됩니다.
# 질문에 대한 답변을 생성하는 함수 생성
def ask_question (input:dict):
return {"answer": chain.invoke(input["question"])}
# 입력값은 딕셔너리 형태로 입력받음
ask_question({"question": "AI가 일자리를 줄이는 대신 창출하는 영역은?"})
{'answer': {'question': 'AI가 일자리를 줄이는 대신 창출하는 영역은?',
'answer': 'AI는 여러 분야에서 새로운 일자리를 창출할 수 있는 잠재력을 가지고 있습니다. 다음은 AI가 일자리를 창출할 수 있는 몇 가지 영역입니다:\n\n1. **AI 개발 및 연구**: AI 시스템을 개발하고 개선하기 위한 연구자, 엔지니어, 데이터 과학자 등의 수요가 증가하고 있습니다.\n\n2. **데이터 분석 및 관리**: AI 시스템이 작동하기 위해서는 대량의 데이터가 필요하며, 이를 수집, 정리, 분석하는 데이터 전문가의 역할이 중요해지고 있습니다.\n\n3. **AI 유지보수 및 운영**: AI 시스템의 유지보수, 운영, 모니터링을 담당하는 직무가 필요합니다.\n\n4. **AI 교육 및 훈련**: AI 기술을 이해하고 활용할 수 있도록 교육하는 역할이 중요해지면서 관련 교육자와 트레이너의 수요가 증가하고 있습니다.\n\n5. **윤리 및 규제 준수**: AI의 윤리적 사용과 규제 준수를 보장하기 위한 전문가들이 필요합니다.\n\n6. **AI와 인간의 협업**: AI가 인간의 업무를 보조하거나 협업하는 방식으로 사용되면서, 이를 관리하고 최적화하는 직무가 생겨나고 있습니다.\n\n이러한 영역들은 AI 기술의 발전과 함께 지속적으로 성장할 것으로 예상됩니다.',
'sources': ''}}
[RAA-gahs]: Retrieval-Augmented Generation Assessment의 약자!pip install -qU ragas rapidfuzz pi-heif unstructured unstructured_inference| 구분 | 사람이 만든 데이터셋 (Human-labeled) | 합성 데이터셋 (Synthetic, LLM-generated) |
|---|---|---|
| 구축 방식 | 전문가/사용자가 직접 질문·정답·근거 작성 | LLM을 활용해 문서에서 자동 생성 |
| 품질 | 신뢰도 높음, 실제 도메인 반영 | 품질 편차 있음, 검수 필요 |
| 다양성 | 작성자 역량/시간에 제한 → 질문 범위 좁을 수 있음 | 대량 생성 가능, 난이도·질문 유형 다양하게 생성 가능 |
| 효율성 | 시간·비용 많이 듦 (노동 집약적) | 빠르게 수백~수천 샘플 생성 가능 |
| 활용 목적 | “골든셋”(기준 데이터셋)으로 성능 검증 | 대규모 회귀 테스트, 자동화된 품질 모니터링 |
| 한계 | 구축 규모 확장 어려움 | LLM 편향, 문체 단조화, 잘못된 Q/A 가능 |
| 권장 사용법 | 소규모지만 정확한 기준 데이터셋 | 보완재로 대량 생성 후 일부 검수 |
# 파일 읽기
documents_2 = load_pdf("./data/인공일반지능의 이해.pdf")
# 텍스트 분리
texts_2 = text_split(documents_2)
# 벡터 DB 저장 후 검색기 설정 ("faiss_db_02", 상단 2개의 유사한 결과 사용)
retriever_2 = create_retriever(texts_2, "faiss_db_02", 2)
from langchain_openai import ChatOpenAI
from langchain.prompts.chat import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
# LLM 모델, 템플릿 작성
llm = ChatOpenAI(model_name="gpt-4o-mini", temperature=0)
template = """당신은 질의 응답 작업의 보조자입니다. context 내용을 사용하여 질문에 답하세요.
답을 모르면 모른다고 하세요. 최대 두 문장을 사용하고 답변을 간결하게 해주세요.
Question: {question}
Context: {context}
Answer:
"""
prompt = ChatPromptTemplate.from_template(template)
# 체인 생성
chain_2 = (
{"context": retriever_2, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
questions = [
"AGI(인공일반지능)는 무엇이며 기존 AI와 어떤 점이 다른가?",
"AGI 구현을 위해 제시된 핵심 기술·아키텍처의 예는 무엇인가?",
"AGI 실현 예상 시점에 대해 문서가 제시한 전망은?"
]
ground_truths = [
# Q1
"AGI는 인간 수준의 인지 능력으로 다양한 과업에 지식을 전이해 해결하는 AI를 뜻한다. "
"기존 과업 특화형 AI와 달리 스스로 학습·적응·추론하며 다중 작업을 수행한다.",
# Q2
"인과적 세계 모델 등 새로운 알고리즘/아키텍처, 지속적 학습·메타학습, "
"양자·아날로그 컴퓨팅 결합 등 고도화된 컴퓨팅이 필요하다고 서술된다.",
# Q3
"전망은 엇갈리나, 대체로 5~10년 이상이 필요하며 2035년경 초기 징후가 보일 수 있다는 관측도 제시된다."
]
# 비교를 위한 LLM의 답변 저장해 줄 빈 리스트 생성 (생성 품질)
answers = []
# LLM 응답을 위해 사용된 RAG 에시 문장 (검색 품질)
contexts = []
# 평가 데이터셋 생성
for query in questions:
# LLM으로 질문에 대한 답변 데이터 생성 후 저장
answers.append(chain_2.invoke(query)) # 여기서는 딕셔너리로 안 넣어도 됨
# 검색기 결과를 저장
# get_relevant_documents(query): 질문(quert)과 가장 관련성이 높은 document를 검색기를 통해 가져옴 → 검색기의 출력 기준이 되는 데이터
contexts.append([docs.page_content for docs in retriever_2.get_relevant_documents(query)])
answers
['AGI(인공일반지능)는 인간 수준의 인지 능력을 갖춘 AI로, 다양한 과업을 수행하고 학습하며 문제를 해결할 수 있는 능력을 의미합니다. 기존 AI는 특정 용도에 제한되어 있지만, AGI는 여러 과업을 넘나들며 지식을 전이할 수 있는 점에서 차별화됩니다.',
'AGI 구현을 위해 필요한 핵심 기술·아키텍처의 예로는 새로운 알고리즘과 엄청난 연산 성능이 요구된다고 언급됩니다. 현재의 디지털 컴퓨팅 및 GPU 기반 방식은 AGI 시대에는 부족할 것으로 보입니다.',
'레즈닉은 AGI가 2035년경부터 실질적인 돌파구가 보이기 시작할 것이라고 전망했습니다. AGI의 출현은 점진적이고 단계적으로 이루어질 것이라고 강조했습니다.']
contexts
[['지능 수준의 인지 유연성과 적응력을 갖추고 있어 추론과 문제 해결이 가능하다.\nAI 기술은 수십 년에 걸쳐 발전해 왔고, 최근 몇 년간 큰 진전을 이뤘다. 그러나 현재의 AI 도구는 여전히\n단일 용도에 머물고 있으며, 자기 인식, 맥락 파악, 추론 같은 인간 지능의 핵심 요소는 부족한 상태다. AI가\n자동차를 운전할 수 있다면, AGI는 운전뿐 아니라 자동차를 수리하고, 세차하고, 등록까지 할 수 있다고\nAGI 지지자들은 말한다.\n딜로이트 미국 법인의 최고 혁신 책임자 데보라 골든은 “오늘날 대부분 AI는 과업 특화형이다. 대화하거나\n이미지를 분류하거나 코드를 작성할 수 있지만, 모두 훈련받은 범위 내에서만 가능하다”라며, “AGI는\n과업을 넘나들며 학습하고 지식을 전이하며, 낯선 문제도 해결할 수 있다는 점에서 다르다”라고 강조했다.\n일부 연구자와 전문가들은 인간 인지 능력에 필적하거나 이를 초월하는 AI 시스템을 AGI로 정의하지만,',
'2년 전 AGI가 통제 불능 상태가 될 것을 우려해 1,000명의 기술 분야 책임자와 AI 연구자가 새로운 AI 모델\n출시를 중단하자는 공개서한에 서명한 바 있다. 물론 그런 중단은 실제로 이뤄지지 않았고, AGI도 아직\n등장하지 않았다.\n오픈AI의 CEO 샘 알트먼과 앤트로픽의 CEO 다리오 아모데이는 AGI가 곧 도래할 것이라고 주장했다.\n그러나 일부 AI 전문가들은 보다 보수적인 관점을 견지하고 있으며, 그 예상 시점도 “앞으로 5년에서 10년\n사이”부터 “수십 년 후”, 또는 “영원히 오지 않을 것”까지 다양하다.\n혼란스러운가? 다들 마찬가지다.\nAGI란 무엇인가?\n흥미롭게도 샘 알트먼 본인조차 최근 들어 AGI라는 표현에 회의적인 입장을 보인다. 사람마다 의미를\n다르게 사용하기 때문에 “그다지 유용한 용어가 아니다”라고 밝힌 것이다. 다만 일반적으로 AGI는 인간\n수준의 인지 능력을 갖춘 AI로 정의된다. AGI 지지자들에 따르면, 이 기술은 인간처럼 이해하고, 학습하고,'],
['실행당 전력 소모가 훨씬 적지만, 챗GPT나 제미나이 같은 서비스에서 발생하는 모든 질의마다 추론 과정이\n실행되므로, 전체 전력 소모량은 학습 못지않게 커진다.\nAGI는 이론적으로 끊임없이 학습하고 적응해야 하므로, 추론 과정에서 지금보다 훨씬 많은 자원을 소모할\n수 있다. 야밧카르는 “현실 세계 데이터를 지속적으로 수집하고 활용하는 것은 전혀 다른 차원의 연산\n성능을 요구한다”라고 지적했다.\n이는 컴퓨팅 방식의 전환이 필요하다는 의미다. 현재 AI 모델은 디지털 컴퓨팅과 GPU 기반으로 작동하고\n있지만, 지속적인 연산과 처리가 요구되는 AGI 시대에는 이 방식으로는 부족하다. 야밧카르는 “우리는\n아키텍처와 알고리즘 지식에서 새로운 돌파구가 필요하다”라며, “연구자가 지금 집중하고 있는 것도 바로\n그것”이라고 말했다. 또, “AGI에는 기존 방식이 아니라 완전히 새로운 알고리즘이 필요하며, 엄청난 연산\n성능이 전제돼야 한다”라고 덧붙였다.',
'AGI의 가능성과 위험성\nAGI 지지자들은 활용 가능성이 사실상 무한하다고 주장한다. 자주 언급되는 사례 중 하나가 자율적으로\n수행하는 과학 및 의학 연구다.\n기존 AI는 특정 과업에 맞춰 훈련되며, 인간의 주도와 개입이 필요하다. AGI 지지자는 AGI가 추상적으로\n사고하고 서로 다른 분야에서 통찰력을 도출하며, 독립적으로 과학 지식을 생성하고 검증하고 정제할 수\n있는 자율 연구원 역할을 할 수 있다고 본다.\nAGI는 방대한 기존 연구 문헌, 실험 데이터, 이론 모델 등을 분석해 현재 과학계의 이해에 존재하는 공백과\n연구 기회가 있는 영역을 식별하는 것부터 시작할 수 있다. 데이터를 분석해 패턴과 이상 징후, 공백을\n식별하고 변수 간의 관계와 상관관계를 파악하며, 가장 그럴듯한 설명을 추론하는 귀추법(Abductive\nReasoning)을 통해 새로운 가설을 제안한다.\n그 다음에는 실험 설계를 포함해 실험을 자율적으로 수행한다. 단순히 시뮬레이션을 실행하는 데 그치지'],
['레즈닉은 “AI가 지혜와 이해를 갖게 되는 순간, 그때가 AGI의 시점”이라고 말했다.\n가트너는 AGI의 초기 징후가 나타날 시점에 대한 목표 시점도 제시한다. 레즈닉은 “2035년경부터 AGI로\n가는 실질적인 돌파구가 보이기 시작할 것”이라고 전망했다. 향후 10년 동안은 획기적인 돌파보다는\n느리지만 꾸준한 진전이 이어질 것으로 보인다. 레즈닉은 “어느 날 갑자기 스위치를 켜듯 AGI가 등장하는\n일은 없을 것이다. 점진적으로, 단계적으로 이뤄질 것”이라고 강조했다.\ndl-itworldkorea@foundryco.com\n© 2025 IDG Communications, Inc. All Rights Reserved.',
'2년 전 AGI가 통제 불능 상태가 될 것을 우려해 1,000명의 기술 분야 책임자와 AI 연구자가 새로운 AI 모델\n출시를 중단하자는 공개서한에 서명한 바 있다. 물론 그런 중단은 실제로 이뤄지지 않았고, AGI도 아직\n등장하지 않았다.\n오픈AI의 CEO 샘 알트먼과 앤트로픽의 CEO 다리오 아모데이는 AGI가 곧 도래할 것이라고 주장했다.\n그러나 일부 AI 전문가들은 보다 보수적인 관점을 견지하고 있으며, 그 예상 시점도 “앞으로 5년에서 10년\n사이”부터 “수십 년 후”, 또는 “영원히 오지 않을 것”까지 다양하다.\n혼란스러운가? 다들 마찬가지다.\nAGI란 무엇인가?\n흥미롭게도 샘 알트먼 본인조차 최근 들어 AGI라는 표현에 회의적인 입장을 보인다. 사람마다 의미를\n다르게 사용하기 때문에 “그다지 유용한 용어가 아니다”라고 밝힌 것이다. 다만 일반적으로 AGI는 인간\n수준의 인지 능력을 갖춘 AI로 정의된다. AGI 지지자들에 따르면, 이 기술은 인간처럼 이해하고, 학습하고,']]
# 생성한 데이터셋을 딕셔너리로 변환 후 데이터프레임으로 생성
data = {
"question": questions # 질문
, "reference": ground_truths # 사람이 만든 정답
, "answer": answers # RAG 응답
, "retrieved_contexts": contexts # RAG 응답의 근거
}
# dataset으로 만들기
from datasets import Dataset
dataset = Dataset.from_dict(data)
dataset.to_pandas()


from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_recall, context_precision
result = evaluate(
dataset=dataset
, metrics=[
context_precision
, context_recall
, faithfulness
, answer_relevancy
]
)
result.to_pandas()

- Context Precision
- contexts 내의 ground-truth 관련 항목들이 상위 순위에 있는지를 평가하는 지표
- 이상적으로는 모든 관련 chunks가 상위 순위에 나타나야 함
- question, ground_truth, 그리고 contexts를 사용하여 계산
- Context Precision@K의 계산식
- K는 contexts의 총 chunk 수, 은 순위 k에서의 관련성 지표
- Precision@k는 다음과 같이 계산함
- 0에서 1 사이의 값 (높은 점수일수록 더 나은 정밀도를 나타냄)
- 정보 검색 시스템에서 검색된 컨텍스트의 품질을 평가하는 데 사용 → 관련 정보가 얼마나 정확하게 상위 순위에 배치되었는지를 측정함으로써 시스템의 성능을 판단
- Context Recall
- 검색된 context가 LLM 이 생성한 답변과 얼마나 일치하는지를 측정
- question, ground truth 및 검색된 context를 사용하여 계산
- 값은 0에서 1 사이 (높을수록 더 나은 성능을 나타냄)
- Ground truth 답변에서 context recall을 추정하기 위해, ground truth 답변의 각 주장이 검색된 context에 귀속될 수 있는지 분석
- 이상적인 시나리오에서는 ground truth 답변의 모든 주장이 검색된 context에 귀속될 수 있어야 함
- Faithfulness
- 생성된 답변의 사실적 일관성을 주어진 컨텍스트와 비교하여 측정하는 지표
- 주요 특징
- 목적: 생성된 답변의 관련성을 평가
- 점수 해석: 낮은 점수는 불완전하거나 중복 정보를 포함한 답변을, 높은 점수는 더 나은 관련성을 나타냄
- 계산에 사용되는 요소: question, context, answer
- 점수 계산 방법
- 생성된 답변에서 주장(claims)들을 식별
- 각 주장을 주어진 컨텍스트와 대조 검증하여 컨텍스트에서 추론 가능한지 확인
- 아래 수식을 사용하여 점수를 계산
- 예시
- 질문: "아인슈타인은 어디서, 언제 태어났나요?"
- 컨텍스트: "알버트 아인슈타인(1879년 3월 14일 출생)은 독일 출신의 이론 물리학자로, 역사상 가장 위대하고 영향력 있는 과학자 중 한 명으로 여겨집니다."
- 높은 충실도 답변: "아인슈타인은 1879년 3월 14일 독일에서 태어났습니다."
- 낮은 충실도 답변: "아인슈타인은 1879년 3월 20일 독일에서 태어났습니다."
- 생성된 답변이 주어진 컨텍스트에 얼마나 충실한지를 평가하는 데 유용하며, 특히 질문-답변 시스템의 정확성과 신뢰성을 측정하는 데 중요
- Answer Relevancy
- 생성된 답변이 주어진 prompt에 얼마나 적절한지를 평가하는 지표
- 주요 특징
- 목적: 생성된 답변의 관련성을 평가
- 점수 해석: 낮은 점수는 불완전하거나 중복 정보를 포함한 답변을, 높은 점수는 더 나은 관련성을 나타냄
- 계산에 사용되는 요소: question, context, answer
- 점수 계산 방법
- 원래 question과 answer를 기반으로 생성된 인공적인 질문들 간의 평균 코사인 유사도로 정의
- 아래와 같이 계산할 수도 있음
- 는 생성된 질문 의 임베딩
- 는 원래 질문의 임베딩
- 은 생성된 질문의 수 (기본값 3)
- 주의 사항
- 실제로는 점수가 대부분 0과 1 사이에 있지만, 코사인 유사도의 특성상 수학적으로 -1에서 1 사이의 값을 가질 수 있음
- 질문-답변 시스템의 성능을 평가하는 데 유용
- 특히 생성된 답변이 원래 질문의 의도를 얼마나 잘 반영하는지를 측정
| 지표 (EN) | 무엇을 재는가 | 필요 컬럼(최소) | 비고 |
|---|---|---|---|
| Faithfulness (정확성/신뢰성) | 응답이 retrieved context에 사실적으로 근거했는가 | user_input, response, retrieved_contexts | LLM판정 기반. 응답의 주장들을 컨텍스트로 검증. |
| Response Relevancy (aka Answer Relevancy) (응답 관련성) | 질문과의 관련도 | user_input, response | 질문과 덜 관련/장황하면 감점. |
| Context Precision (문맥 정밀도) | 가져온 컨텍스트 중 관련 조각의 비율 | (가변) WithoutReference(LLM): user_input, response, retrieved_contexts / WithReference(LLM): reference, retrieved_contexts (+옵션 user_input) / WithReference(Non-LLM): reference_contexts, retrieved_contexts | 구현에 따라 LLM·Non-LLM 버전 존재. 공통적으로 retrieved_contexts 필수. |
| Context Recall (문맥 재현율) | 놓치지 않았는가(필요 정보가 컨텍스트에 얼마나 포함) | LLM 버전: user_input, reference, retrieved_contexts / Non-LLM 버전: reference_contexts, retrieved_contexts | Recall은 기준이 필요 → 참조(reference 또는 reference_contexts)가 필수. |
| Context Entities Recall (문맥 엔터티 재현율) | 참조에 있는 엔터티가 컨텍스트에서 얼마나 회수되었는가 | reference, retrieved_contexts | 엔터티 기반 재현율. |
| Noise Sensitivity (노이즈 민감도) | 불필요/오류 문맥이 있을 때 오답을 내는 빈도 | user_input, response, reference, retrieved_contexts | 낮을수록 좋음. 노이즈 주입 평가. |
| Multimodal Faithfulness (멀티모달 신뢰성) | 응답이 텍스트+비주얼 컨텍스트에 사실적으로 일치하는가 | response + 텍스트/비주얼 컨텍스트(프로젝트 스키마에 맞게) | 멀티모달 RAG용. |
| Multimodal Relevance (멀티모달 관련성) | 질문–응답–멀티모달 컨텍스트의 관련도 | user_input, response + 텍스트/비주얼 컨텍스트 | 멀티모달 관련성 판정. |
# 평가용 질문
q1 = "인공일반지능은 무엇인가요?"
q2 = "기존 약한 AI와의 차이점은 무엇인가요?"
q3 = "AGI가 자율 연구원이 되어 할 수 있는 일들은 무엇일까요?"
questions = [q1, q2, q3]
# 평가용 질문에 대한 대답: ground_text(인간이 쓴 정답)
a1 = "인간처럼 이해하고 학습하고 지식을 다양한 과업에 적용할 수 있는 인간 수준의 인지 능력을 갖춘 AI이다."
a2 = "AGI는 스스로 행동을 시작하고 여러 작업을 수행하며 추론과 문제 해결이 가능하다."
a3 = "현재 과학계의 이해에 존재하는 공백과 연구 기회가 있는 영역을 식별하고 실험 설계를 포함해 실험을 자율적으로 수행한다."
ground_text = [a1, a2, a3]
# 비교를 위한 LLM의 답변 저장해 줄 빈 리스트 생성 (생성 품질)
answers = []
# LLM 응답을 위해 사용된 RAG 에시 문장 (검색 품질)
contexts = []
# 평가 데이터셋 생성
for query in questions:
# LLM으로 질문에 대한 답변 데이터 생성 후 저장
answers.append(chain_2.invoke(query)) # 여기서는 딕셔너리로 안 넣어도 됨
# 검색기 결과를 저장
# get_relevant_documents(query): 질문(quert)과 가장 관련성이 높은 document를 검색기를 통해 가져옴 → 검색기의 출력 기준이 되는 데이터
contexts.append([docs.page_content for docs in retriever_2.get_relevant_documents(query)])
# 생성한 데이터셋을 딕셔너리로 변환 후 데이터프레임으로 생성
data = {
"question": questions # 질문
, "reference": ground_text # 사람이 만든 정답
, "answer": answers # RAG 응답
, "retrieved_contexts": contexts # RAG 응답의 근거
}
# dataset으로 만들기
from datasets import Dataset
dataset = Dataset.from_dict(data)
dataset.to_pandas()

result = evaluate(
dataset=dataset
, metrics=[
context_precision
, context_recall
, faithfulness
, answer_relevancy
]
)
result.to_pandas()

q3 = "AGI 구현을 위한 핵심 기술은 무엇인가요?"
a3 = "단순한 관찰, 패턴 인식, 예측을 넘어 인과 추론과 의사결정을 가능하게 하는 인과적 세계 모델과 양자 컴퓨팅과 아날로그 컴퓨팅을 결합한 새로운 형태의 컴퓨팅 기술이 필요하다."
RAGAS 스코어는 Retrieval-Augmented Generation (RAG) 시스템의 성능을 평가하기 위해 고안된 평가 프레임워크입니다. 주요 평가 지표로는 답변의 연관성(Answer Relevancy), 문맥 재현율(Context Recall), 문맥 정밀도(Context Precision), 그리고 사실성(Faithfulness) 등이 있습니다.
- Answer Relevancy (답변 연관성): 생성된 답변이 원래 질문과 얼마나 관련성이 높은지를 평가하는 지표입니다. LLM이 생성한 답변을 바탕으로 역으로 질문을 여러 번 생성하고, 이 인공 질문들과 원래 질문의 임베딩 코사인 유사도를 평균 내어 계산합니다. 점수가 낮으면 답변이 불완전하거나 불필요한 정보가 포함된 것이고, 높으면 질문에 적절히 답한 것입니다. 이 점수는 보통 0에서 1 사이지만 코사인 유사도 특성상 -1에서 1 사이일 수도 있어 0 또는 1이 아닐 수도 있습니다.
- Context Recall (문맥 재현율): 시스템이 얼마나 많은 관련 정보를 성공적으로 검색해냈는지를 나타내며, 중요한 정보를 놓치지 않는 정도를 평가합니다. 예를 들어 참조 답변(ground truth)을 여러 개의 개별 주장(claim)으로 나눈 뒤, 검색된 문맥(retrieved contexts)이 그 각각을 얼마나 커버하는지 확인하는 방식입니다. 최대 1까지의 값으로 평가되며 0이면 전혀 관련 정보를 못 찾은 것입니다.
두 지표 모두 평가 시 원래 질문(user_input), 참조 답변(reference), 그리고 검색된 문맥(retrieved_contexts)을 활용합니다. 따라서, 만약 answer_relevancy가 0.0, context_recall이 0.0으로 나왔다면 다음과 같은 이유가 있을 수 있습니다.
- Answer Relevancy 0.0의 이유
- 생성된 답변이 질문과 의미상 맞지 않거나 관련성이 거의 없을 때 나타납니다.
- 답변이 너무 짧거나 불완전해서 역으로 질문 생성이 제대로 이뤄지지 않은 경우.
- 질문/답변 데이터 포맷 오류 또는 LLM 임베딩 생성 문제 가능성.
- Context Recall 0.0의 이유
- 참조 답변 내 주장을 커버하는 검색된 문맥이 전혀 없을 때 발생합니다.
- 참조 답변과 검색 문맥간의 내용 불일치 혹은 문맥 설정 오류 가능성.
- retrieved_contexts가 비어 있거나 적절히 입력되지 않은 경우.
- 따라서 사용된
user_input,retrieved_contexts,reference간 내용이 얼마나 의미적으로 맞물려 있는지가 중요합니다. 만약 검색된 문맥에 답변의 주요 내용을 뒷받침하는 정보가 없거나, 생성된 답변이 질문에 부합하지 않으면 이런 0 점수가 산출됩니다. 메트릭은 LLM을 이용하지만 로직상 여전히 입력된 데이터 간 적절한 의미적 연결이 있어야 점수가 높게 나옵니다.- 요약하면,
- answer_relevancy 0.0 → 답변이 질문과 관련성이 전혀 없거나 적절한 질문 역생성이 실패했기 때문
- context_recall 0.0 → 검색된 문맥이 참조 답변의 핵심 주장을 전혀 포함하지 않아서
- 이 두 점수가 모두 0인 경우는 입력 데이터(질문, 답변, 참조, 문맥) 간 의미 불일치 또는 포맷 오류 가능성이 크니 데이터 검증이 필요합니다. 또한 RAGAS 평가 도구가 요구하는 정확한 입력 형식을 따르고 있는지 점검하는 것이 좋습니다.
한국어 WordNet 데이터 처리 방식# 한국어 WordNet 데이터 처리 방식
rdflib 같은 RDF 처리 라이브러리를 사용합니다.xml.etree.ElementTree, json 모듈 등으로 파싱합니다.예 (RDF/XML 파싱 간단 예시):
from rdflib import Graph, URIRef
# 한국어 WordNet RDF 데이터 로드
g = Graph()
g.parse("korean_wordnet.rdf")
# 특정 단어의 동의어(유의어) 조회 예시
word_uri = URIRef("http://ko-wn.nate.com/word/0012345") # 예시 URI
query = """
PREFIX wn: <http://ko-wn.nate.com/wordnet#>
SELECT ?synonym WHERE {
?synset wn:contains ?word .
?synset wn:contains ?synonym .
FILTER(?word = <http://ko-wn.nate.com/word/0012345>)
}
"""
results = g.query(query)
for row in results:
print(str(row.synonym))
예:
from kiwipiepy import Kiwi
kiwi = Kiwi()
text = "나는 학교에 갑니다"
tokens = kiwi.tokenize(text)
print(tokens) # 형태소와 품사 출력
예:
def get_synonyms(word_uri, graph):
# word_uri에 해당하는 동의어 집합 반환 (URI 혹은 문자열)
synonyms = set()
query = f"""
PREFIX wn: <http://ko-wn.nate.com/wordnet#>
SELECT ?synonym WHERE {{
?synset wn:contains ?word .
?synset wn:contains ?synonym .
FILTER(?word = <{word_uri}>)
}}
"""
results = graph.query(query)
for row in results:
synonyms.add(str(row.synonym))
return synonyms
rdflib로 파싱.이 흐름을 바탕으로 코드를 작성하면 한국어 문장 간 METEOR 평가 시 동의어, 어간, 형태 변화까지 반영 가능합니다.