ProxyFactory 프록시는 어드바이저가 없으면 대상을 그대로 부른다

컨트롤러·서비스·리포지토리 세 계층에 로그 추적을 붙였다면, 요청 하나에 로그 추적기(요청 하나의 호출을 같은 ID로 묶어 계층마다 시작과 끝을 한 줄씩 찍는 도구)가 여섯 줄을 남겨야 한다. ProxyFactory(대상 객체를 받아 JDK 동적 프록시나 CGLIB 프록시를 만들어 주는 스프링 클래스)로 인터페이스와 구현…

컨트롤러·서비스·리포지토리 세 계층에 로그 추적을 붙였다면, 요청 하나에 로그 추적기(요청 하나의 호출을 같은 ID로 묶어 계층마다 시작과 끝을 한 줄씩 찍는 도구)가 여섯 줄을 남겨야 한다. ProxyFactory(대상 객체를 받아 JDK 동적 프록시나 CGLIB 프록시를 만들어 주는 스프링 클래스)로 인터페이스와 구현…

앞 글에서는 로그 추적(요청 하나의 호출을 같은 ID로 묶어 계층마다 시작과 끝을 찍는 로그)을 붙이려고 컨트롤러·서비스·리포지토리마다 프록시 클래스를 하나씩 만들었다. JDK 동적 프록시를 쓰면 부가 기능은 InvocationHandler 하나에 쓰고, 프록시 클래스는 실행 중에 JDK가 만든다. 강의의 핸들러는 리플렉션(클래스와 메서드의 정보를…

2021년 강의의 v1·v2 컨트롤러를 Spring Boot 4.1로 옮기면 서버는 정상으로 뜨는데 요청마다 404를 돌려준다. v1은 인터페이스와 구현 클래스로, v2는 인터페이스 없는 클래스로 만들었고, 둘 다 @Controller 대신 @RequestMapping만 붙어 있다. 컴포넌트 스캔을 피하고 설정 클래스에서 직접 빈으로 등록하려는 선택이다. 등록을…

앞 글의 로그 추적기는 컨트롤러·서비스·리포지토리마다 try/catch 안에서 begin()과 end()를 부르고, 요청 하나의 호출을 묶는 트랜잭션 ID(DB 트랜잭션과는 관계없다)를 ThreadLocal에 두었다가 가장 바깥 호출이 끝날 때 remove()로 비운다. 계층마다 핵심 호출 한 줄을 추적 코드 여러 줄이 둘러싸고, 그 모양이 클래스마다…

로그 추적기(요청 하나의 호출을 같은 ID로 묶어 찍는 도구)를 싱글톤 빈 하나로 만들고 요청을 묶는 트랜잭션 ID(DB 트랜잭션과는 관계없는 요청 ID)를 그 필드에 두면, 첫 요청이 끝나기 전에 들어온 두 번째 요청이 같은 ID를 이어 쓴다. 필드를 ThreadLocal로 바꾸면 값이…

안드로이드나 Flutter 앱처럼 JavaScript SDK를 쓸 수 없는 클라이언트에서 Flue 에이전트와 대화하려면 HTTP로 직접 붙어야 한다. 메시지를 POST하면 답 대신 202 접수 응답이 오고, 답은 그 응답에 실린 offset을 들고 Flue 대화 스트림을 읽어서 받는다. offset은 응답에서 받은 문자열을 저장해…

Flue로 만든 고객 응대 에이전트에 스킬, 서브에이전트, MCP 서버, 샌드박스를 차례로 붙여 보면 useSkill, useSubagent, useMcpConnection, useSandbox 모두 에이전트 함수에 한 줄을 더하는 같은 모양이고, 조건문 안에 넣으면 상태에 따라 붙였다 뗄 수도 있다. 하지만 모델이 호출마다 받는 분량과 실제…

결제나 메일 발송을 맡은 도구가 도는 중에 서버가 죽으면, 서버가 돌아온 뒤 그 도구도 다시 실행될 거라고 기대하기 쉽다. Flue에서 크래시 뒤에 재실행되는 도구는 durable: true로 선언한 도구뿐이다. 일반 도구 호출은 결과를 알 수 없다는 오류로 마감되고, 모델이 그 오류를…

usePersistentState로 모드 상태를 두고 set_mode 도구로 그 모드를 바꾸게 만든 Flue 에이전트가 있다고 하자. 사용자가 “빠른 모드로 바꿔 줘”라고 보내면 모드가 바뀌었다고 알리는 답까지 빠른 모델이 쓸 것 같지만, 그 응답은 원래 모델이 끝내고 빠른 모델은 다음 메시지부터 답한다. 같은…

Flue로 첫 에이전트를 만들면 손이 가는 곳은 에이전트 코드보다 그 바깥이다. 에이전트는 시스템 프롬프트를 반환하는 함수 몇 줄로 끝나고, 대화 기록과 스트리밍, 중단된 작업의 복구는 Flue가 맡는다. 작성자에게 남는 일은 어디에 배포할지, 어떤 URL로 열지, 그 URL을 누구에게 열지를 정하는…