| 기간 | 프로젝트 | 형태 | 담당 |
|---|---|---|---|
| 2026.08 – 09 | MQTT Protocol Validation | 개인 | 전 범위 |
| 2026.08 | ForeShield | 팀 | 데이터 Tool · AI 응답 검증 · 대화 복구 |
| 2026.06 – 07 | 마음갈피 | 4인 팀 | RAG 인덱스 · 안전 게이트 · 기관 추천 |
| 2026.05 | UprightAI | 4인 팀 | Azure 백엔드 · 데이터셋 검증 · UI |
| 2024.02 – 2025.12 | 암호화 트래픽 분류 | 개인 연구 | 전 범위 |
| 2024.03 – 06 | 적재적소 | 3인 졸업작품 | 적재 판단 · 임베디드 연동 · 앱 |
| 영역 | 수행 내용 | 저장소 |
|---|---|---|
| 요구사항 기반 테스트 설계 | 요구사항 ID와 테스트케이스 ID를 1:1로 대응시킨 추적표 작성, 12개 케이스 정의 | mqtt-protocol-validation |
| 검증 자동화 도구 개발 | YAML 시나리오를 읽어 publisher·subscriber를 구성하고 합불을 자동 판정하는 CLI 구현 | mqtt-protocol-validation |
| 통신 프로토콜 특성 검증 | QoS 0/1/2와 협상, retained message, persistent session, 중복 탐지, malformed payload, timeout 검증 | mqtt-protocol-validation |
| 장애 주입과 복구 시험 | Toxiproxy로 TCP 연결을 강제 차단한 뒤 감지·재접속·재구독·수신 복구까지 자동 판정 | mqtt-protocol-validation |
| 결함 재현과 증적 관리 | 의도적 실패 시나리오 구성, Expected/Observed 불일치 기록, JSON·JUnit XML·JSONL 리포트 생성 | mqtt-protocol-validation |
| 반복 시험과 CI 구성 | Docker Compose·pytest·GitHub Actions 연동, 20회 반복 안정성 검사, 커버리지 80% 게이트 적용 | mqtt-protocol-validation |
| Linux 네트워크 환경 구축 | Ubuntu VM에 stunnel로 TLS 1.3 구간 구성, tcpdump 수집, tshark로 TCP stream 분리 | encrypted-traffic-classification |
| 패킷 통계 기반 분류 | 크기·간격·길이 통계 9개로 트래픽 유형 분류, 오차 구간과 일반화 한계 분석 | encrypted-traffic-classification |
| 입력 검증과 계약 설계 | 상태·출처를 함께 반환하는 Tool 계약 설계, UTF-8 강제 디코딩과 중복 키 거부 검증기 구현 | foreshield-data-and-validation |
| 응답 신뢰성 검증 | 기존 Claim Grounding에 수치·시간·기관·식별자 유형별 검증과 절 단위 비교·부정 표현 검증을 보강 | foreshield-data-and-validation |
| 예외 처리와 상태 복구 | 기존 SSE·Repository 경로에 실패 시 부분 답변 보존을 추가하고, 대화 삭제 중 발생하는 비동기 경합 방어 | foreshield-data-and-validation |
| 성능 개선 | 이차 시간 검사를 선형 시간으로 변경, 순수 함수 캐시와 접두사 후보 선별 적용 | foreshield-data-and-validation |
| 팀 협업과 코드 리뷰 | Issue로 작업을 정의하고 기능 브랜치·PR·리뷰 반영·회귀 검증을 거쳐 병합 (PR 28건 병합, Issue 27건 종료) | foreshield-data-and-validation |
| 데이터셋 검증과 변환 | 키포인트 라벨 검증, YOLO에서 COCO로 변환, 파일명 중복으로 학습 데이터가 두 배로 집계되던 결함 발견 | uprightai-posture-analysis |
| 클라우드 백엔드 구성 | Azure Functions REST API 4종, Cosmos DB 사용자 단위 파티션 설계, Logic Apps 자동화, Application Insights 연동 | uprightai-posture-analysis |
Note
다음 영역은 아직 다루어 보지 못했습니다. 실차 및 HIL·SIL 환경, CAN·SOME/IP·DDS, C/C++ 임베디드 구현, 기능안전(ISO 26262) 산출물.
개인 · 2026.08 – 09 · 저장소
YAML 시나리오를 읽어 Mosquitto에 publisher와 subscriber를 구성하고, Expected와 Observed를 비교해 합불을 자동으로 판정하는 검증 도구입니다. 판정 근거는 JSON 요약, JUnit XML, JSONL 단계별 로그로 남습니다.
| 항목 | 내용 |
|---|---|
| 테스트케이스 | 기본 10개 · 장애 복구 2개 · 의도적 실패 1개 |
| 검증 결과 | pytest 20 passed · 12개 케이스 전부 통과 |
| 반복 안정성 | 복구 suite 20회 반복, 총 40 케이스 failure 0 |
| 커버리지 | statement 83.42% (게이트 80%) |
검증 범위와 설계 판단 (펼치기)
검증 범위
- QoS 0/1/2 정상 경로와 publisher·subscriber 간 QoS 협상
- retained message와 나중에 접속한 subscriber의 수신 여부
- 동일
message_id를 가진 애플리케이션 중복 메시지 탐지 - malformed JSON 거부와 구체적인 파싱 실패 사유 분류
- 메시지 미수신 timeout을 정상 결과로 판정하는 경우의 구분
- 명시적 disconnect 이후 reconnect와 재구독, 메시지 수신
clean_session=falsepersistent session과 오프라인 QoS 1 queue 복원- Toxiproxy로 기존 TCP 연결을 강제 절단한 뒤 감지·재연결·재구독·수신 복구
- 비일치 topic의 격리
- Expected/Observed 기반 자동 판정과 의도적 실패 재현
설계 판단
{run_id}치환으로 실행마다 topic을 분리해, 이전 실행의 retained message나 동시 실행이 결과를 오염시키지 않도록 했습니다.- 알 수 없는 시나리오 종류, 잘못된 QoS, 중복 케이스 ID, 빈 Expected는 실행 전에 거부합니다.
- paho 콜백 스레드와 메인 스레드 사이의 대기·전달은
threading.Event와queue.Queue로 처리해, 타임아웃이 있는 결정적 판정이 가능하게 했습니다. - 리포트를 세 형식으로 나눈 이유는 소비자가 다르기 때문입니다. JSON은 사람이 요약을 확인하고, JUnit XML은 CI가 성공·실패를 표준 형식으로 표시하며, JSONL은 연결부터 판정까지의 시간 순서를 추적합니다.
- QoS 0 테스트는 손실 없는 전달을 주장하지 않고 정상 연결에서 한 번 도달하는지를 관측합니다. QoS 2 역시 패킷 4단계 핸드셰이크를 검사하지 않고 subscriber가 한 번 관측하는지를 확인합니다.
포함하지 않은 범위
웹 대시보드, 실제 차량 ECU 및 HIL, CAN·SOME/IP·DDS, TLS와 인증·ACL, MQTT 5 reason code, broker 프로세스 강제 종료와 재기동, packet loss 및 latency 주입, MQTT DUP flag 강제 재현.
Python paho-mqtt Mosquitto Toxiproxy Docker Compose pytest GitHub Actions
개인 연구, 학부연구생 · 2024.02 – 2025.12 · 저장소
TLS 1.3으로 암호화된 트래픽을 복호화하지 않고, 패킷 크기와 도착 간격, 세션 길이 통계 9개만으로 분류했습니다. 분류 결과를 네트워크 슬라이스 정책에 대응시키는 시연 대시보드를 함께 만들었습니다.
| 실험 | 클래스 | 표본 수 | 행 단위 hold-out 정확도 |
|---|---|---|---|
| 2분류 | bulk / control | 1,200 | 97.08% |
| 3분류 | control / video / download | 2,400 | 95.21% |
| 3분류 (크기 필터) | control / video / download | 992 | 93.97% |
테스트베드 구축과 분석 내용 (펼치기)
직접 구축한 테스트베드
VMware에 Ubuntu 22.04 서버·클라이언트 VM을 올리고, stunnel로 TLS 1.3 구간을 만든 뒤 Python으로 트래픽을 생성해 tcpdump로 수집하고 Wireshark/tshark로 TCP stream을 분리했습니다.
분류 실험
성능 측정은 사이트별로 라벨링된 공개 TLS 1.3 데이터셋으로 수행했습니다. 직접 수집한 트래픽으로 낸 수치가 아닙니다. 동일한 4개 사이트의 표본 행을 8:2로 무작위 층화 분할하고 RandomForest(n_estimators=100)로 측정한 초기 결과이며, 새로운 사이트나 환경에 대한 일반화 성능은 아닙니다.
분석
- bulk를 video와 download로 나누면 정확도가 약 2%p 떨어집니다. 두 트래픽 모두 대역폭을 크게 쓰는 전송 패턴이라 통계적으로 겹치는 구간이 있고, 오차 행렬에서도 이 둘 사이의 혼동이 대부분을 차지합니다.
- 분류에 가장 크게 기여한 특징은 평균 패킷 크기와 패킷 크기 표준편차였습니다. 페이로드를 보지 못하더라도 패킷의 크기 분포만으로 두 유형이 갈린다는 의미입니다.
한계
라벨이 사이트 단위여서 모델이 배운 것이 트래픽 유형인지 특정 서버의 응답 패턴인지 분리되지 않습니다. 단일 캡처 환경에서 나온 데이터이며, 세션 종료 후 계산하는 특징이라 실시간 판정에는 그대로 쓸 수 없습니다. 슬라이스 할당은 학습된 판단이 아니라 분류 결과를 고정 규칙표에 대응시킨 것이고, 상용 O-RAN이나 RIC 연동은 없습니다.
Ubuntu TLS 1.3 stunnel tcpdump Wireshark/tshark Scapy scikit-learn Streamlit
팀 프로젝트 · 2026.08 · 공개용 재구성 저장소
기후재난 위험도와 기상 예보·특보를 지도에서 확인하고, 자연어로 질문하거나 대응 훈련을 진행하는 서비스입니다. 재난 데이터 Tool, 수집·검증 자동화, 훈련 세션을 담당했고 이후 AI 응답 근거 검증과 대화 오류 복구까지 맡았습니다.
공개 저장소에는 팀 원본 코드·내부 이력·실데이터 대신 합성 입력으로 다시 만든 독립 예제만 포함했습니다.
팀 저장소에서 PR 28건을 병합하고 Issue 27건을 종료했습니다. Issue로 작업 범위와 완료 조건을 먼저 정의하고, 기능 브랜치에서 구현한 뒤 PR 리뷰 지적을 반영해 회귀 검증을 거쳐 병합했습니다.
담당 작업 상세 (펼치기)
데이터 Tool 7종
지역 해석, 예보, 위험도, 상위 위험지역, 공식 특보, 모델 설명, 과거 사례를 조회하는 Tool을 구현했습니다. 값만 반환하지 않고 상태(status)와 출처(provenance), 오류를 함께 전달하는 계약을 설계했습니다.
- 발행물과 Agent가 쓰는 재난명·지역코드·리드 표기가 계층마다 달라, 변환을 한 모듈에 모으고 Provider가 계약에 맞게 반환하도록 했습니다.
- "0"과 "데이터 없음", "특보가 없다"와 "특보 파일을 읽을 수 없다"를 구분했습니다. 실패를 빈 결과로 바꾸면 사용자를 잘못 안심시킬 수 있기 때문입니다.
- bool이 숫자의 하위 타입이라
True가 확률 1.0처럼 통과하던 입력을 거부했습니다. - 광역 예보는 변수별 집계 계약이 없어 미지원으로 반환하고, 광역 특보는 값을 합성하지 않고 지역 포함관계로 조회할 수 있어 지원했습니다.
- Mock과 실제 데이터 Provider를 설정으로 교체할 수 있도록 기존 인터페이스에 맞춰 구현했습니다.
수집·검증 자동화
Timer Trigger로 샘플 응답을 수집해 Raw에 저장하고 수집 메타데이터를 남긴 뒤, Blob Trigger에서 파일 크기·확장자·해시·필수 컬럼·결측·중복·시각 등 검사를 거쳐 Curated 발행 여부를 결정하도록 구성했습니다.
json.loads(bytes)가 UTF-16/32도 자동 감지하기 때문에, UTF-8을 전제로 하는 다음 단계가 읽지 못하는 문제가 있었습니다.
UTF-8 디코딩을 먼저 수행하고 중복 키와 비유한 수치를 거부하도록 했습니다.
임시 파일에 기록한 뒤 원자적으로 발행해 불완전한 파일이 노출되지 않게 했습니다.
중복 키 검사가 키마다 list.count()를 호출해 이차 시간으로 증가하던 것을 집합 기반 단일 순회로 바꿨습니다.
당시 기록은 4만 키 입력 기준 26.35초에서 0.02초입니다. 검사 단계의 로컬 측정이며 전체 처리시간이 아닙니다.
훈련 세션
advance_time / set_condition / pause / resume / reset / complete / cancel 이벤트와 세션 상태를 처리했습니다.
다른 대화의 세션을 수정하지 못하도록 소유권을 검사하고, 동일 client_event_id의 재시도가 두 번 적용되지 않도록 결과를 재사용했습니다.
훈련 모드에서 외부 호출이 차단되는지도 통합 시나리오로 검증했습니다.
지역 해석과 Product Help
"ForeShield 작동원리를 알려주세요"는 처리되고 "ForeShield 작동원리 알려주세요"는 거절되던 문제를 다뤘습니다. 완성 문장을 계속 등록하는 방식에서, 주어·조사·종결형을 조합해 동등 표현을 생성하는 방식으로 바꿨습니다.
- 조사를 무조건 제거하면 "완도"처럼 이름 자체가 조사와 같은 글자로 끝나는 지역이 훼손되므로, 원본 매칭을 먼저 시도하고 실패한 경우에만 정규화를 적용했습니다.
- 상위 지역 힌트와 조상 체인으로 동명 지역 후보를 좁히고 순환 참조를 방어했습니다.
- 받침에 맞는 조사만 생성하도록 해 "작동원리이" 같은 비문을 막았습니다.
- 중복 제거를 전체 항목에 걸쳐 수행하면 순회 순서에 따라 답변 소유권이 바뀌므로, 같은 항목 안으로 범위를 한정했습니다.
- 표현 확장이 보안 경계를 우회하지 않도록 인용·번역·내부 설정 요청의 오인을 함께 검증했습니다.
순서는 리스트에 보존하고 중복 판정만 집합으로 수행했으며, 순수 변형 함수의 반환값을 튜플로 바꾸고 캐시를 적용했습니다. 성능은 패턴 생성 2.425초에서 0.189초, 후속 캐시 변경에서 0.149초에서 0.082초로 기록되어 있습니다. 두 측정은 리비전과 패턴 집합이 다르므로 하나의 개선율로 합치지 않았습니다.
AI 응답 근거 검증
답변에 등장하는 숫자가 근거 자료 어딘가에 있다는 것만으로는 부족합니다. 그 숫자가 같은 지역·시간·사건의 값인지, 비교와 부정의 의미까지 맞는지 확인해야 했습니다. 팀에서 만든 Claim Grounding 구현에 다음 검증을 보강했습니다.
- 출처 단위로 근거와 주장을 묶어 다른 항목의 숫자를 가져오는 경로 차단
- 시간·수치·기관·식별자를 유형별로 검증하고, 절 단위로 비교·부정 표현을 확인
- RAG 문서의 날짜를 해당 사건에 연결하고 지역별 특보 개수의 범위 혼동 방지
- 화면의 위험도 표시 계약과 Agent 답변이 같은 값을 설명하도록 응답 경로 조정
- 단일 위험도 요청에서 불필요한 후속 LLM 호출 제거 (운영 API에서 동일 질문을 새 대화 6개로 측정해 구간별 비교)
- 답변 생성과 문맥 해석이 공유하는 출력 토큰 예산 정책 구현. 본문이 비었고 종료 사유가 length일 때만 한 번 재시도하도록 좁혔습니다.
대화 오류 복구
- SSE delta를 누적해 실패나 비정상 종료 시 부분 답변을 저장하도록 기존 Repository 경로를 확장했습니다.
- 오류 코드·메시지·재시도 가능 여부 등 오류 계약을 프론트 표시와 연결했습니다.
- 삭제된 대화 ID를 제외 집합에 유지해, 늦게 도착한 조회가 삭제된 대화를 다시 선택하지 못하게 했습니다.
- 대화 전환 중 입력을 잠그고, 비동기 조회 완료 후 상태를 재검사했습니다.
- 내부 예외 문자열이 public SSE나 저장 이벤트에 실리지 않도록 처리했습니다.
AI 도구 활용
Claude와 Codex로 코드 작성과 리뷰, 테스트 보강을 진행했습니다. AI가 제안한 수정은 재현 조건과 계약을 확인한 뒤 반영했습니다. JSON 인코딩과 중복 키 문제는 입력을 만들어 재현했고, Product Help는 정상 질문뿐 아니라 보안 경계와 오인, 복합 요청까지 함께 회귀 검증했습니다. 전체 테스트가 통과해도 캐시가 데워진 탓에 가려지는 성능 문제가 있어 초기 실행 조건도 확인했습니다.
Python TypeScript FastAPI Pydantic SQLAlchemy PostgreSQL SSE Azure Functions Azure OpenAI pytest
4인 팀 프로젝트 · 2026.05 · 공개용 재구성 저장소
웹캠으로 앉은 자세를 추정해 거북목 여부를 판단하고, 기록을 쌓아 주간 리포트를 보내는 서비스입니다. Azure 백엔드 구성과 키포인트 데이터셋 검증, 전체 UI와 번아웃 영역을 담당했습니다.
공개 저장소에서는 팀 Azure export·실제 자원 식별자·데이터셋·다른 팀원 코드를 제외했습니다.
담당 작업 상세 (펼치기)
키포인트 데이터셋 검증과 변환
자세 판정 정확도를 높이려 MoveNet 대신 HRNet을 쓸 수 있는지 검토했습니다. HRNet은 COCO 형식 어노테이션을 요구하는데 보유 데이터는 YOLO pose 형식이어서 변환과 검증이 먼저 필요했습니다.
- YOLO pose 라벨 파서를 작성했습니다. 길이가 맞지 않으면 파일명과 줄 번호를 출력하고 실패시킵니다.
- 이미지와 라벨 파일의 1:1 대응을 검사했습니다 (train 250, val 50, 누락 0건).
- bbox 크기와 visibility 값을 검사했습니다. 당시 노트북은 경계 밖 좌표를 먼저 보정해 해당 범위 검사가 독립적으로 유효하지 않았고, 공개용 재구성에서는 좌표를 clipping하기 전에 범위를 검사해 잘못된 입력을 거부하도록 수정했습니다.
- YOLO에서 COCO JSON으로 변환하며 bbox를 1.4배 패딩해 크롭 시 키포인트가 잘리지 않게 했습니다.
- 변환 결과의 이미지 수, 어노테이션 수, 파일명 중복을 재검증했습니다.
발견한 결함
학습 이미지가 250장이어야 하는데 500장으로 집계되는 것을 발견했습니다.
원인은 파일명 중복이었고, Counter로 중복을 집계해 확인한 뒤 파일명 기준 중복 제거를 파이프라인에 넣었습니다.
키포인트는 경추·흉추·요추·천추 4개입니다.
판단
변환과 검증까지 마쳤으나 HRNet은 최종적으로 채택하지 않았습니다. 브라우저에서 바로 실행해야 하는 서비스 특성상 TF.js로 클라이언트에서 추론하는 MoveNet 쪽이 지연과 서버 비용에서 유리했습니다.
Azure 백엔드 구성
| 리소스 | 역할 |
|---|---|
| Azure Functions | REST API 4종 (회원가입, 로그인, 자세 로그 적재, 통계 조회) |
| Cosmos DB | 자세 로그와 사용자 데이터. /user_id 파티션 키 |
| Logic Apps | 주간 리포트 자동 이메일 발송 (recurrence 트리거) |
| Application Insights | 호출 수·실패·응답시간 모니터링 |
| Storage Account | Functions 실행 환경 |
조회가 대부분 사용자 단위로 끝나기 때문에 파티션 내에서 처리되도록 /user_id를 파티션 키로 잡았습니다.
크롬 확장 프로그램
팀 확장 프로그램 저장소에 UI 수정과 콘솔·DB 로깅을 PR로 기여했습니다.
한계
Azure IaC는 직접 작성한 것이 아니라 Portal에서 자동 export한 결과물입니다. Functions 핸들러 구현 코드는 개인 저장소에 없고 라우트·바인딩·트리거 설정까지만 남아 있습니다. 배포된 함수들의 authLevel이 전부 anonymous였는데, 로그 적재와 통계 조회는 함수 키나 API Management, 또는 Easy Auth를 앞에 두는 편이 맞았습니다.
Azure Functions Cosmos DB Logic Apps Application Insights Python COCO/YOLO
- Azure OpenAI 임베딩과 AI Search를 사용해 RAG 인덱스를 구성했습니다.
- Content Safety로 위기 상황을 감지하는 안전 게이트를 적용했습니다.
- 위기 감지 이후 GPS 기반으로 Cosmos DB의 상담 기관을 추천하는 경로를 연결했습니다.
- Streamlit 홈 화면에서 채팅과 대시보드로 이동하는 흐름을 구성했습니다.
- 프로필·대화·기관 데이터를 Cosmos DB에 분리해 저장하고 설명 API로 연결했습니다.
팀 저장소이며, 개인 커밋은 각 저장소의 Contributors에서 확인하실 수 있습니다.
Python FastAPI Streamlit Azure OpenAI Azure AI Search Content Safety Cosmos DB Docker
3인 졸업작품 · 2024.03 – 06
드론 영상으로 화물차의 불량 적재와 사각지대 위험을 판단해 운전자에게 알리는 시스템입니다.
- 불량 적재 판단 영역과 Raspberry Pi 연동을 담당했습니다.
- App Inventor로 시연 앱을 만들었고, MongoDB의 교육 이수 내역·고지서 조회와 Google Maps 기반 교육장 추천을 구현했습니다.
- 결과를 바탕으로 한국통신학회 논문을 작성하고 포스터 발표를 진행했습니다.
YOLOv5 Raspberry Pi App Inventor MongoDB Google Maps API
| 구분 | 내용 |
|---|---|
| 언어 | Python, TypeScript, SQL |
| 검증 | pytest, unittest, GitHub Actions, Docker Compose, Toxiproxy |
| 네트워크 | MQTT (paho, Mosquitto), TLS 1.3, HTTP/SSE, tcpdump, Wireshark/tshark, Scapy |
| 클라우드 | Azure Functions, Cosmos DB, Logic Apps, Application Insights, Azure OpenAI, Azure AI Search |
| 데이터 | pandas, scikit-learn, COCO/YOLO 어노테이션, Streamlit |
| 협업 | Git, GitHub Issue·Project·PR 리뷰 |