갑자기 챗봇 버그가..?
스토리파이
챗봇 버그
갑자기 챗봇이 이미 한 질문을 함.
원인 찾고 수정하기.
클라이언트에서 보낼 때 마침표 유무에 따라 응답이 달라지는 걸 확인함.
-> 프론트에 구두점 여부 체크해서 없으면 추가하도록 요청함.
파인 튜닝
현재는 한 문장에 대한 응답만 학습한 모델임.
여러 문장이 입력되었을 때, 마지막 문장에 대한 응답만 하도록 학습한 모델로 교체
온도 값 변경
온도 값 0.9로 어투가 랜덤하게 바뀌는 문제가 있어 0.2로 변경
위와 같이 조치하였을 때 비교적 안정적이고 일관된 어투 생성됨.
멘토링
브라우저에 google.com을 입력했을 때
지난 번 멘토링 때 잠깐 나왔던 질문인데 한번 정리해 보기
1. URL 인식 및 분석
- 브라우저는 "google.com"을 URL로 인식하고, 프로토콜, 호스트 이름, 경로, 쿼리 문자열을 식별합니다.
- 프로토콜을 추출해서 요청을 처리하는 방식을 결정합니다.
- 호스트 이름을 파싱해서 DNS를 조회할 준비를 합니다.
- 프로토콜을 입력하지 않으면 기본적으로 HTTPS(HTTP)로 요청한다.
2. DNS 조회
- 브라우저 DNS 캐시 확인: 브라우저 자체 DNS 캐시, 일반적으로 브라우저를 재시작하면 초기화됩니다.(브라우저 설정에 따라 다름)
- 운영체제 DNS 캐시 확인: 시스템 전체에 DNS 요청이 있을 때 참조되며, 다양한 애플리케이션에 걸쳐 공유
- 로컬 네트워크에 설정된 DNS 서버 조회: 캐시에 정보가 없으면 로컬 네트워크에 설정된 DNS 서버에 요청합니다. 개별 PC 또는 공유기에서 설정 가능하며, 우선순위에서는 공유기보다 개별 PC 설정 DNS가 더 높습니다.
단, 이 단계에서 공유기에 캐싱된 정보가 있다면 DNS 서버에 요청을 보내지 않고 캐싱된 정보를 반환합니다.
로컬 네트워크에서 ISP DNS, 또는 다른 DNS(ex. google 8.8.8.8)을 설정할 수 있다. 각 DNS는 캐싱된 정보를 반환하며, 캐싱된 정보가 없는 경우 요청은 TLD 서버로 전송되고, 필요에 따라 계층적으로 더 구체적인 DNS 서버로 전달되어, 최종적으로 해당 도메인을 관리하는 권한 있는(Authoritative) DNS 서버에서 처리됩니다.
- IP 주소 수신: "google.com"에 해당하는 IP 주소를 받아옵니다.
DNS 요청은 HTTP 프로토콜이 아닌 UDP 또는 TCP로 전송된다.
보안 취약하기 때문에 DNS over HTTPS(DoH), DNS over TLS(DoT)와 같은 기술이 도입되었다.
3. HTTP 요청 생성
HTTPS 연결
SSL/TLS 핸드셰이크
- 클라이언트 헬로: 클라이언트가 서버에 사용 가능한 암호화 알고리즘, 세션 ID, SSL/TLS 버전 등 정보를 서버에 전송한다.
- 서버 헬로: 서버가 메시지를 받고, 협상된 암호화 알고리즘, 세션 ID, SSL/TLS 버전 등을 클라이언트로 전송한다.
- 인증서 전송: 서버는 자신의 SSL/TLS 인증서를 클라이언트에 전송한다. 이 인증서에 서버의 공개키가 포함되어 있다.
- 키 교환: 클라이언트는 서버의 공개키를 사용하여 랜덤하게 생성된 세션키(대칭키)를 암호화해서 서버에 전송하고, 서버는 자신의 개인키로 이를 복화화해서 세션키(대칭키)를 얻는다. 세션키는 세션 시작 시에만 교환되며, 해당 세션 동안 교환되는 모든 데이터를 암호화하는 데 사용된다.
- 핸드셰이크 완료: 대칭키를 사용하여 데이터를 암호화하고 복호화한다.
왜 대칭키를 쓸까?
비대칭키는 보안성이 높지만 더 느리다. 그래서 데이터 전송을 위해서는 대칭키를 사용한다.
3~4는 데이터 교환을 위한 대칭키를 서로 공유하기 위해 단방향 암호화 방식으로 소통하고, 5부터는 이렇게 공유한 대칭키를 통해 양방향 암호화 방식으로 데이터를 송수신한다.
정확히는 TLS 프로토콜로 통신을 한다. 하지만 TLS가 SSL을 기반으로 개발되었고, SSL이라는 용어를 많이 사용해서 SSL/TLS라는 표현이 널리 사용된다.
HTTP 요청 메시지 구성
- 요청 라인: HTTP 메서드, 리소스 URI, HTTP 버전
- 헤더: 사용자 에이전트, 호스트, 허용 가능 콘텐츠 타입
- 본문: POST, PUT, PATCH는 전송 데이터 포함
HTTP는 평문으로 통신하고, HTTPS는 암호화해서 통신한다.
4. HTTP 요청 전송
TCP 연결 설정
- SYN 패킷 전송: 클라이언트는 서버로 SYN(Synchronize) 패킷을 보내 연결을 초기화합니다.
- SYN-ACK 응답: 서버는 SYN 요청을 받고, SYN-ACK(Synchronize-Acknowledge) 패킷으로 응답하여 연결 요청을 수락합니다.
- ACK 패킷 전송: 클라이언트는 ACK(Acknowledge) 패킷으로 응답하여 TCP 연결을 완료합니다. 이 시점에서 TCP 연결이 설정되며, 데이터 전송이 가능해집니다.
IP 라우팅
- 목적지 주소 결정: 클라이언트는 DNS 조회를 통해 얻은 서버의 IP 주소를 목적지로 설정합니다.
- 라우팅 프로세스: 각 네트워크 라우터는 패킷의 목적지 IP 주소를 기반으로 다음 홉(next hop)을 결정하고, 패킷을 그 방향으로 전달합니다. 이 과정은 패킷이 목적지에 도달할 때까지 반복됩니다.
패킷 재조립 및 TLS 처리
- 패킷 분할: 큰 HTTP 요청 메시지는 여러 TCP 패킷으로 분할되어 네트워크를 통해 전송됩니다.
- 서버에서의 패킷 수신 및 재조립: 서버는 도착한 패킷들을 순서대로 재조립하여 원래의 HTTP 요청 메시지를 복구합니다.
- TLS 암호화 및 MAC 생성: TLS 세션에서는 HTTP 요청 메시지가 클라이언트에서 암호화되어 전송됩니다. 암호화 과정에는 협상된 대칭키가 사용되며, 각 메시지에는 무결성 검증을 위한 MAC(Message Authentication Code)가 포함됩니다.
- MAC 생성: 메시지의 무결성을 보장하기 위해, 전송되는 데이터의 내용과 시크릿 키(대칭키의 일부 또는 별도의 키)를 사용하여 MAC를 계산합니다. 이 MAC는 메시지와 함께 전송되어, 수신자가 메시지의 무결성을 검증할 수 있게 합니다.
- 서버에서의 복호화 및 MAC 검증: 서버는 받은 메시지를 대칭키로 복호화하고, MAC를 사용하여 메시지의 무결성을 검증합니다. MAC가 일치하면, 메시지가 중간에 변경되지 않았음을 의미하며, 서버는 요청을 안전하게 처리할 수 있습니다.
5. 응답 수신
응답 수신 과정은 서버로부터 데이터를 받고, 이를 클라이언트(브라우저)에서 처리하는 단계로 구성됩니다. 이 과정은 TLS 환경에서도 동일하게 적용되며, 응답 데이터는 암호화된 상태로 전송됩니다.
응답 패킷 수신
- 암호화된 데이터 수신: 서버로부터 암호화된 응답 데이터가 TLS 프로토콜을 통해 클라이언트로 전송됩니다. 데이터는 네트워크를 통해 여러 라우터와 스위치를 경유하여 클라이언트에 도달합니다.
- 패킷 재조립: 클라이언트는 네트워크를 통해 수신된 분할된 패킷들을 순서대로 재조립하여 원래의 응답 메시지를 복구합니다.
응답 메시지 디코딩 및 복호화
- TLS 복호화: 클라이언트는 TLS 세션 동안 협상된 대칭키를 사용하여 암호화된 응답 데이터를 복호화합니다. 이 과정을 통해 원래의 HTTP 응답 메시지가 복원됩니다.
- 디코딩: 복호화된 데이터는 주로 UTF-8 등의 인코딩 방식으로 인코딩되어 있습니다. 클라이언트는 이 데이터를 디코딩하여 가독 가능한 텍스트 형태로 변환합니다.
HTTP 응답 분석
- 상태 코드 검토: HTTP 응답의 첫 번째 줄에는 상태 코드(예: 200 OK, 404 Not Found 등)가 포함되어 있습니다. 클라이언트는 이 상태 코드를 분석하여 요청의 성공 여부를 판단합니다.
- 응답 헤더 분석: 응답 메시지에는 서버에 대한 정보, 콘텐츠 유형, 캐싱 정책 등을 설명하는 여러 HTTP 헤더가 포함되어 있습니다. 클라이언트는 이 헤더들을 분석하여 응답을 적절하게 처리합니다.
- 응답 본문 처리: HTTP 응답의 본문에는 실제 요청된 리소스의 데이터가 포함되어 있습니다. 클라이언트는 이 데이터를 웹 페이지 렌더링, 파일 다운로드 등의 목적으로 사용합니다.
6. 콘텐츠 렌더링
- DOM 트리 구축: HTML을 파싱하여 DOM 트리를 구축합니다.
- CSSOM 트리 구축: CSS 규칙을 파싱하여 CSSOM 트리를 구축합니다.
- 렌더 트리 생성: DOM 트리와 CSSOM 트리를 결합하여 렌더 트리를 생성합니다. (
display: none
속성을 가진 요소들은 렌더 트리에 포함되지 않음.)
- 레이아웃 계산: 렌더 트리 완성 후, 브라우저가 각 요소의 정확한 위치와 크기를 계산하는 레이아웃 과정을 수행합니다.
- 페인팅: 레이아웃 계산이 완료되면, 실제 화면에 요소를 그리는 페인팅 과정을 수행합니다. 이때 텍스트, 색상, 이미지가 실제 픽셀로 변환되어 화면에 표시됩니다.
- 합성: 여러 레이어를 합성하여 최종적인 페이지를 화면에 표시합니다.
7. TCP 연결 종료: 4단계 과정
- FIN: 연결을 종료하고자 하는 호스트(클라이언트 또는 서버)가 FIN(Finish) 플래그가 설정된 패킷을 보냅니다.
- ACK: 다른 쪽 호스트는 FIN 패킷을 받고 ACK(Acknowledge) 패킷으로 응답하여 이를 수신했음을 확인합니다.
- FIN: 이제 연결을 종료하려는 쪽에서도 FIN 패킷을 보내 연결 종료 준비가 되었음을 알립니다.
- ACK: 처음 FIN을 보낸 호스트가 ACK 패킷을 받으면, 양쪽 모두 연결 종료에 동의한 것으로 간주하고 연결을 종료합니다.
HTTP vs TCP
HTTP
- 애플리케이션 계층 프로토콜
- 웹 서버와 클라이언트 통신을 위해 설계
- Stateless
- 각 요청은 독립접, 이전 및 이후 요청과 연관성 없음
- 세션 상태 유지 부재
TCP
- 전송 계층 프로토콜
- 인터넷 상의 데이터를 안정적으로, 순서대로, 에러없이 전송하기 위해 설계
- stateful(상태 유지)
- 연결 지향: 통신 시간 전 클라이언트-서버 연결 수립(3way handshake)
- 세션 관리: 세션을 통해 데이터 전송 상태 관리
차이점
- HTTP가 애플리케이션 계층에서 웹 문서와 리로스를 전송하기 위한 목적의 프로토콜이라면, TCP는 전송 계층에서 안정적인 데이터 전송을 보장하기 위한 프로토콜
- HTTP는 주로 웹 페이지 요청 및 전송에 사용, TCP는 이메일, 파일 등 다양한 인터넷 애플리케이션에서 데이터의 안정적인 전송을 위해 사용
웹 브라우저에서 통신을 할때 stateless인 HTTP를 보완하기 위해서 stateful인 TCP와 함께 씀.
이상한 질문 해봤음
Git
Checkout 말고 switch 명령어로 브랜치 생성하고 바로 전환하기
git switch -c test/ai-co
테스트 코드
테스트 코드를 쓰려고 봤더니 기존의 엉망인 함수가 문제
Req 객체에 직접 접근하는게 아니라, 로직을 분리하거나 별도 함수로 만들어서 mock 없이도 테스트 할 수 있게 해야 함.
그리고 컨트롤러는 HTTP에만 집중하고 id 추출 등은 서비스 로직에서 처리하는 게 더 좋음.
우선 해결
서비스 레이어 함수에 반환 타입을 지정해 주니까 해결됨.
아마, 지정을 해주지 않으면 타입 추론을 해서 그럴 수도 있음.
타입 스크립트 정석으로 공부해야 할 듯.