반응형
반응형

RAG (검색 증강 생성) 설명

**RAG (Retrieval-Augmented Generation)**는 **"검색 증강 생성"**의 줄임말이에요. 대규모 언어 모델(LLM)의 한계를 보완하고 성능을 높이기 위한 강력한 기술이죠.


왜 RAG가 필요할까요?

ChatGPT 같은 LLM은 엄청난 양의 데이터로 학습되어 유창한 글을 잘 만들어요. 하지만 몇 가지 아쉬운 점이 있습니다.

  • 환각(Hallucination): LLM이 학습하지 않은 정보나 잘못된 내용을 마치 사실인 양 지어낼 수 있어요.
  • 정보의 최신성 부족: LLM은 특정 시점까지의 데이터로 학습되므로, 그 이후의 최신 정보는 알지 못합니다.
  • 특정 도메인 지식 부족: 일반적인 지식은 풍부하지만, 특정 기업의 내부 문서나 전문 분야 논문 같은 깊이 있는 지식은 부족할 수 있어요.
  • 투명성 부족: 왜 그런 답변을 생성했는지 그 근거를 제시하기 어렵습니다.

이런 문제들을 해결하기 위해 RAG가 등장했습니다.


RAG는 어떻게 작동할까요?

RAG는 질문에 답변을 만들기 전에, 외부에서 관련성 높은 정보를 검색(Retrieval)해서 가져온 뒤, 이 정보를 바탕으로 답변을 생성(Generation)하는 방식이에요. 쉽게 말해, LLM에게 "답변하기 전에 관련 자료를 찾아보고 대답해줘"라고 시키는 것과 같죠.

RAG의 핵심 과정은 다음과 같습니다.

  1. 질문 입력: 사용자가 질문을 입력합니다.
  2. 관련 문서 검색:
    • 질문을 분석하고 핵심 키워드나 의도를 파악해요.
    • 미리 구축해 둔 외부 지식 베이스 (데이터베이스, 문서 저장소, 웹 등)에서 질문과 가장 관련 깊은 **문서 조각(Chunk)**들을 찾아냅니다. 이때 벡터 데이터베이스 같은 기술이 사용되어 질문과 문서의 의미적 유사성을 기반으로 효율적인 검색이 이루어져요.
  3. 정보 증강 및 프롬프트 구성:
    • 검색된 관련 문서 조각들을 LLM에게 전달할 **프롬프트(Prompt)**에 추가합니다.
    • 보통 "다음 문서들을 참고하여 질문에 답변해 줘: [검색된 문서들 내용] 질문: [원래 질문]"과 같은 형식으로 프롬프트를 만들어요.
  4. 답변 생성:
    • 증강된 프롬프트(질문 + 관련 문서)를 LLM에 전달합니다.
    • LLM은 이제 자신의 학습 데이터만으로 답변하는 게 아니라, 제공된 최신 또는 특정 도메인의 정보를 참고하여 더 정확하고 근거 있는 답변을 생성해요.
  5. 답변 출력: LLM이 만든 답변을 사용자에게 보여줍니다.

RAG의 장점

  • 정확성 향상: 최신 정보나 특정 도메인 지식을 참조하여 잘못된 정보를 줄이고 답변의 정확도를 높여요.
  • 최신 정보 반영: LLM을 다시 학습(fine-tuning)할 필요 없이, 외부 데이터만 업데이트하면 실시간으로 최신 정보를 반영할 수 있어 비용 효율적입니다.
  • 투명성 및 신뢰성: 답변의 근거가 된 원본 문서를 함께 제시함으로써 답변에 대한 신뢰도를 높일 수 있어요.
  • 비용 효율성: LLM 자체를 재학습시키는 것보다 훨씬 적은 비용과 시간으로 모델의 지식을 확장할 수 있습니다.
  • 유연성: 다양한 외부 지식 베이스(데이터베이스, 문서, 웹 등)와 연결하여 사용할 수 있어요.

RAG의 활용 사례

  • 기업 내부 지식 챗봇: 회사의 내부 문서나 규정을 기반으로 직원들의 질문에 정확히 답변합니다.
  • 고객 서비스 챗봇: 기업의 최신 제품 정보나 FAQ를 기반으로 고객 문의에 응대해요.
  • 법률 및 의료 정보 시스템: 최신 법률이나 의학 논문 등을 참고하여 전문적인 질문에 답변합니다.
  • 개인화된 학습 도구: 특정 학습 자료를 기반으로 학생들의 질문에 맞춤형 답변을 제공해요.
  • 실시간 데이터 분석: 실시간으로 업데이트되는 데이터를 참조하여 질문에 대한 답변을 생성합니다.

RAG는 LLM의 한계를 극복하고 실제 환경에서 더욱 유용하게 쓰일 수 있도록 돕는 핵심 기술로 자리매김하고 있어요. 질문의 맥락과 외부 데이터를 함께 고려하여 더 스마트하고 신뢰할 수 있는 답변을 제공하는 것이 RAG의 궁극적인 목표라고 할 수 있습니다.

반응형
반응형

https://www.data.go.kr/data/15044350/fileData.do

 

한국산업은행_금융 관련 용어_20151231

리스크 개요 및 유형별 측정 방법과 관련된 용어 정의, 퇴직연금 관련 용어 정의

www.data.go.kr

반응형
반응형

[python] 유튜브 자막 가져오기 

 

 

""" 유튜브 자막 가져오기 
    pip install youtube-transcript-api
    
    -- 최신 버전으로 업데이트
    pip install --upgrade youtube-transcript-api

    https://www.youtube.com/watch?v=XyljmT8dGA4
    
    자막있는 동영상 : https://www.youtube.com/watch?v=zRz9q8dPjC4
"""


from youtube_transcript_api import YouTubeTranscriptApi
# youtube_transcript_api._errors 에서 TooManyRequests를 제외하고 임포트합니다.
# TooManyRequests는 더 이상 직접 임포트할 수 없는 것으로 보입니다.
from youtube_transcript_api._errors import NoTranscriptFound, TranscriptsDisabled, VideoUnavailable

def get_youtube_transcript(video_id, languages=['ko', 'en']):
    """
    주어진 YouTube 동영상 ID와 언어 목록에 대해 자막을 가져옵니다.
    자동 생성 자막과 공식 자막을 모두 시도합니다.
    """
    try:
        # 우선 공식 자막을 시도
        transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)

        # 사용 가능한 언어 목록에서 요청한 언어 중 하나를 찾아 가져옵니다.
        chosen_transcript = None
        for lang_code in languages:
            for transcript in transcript_list:
                if transcript.language_code == lang_code:
                    chosen_transcript = transcript
                    break
            if chosen_transcript:
                break

        if chosen_transcript:
            print(f"[{video_id}] {chosen_transcript.language} ({chosen_transcript.language_code}) 자막을 가져옵니다.")
            # fetch()는 이제 FetchedTranscript 객체를 반환하며, 이는 이터러블합니다.
            transcript_segments = chosen_transcript.fetch()
            return transcript_segments
        else:
            raise NoTranscriptFound(
                f"No suitable official transcript found for video {video_id} in languages {languages}.",
                video_id
            )

    except NoTranscriptFound:
        print(f"[{video_id}] 공식 자막을 찾을 수 없습니다. 자동 생성 자막을 시도합니다.")
        try:
            for lang_code in languages:
                try:
                    # get_transcript() 역시 이터러블한 객체를 반환하는 것으로 가정합니다.
                    transcript_segments = YouTubeTranscriptApi.get_transcript(video_id, languages=[lang_code], preserve_formatting=True)
                    print(f"[{video_id}] {lang_code} 자동 생성 자막을 가져왔습니다.")
                    return transcript_segments
                except NoTranscriptFound:
                    continue # 다음 언어로 시도
            print(f"[{video_id}] 요청된 언어 ({languages})로 자동 생성 자막도 찾을 수 없습니다.")
            return None # 적합한 자막을 찾지 못함
        except TranscriptsDisabled:
            print(f"[{video_id}] 이 동영상은 자막이 비활성화되어 있습니다.")
            return None
        except VideoUnavailable:
            print(f"[{video_id}] 동영상을 사용할 수 없거나 비공개/삭제되었습니다.")
            return None
        except Exception as e: # TooManyRequests를 포함한 모든 예외를 잡습니다.
            # 이 부분에서 TooManyRequests 에러를 포함하여 일반적인 오류를 처리합니다.
            print(f"[{video_id}] 자막을 가져오는 중 예기치 않은 오류가 발생했습니다: {e}")
            return None

    except TranscriptsDisabled:
        print(f"[{video_id}] 이 동영상은 자막이 비활성화되어 있습니다.")
        return None
    except VideoUnavailable:
        print(f"[{video_id}] 동영상을 사용할 수 없거나 비공개/삭제되었습니다.")
        return None
    except Exception as e: # TooManyRequests를 포함한 모든 예외를 잡습니다.
        # 이 부분에서 TooManyRequests 에러를 포함하여 일반적인 오류를 처리합니다.
        print(f"[{video_id}] 자막을 가져오는 중 예기치 않은 오류가 발생했습니다: {e}")
        return None


if __name__ == "__main__":
    # 예시 동영상 ID (실제 존재하는 동영상 ID로 변경해야 합니다)
    # 제가 추천해 드렸던 URL에서 ID를 추출했습니다.
    video_id_with_subtitle = "XyljmT8dGA4" # "모바일 유튜브 자동번역 한글자막 보는 방법"
    video_id_auto_caption = "XyljmT8dGA4" # 짧은 영상 (자동 생성 자막 가능성)
    #video_id_invalid = "invalid_video_id_123"
    video_id_invalid = "XyljmT8dGA4"

    print("--- 예제 1: 자막이 있는 동영상 ---")
    transcript_data = get_youtube_transcript(video_id_with_subtitle, languages=['ko', 'en'])
    if transcript_data:
        # segment.start, segment.duration, segment.text와 같이 속성으로 접근합니다.
        for i, segment in enumerate(transcript_data[:5]): # 슬라이싱은 여전히 가능해야 합니다.
            print(f"[{segment.start:.2f}-{segment.start + segment.duration:.2f}] {segment.text}")
        print(f"... (총 {len(list(transcript_data))}개 세그먼트)") # len()을 위해 list로 변환

        # 전체 자막 텍스트만 추출하고 싶다면:
        full_text = " ".join([segment.text for segment in transcript_data])
        print("\n--- 전체 자막 텍스트 (예제 1) ---")
        print(full_text[:500] + "...")
    else:
        print("자막을 가져오지 못했습니다.")

    print("\n--- 예제 2: 자동 생성 자막을 시도할 수 있는 동영상 ---")
    transcript_data_auto = get_youtube_transcript(video_id_auto_caption, languages=['en', 'ko'])
    if transcript_data_auto:
        for i, segment in enumerate(transcript_data_auto[:5]):
            print(f"[{segment.start:.2f}-{segment.start + segment.duration:.2f}] {segment.text}")
        print(f"... (총 {len(list(transcript_data_auto))}개 세그먼트)")
    else:
        print("자막을 가져오지 못했습니다.")

    print("\n--- 예제 3: 존재하지 않는 동영상 ID ---")
    transcript_data_invalid = get_youtube_transcript(video_id_invalid)
    if transcript_data_invalid:
        print("자막을 가져왔습니다.")
    else:
        print("자막을 가져오지 못했습니다.")
반응형
반응형

당신의 '화목한' 팀이 실패하는 이유

Why Your ‘Harmonious’ Team Is Actually Failing

 

https://terriblesoftware.org/2025/03/12/why-your-harmonious-team-is-actually-failing/

 

🔹 심리적 안전감의 오해와 진짜 의미

  • 오해: 갈등이 없는 조용하고 화목한 분위기가 심리적 안전감이라 착각함.
  • 진짜 의미: 아이디어, 질문, 우려, 실수를 처벌 없이 표현할 수 있는 믿음이 있는 상태.
    (하버드대 Amy Edmondson 교수의 정의)

🔹 심리적 안전이 높은 팀의 특징

  • 발언이 자유롭고, 격렬한 논쟁도 환영됨.
  • 아이디어에 대한 도전이 신분과 상관없이 가능.
  • 실수를 학습의 기회로 삼음.
  • 문제에 대해 빠르게 인식하고 공유.
  • 사람보다 문제아이디어 내용에 집중.

🔹 생산적인 토론이 이루어지는 팀 문화

  • 문제를 조기에 드러냄 (예: 엔지니어가 사소한 문제도 먼저 언급)
  • 설계나 기술적 이견에 대해 격렬하게 토론하더라도 관계에 문제 없음.
  • Postmortem 회고 시 실수한 당사자가 주도적으로 나섬.

🔹 갈등 없는 '착한' 팀이 놓치는 것

  • 겉으론 평화로우나 비판적 사고 부족으로 평균적인 성과에 그침.
  • 회의에서는 동의했지만 실제 실행에서는 불일치 발생.
  • 의사소통 부족 → 숨은 갈등 → 성과 저하.

🔹 심리적 안전과 갈등의 균형을 위한 리더의 역할

  1. 취약성 드러내기: 리더 스스로 모르는 걸 인정.
  2. 토론 규칙 만들기: 사람 아닌 아이디어를 비판하고, 결정과 토론은 구분.
  3. 도전 장려: 어려운 질문을 던진 사람을 공식적으로 칭찬.

🔹 결론: 건강한 충돌이 팀을 성장시킨다

  • 갈등을 자유롭게 표현하는 팀은 오히려 갈등이 적고 신뢰가 높음.
  • 조용한 팀보다 다양한 시각과 기술적 논쟁이 있는 팀이 더 강함.
  • 검증 없는 아이디어는 실패의 원인이며, 논쟁 없는 팀도 실패를 부른다.
반응형
반응형

[PYTHON] Streamlit: 데이터 과학자의 쉬운 웹 제작 도구

 

vscode에서 streamlit 디버깅 하기

 

 

// conda env list
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "streamlit debug (p_ai env)",
            "type": "python",
            "request": "launch",
            "module": "streamlit",
            "args": ["run", "${file}"],
            "justMyCode": true,
            "python": "C:\\ProgramData\\anaconda3\\envs\\p_ai\\python.exe" // <--- 이 줄을 추가합니다. 
        }
    ]
}

 

 

https://github.com/ngio/py_ai/blob/main/README.md

반응형
반응형

[python] streamlit.io - A faster way to build and share data apps

 

 

https://www.youtube.com/watch?v=d7fnzDQ5qM8

https://streamlit.io/

 

Streamlit • A faster way to build and share data apps

Streamlit is an open-source Python framework for data scientists and AI/ML engineers to deliver interactive data apps – in only a few lines of code.

streamlit.io

Summary for experts

 
  1. Set up your Python development environment.
  2. Run:

    pip install streamlit

  3. Validate the installation by running our Hello app:

    streamlit hello

  4. Jump to our Basic concepts.
반응형

+ Recent posts