전체 글
-
Function Calling 구현해보기개발노트 2026. 7. 6. 22:26
Function Calling을 사용해서 LLM이 함수를 호출하게 해보자 Function Calling은 말그대로 LLM이 함수를 호출하는 기술이며파라미터를 주거나 함수를 직접 명시하는게 아니라 사용자의 질문 문맥을 파악해서 알아서 호출하는 것이 핵심이다. 1. 전제 조건Function Calling은 LLM이 고도의 문맥 판단을 해야 하므로, 너무 작은 소형 모델(예: 1B~3B 모델)은 간혹 오작동한다.Ollama llama3나 gemma2 정도의 모델로 진행하자. 2. Function Calling 구현호출될 Java 메서드 정의LLM이 요청할 때 주고받을 함수를 생성한다. 2.1 Tools 빈 등록Spring AI 가 관리할 수 있도록 빈으로 등록한다.package com.example.demo..
-
RAG(검색 증강 생성) 파이프라인 구현개발노트 2026. 6. 29. 23:02
이제 Ollama가 좀 더 똑똑해지도록 RAG 파이프라인을 구현해보자 1. RAG(검색 증강 생성)란 무엇인가?Retrieval(검색) Augmented(증강) Generation(생성)의 약자로 증강된 프롬프트를 LLM에 입력해서 답변에 도움을 주는 기술이라고 볼 수 있다.기본적으로 LLM 모델은 환각 현상, 학습하지 못한 데이터 시점의 한계, 비공개 데이터의 부재와 같은 한계를 가지고있다.RAG는 이러한 한계를 극복하기 위해 등장했으며 LLM에만 의존하지 않고 DB에서 관련 자료를 먼저 검색해서 답변을 생성하는데 참고하도록 한다. 2. RAG 파이프라인의 전체 아키텍처RAG는 크게 데이터를 준비하는 과정(수집 및 인덱싱)과 사용자의 질문에 답하는(검색 및 생성) 두 가지 흐름으로 나뉜다.이 전체 흐름..
-
AI 응답 속도 최적화 (Streaming API)개발노트 2026. 6. 24. 00:14
로컬에 구성한 Ollama + Spring AI 로 요청하고 응답도 받았지만 속도가 너무 느린 문제가 있다.전체 응답 시간을 줄이는 것보다 첫 번째 글자를 보기까지의 시간(TTFT, Time-To-First-Token)을 최소화해보자. 1. 스트리밍 아키텍처 이해하기전체적인 흐름은 아래와 같음[Ollama (로컬)] ──(Flux/SSE)──> [Spring Boot] ──(text/event-stream)──> [브라우저] 백엔드와 클라이언트는 SSE(Server Sent Events) 프로토콜을 사용해 HTTP 연결을 유지한채 서버가 클라언트로 데이터를 밀어 넣는다.백엔드 내부 Spring AI에서는 리액티브 스트림 표준인 Flux 를 사용해서 데이터를 파이프라인으로 처리한다.2. 백엔드(Spring..
-
Spring AI & Ollama 로컬 연동개발노트 2026. 6. 21. 23:35
LLM과 AI Agent를 사용만 해봤지 어떻게 동작하는지는 잘 모르고 있는것 같아직접 Spring AI와 Ollama를 연동하고 기능 구현을 해보면서 흐름을 파악 해보려고한다.우선은 연동부터 시작해보자1. 맥북에 Ollama 설치 및 실행Ollama 공식 홈페이지에서 macOS용 앱을 다운로드해 설치한다.터미널을 열고 명령어 입력 $curl -fsSL https://ollama.com/install.sh | sh 모델 설치 $ollama run llama3.22. Spring AI 프로젝트 설정 Spring Boot 3.2.x 이상 환경에서 아래 의존성을 추가 org.springframework.ai spring-ai-ollama-spring-boot-starter 3. applicati..
-
Java Stream API 에서 peek 메서드 사용개발노트 2026. 1. 21. 23:45
인텔리제이에서 Stream 사용 중 peek를 사용하라고 추천해줬다. 예를 들면 아래와 같이 map을 사용하면 peek을 추천해주는데 인텔리제이에서 추천해주니 Replace하고 그냥 사용할 수 있지만 주석에 써있기로는 디버깅용으로 사용하라고 한다.왜 추천한걸까? 디버깅이 필요해 보였나? peek로 변경하면 아래와 같은 코드로 변경되는데 결과 값은 map을 사용했을 때와 같다..peek(u -> u.setName("New Name")) 결과 값이 같은데 왜 peek를 디버깅용에만 사용하라고 하는걸까? 주석 내용을 읽어보면 최종 연산 즉 Collect()나 toList() 가 이루어지지 않으면 peek는 실행되지 않으며자바가 자체적으로 Stream 최적화를 진행할 때 불필요하다고 판단하면 peek 로직이 무..
-
자바 가비지 컬렉터(GC) 동작 원리개발노트 2024. 8. 29. 22:08
1. 가비지 컬렉션(GC)의 개념자바의 GC는 힙(Heap) 메모리에서 더 이상 참조되지 않는 객체를 찾아 자동으로 삭제하는 프로세스개발자가 직접 메모리를 해제할 필요가 없어 메모리 누수 방지에 결정적인 역할을 한다.2. 메모리 구조와 영역 분리 (Young vs Old)GC는 대부분의 객체는 금방 사라진다는 가설을 바탕으로 효율성을 위해 힙 영역을 나누어 관리한다.Young Generation: 객체가 처음 생성되는 곳. 청소가 빈번하며 속도가 빠름 (Minor GC)Eden / Survivor 0 / Survivor 1로 세분화됨Old Generation: Young 영역에서 오래 살아남은 객체들이 이동함. 덩치가 커서 청소 시간이 더 걸림 (Major GC)3. GC의 핵심 동작: Mark and ..
-
GitHub Action으로 CI/CD개발노트 2024. 7. 11. 22:52
WorkFlow 생성 GitHub 프로젝트 생성 후 Actions 탭으로 이동해 "New workflow" 버튼을 눌러 WorkFlow를 생성합니다. 배포하고자 하는 프로젝트언어와 같거나 비슷한 workflow를 찾습니다.없으면 "set up a workflow yourselg"를 클릭해 직접 만들면 됩니다. 배포 파일 생성파일은 .github/worflows 아래 만들어지게 됩니다.직접 작성한 YML 파일의 예는 아래와 같습니다.name: Deploy to Raspberry Pion: workflow_dispatch: push: branches: - masterjobs: build: runs-on: ubuntu-latest steps: - uses: actions/c..
-
람다 캡처링 (Lambda Capturing) 정리개발노트 2024. 5. 20. 23:05
람다 캡처링은 자바 람다 표현식이 자신이 정의된 범의 외부에 있는 변수를 사용할 수 있는 기능을 의미한다.캡처링 : 람다 표현식이 외부 변수를 사용하기 위해 이를 캡처하는 기능final : 람다 표현식에서 사용되는 로컬 변수와 매개변수는 변경되지 않도록 제한해야 함일관성, 안정성, 스레드 안전성, 컴파일러 최적화사용 예 : 콜백 함수, 비동기 처리 왜 final 또는 사실상 final이어야 하는가?로컬 변수와 메서드 매개변수는 final 또는 사실상 final이어야 람다 표현식 내부에서 사용할 수 있으며 이유는 아래와 같다.일관성 및 안정성: 람다 표현식은 비동기 코드나 콜백으로 사용되는데 이 때 람다 표현식 내부에서 사용하는 외부 변수가 변경될 수 있다면, 값이 예상치 못하게 변경될 위험이 있기 때문에..