프로그래밍 403

Pydantic Serialize시 오류 : Object of type <Enum> is not JSON serializable 해결방법

공식문서 참조: https://docs.pydantic.dev/latest/api/config/#pydantic.config.ConfigDict.use_enum_valuesEnum을 Enum 값으로 사용할지 여부를 정의할 수 있는 use_enum_values라는 Model Configuration을 True로 설정할 경우에 Serialize 가능해진다.class SomeEnum(Enum): FOO = 'foo' BAR = 'bar' BAZ = 'baz'class SomeModelCls(BaseModel): e: SomeEnumm = SomeModelCls(e=SomeEnum.FOO)m.model_dump() # TypeError: Object of type SomeEnum is no..

반쪽짜리 Contextual Retrieval로 RAG 강화 해보기

2024년 9월 20일, Anthropic은 Contextual Retrieval이라는 개념을 제시했다. Contextual Retrieval은 기존의 RAG의 검색 성공률을 향상시키기 위한 방법으로, Contextual Embeddings와 Contextual BM25의 두가지 하위 기술을 사용한다. Anthropic에 따르면 이 방법을 이용할 경우 실패한 검색 수를 49%까지 줄일 수 있으며, ReRanking과 함께 사용하면 67%까지 줄일 수 있다고한다. 최근에는 RAG에 이어 CAG(Cache-Augmented Generation)도 등장했다. CAG는 더 길어진 LLM의 Context Window를 충분히 활용하여, 검색 증강하려는 문서의 전체 내용이 Context Window에 들어갈 수 있..

사내 AI Agent 구축기

이건 정말 Agent를 만들어야하는데...사원들의 온보딩을 위해 회사업무에 필요한 질문에 대한 답변들을 제공해주는 챗봇을 개발하게 되었다. 노션도, 슬랙도 통합해야하고 사용자의 다양한 질문에 대답할 수 있어야했다. 꼼짝없이 Agent를 만들어야할 순간이 왔다. 이때까지도 번역을 위한 작은 RAG앱만 만들어본터라, Agent를 개발하는 것은 좀 막막했다. 심지어 시작은 신입 “개발자”들을 위한 챗봇이었다. 기본적인 회사 문서들 외에 코드베이스도 통합해야했다. 코드베이스 통합을 위해서 이리저리 찾아보다가 Codegen의 CodeAgent를 사용해봤다. CodeAgent를 사용하면서 어떻게 Agent를 개발해야하는지에 대한 많은 힌트를 얻었다. 내가 개발한 Agent도 CodeAgent와 크게 다르지않다. 그..

Cannot call method 'get_first_node_in_group' on a null value 해결방법

씬을 오가다보면 Cannot call method 'get_first_node_in_group' on a null value라며 문제가 생기는 경우가 있다. 대표적인 예시코드는 다음과 같다.@onready var player: Player = get_tree().get_first_node_in_group("player") 이는 첫번째 프레임이 처리되기도 전에 group에 있는 노드를 가져오려고 해서 생기는 이슈로, 프레임이 처리되기까지 기다린 후 트리가 셋업된 후에 노드를 가져오면 해결된다.var player: Playerfunc _ready() -> void: await get_tree().process_frame player = get_tree().get_first_node_in_group("play..

[ComfyUI] Workflow를 Python API로 만들기

ComfyUI로 구성한 Workflow를 Python API로 만드는 방법을 공유한다. ComfyUI 서버에 HTTP/Websocket 통신을 하는 구조로 되어있기 때문에 사실 어떤 언어든 가능하다. 노드 ID의 확인과 사용예시로, Text 프롬프트를 읽고 이미지를 출력하는 Workflow가 있다고하면 ComfyUI에서는 이런 TextInput Node를 준비하고, 이 노드의 출력을 CLIP Prompt 노드의 STRING 포트와 연결한다. 이 노드의 우측상단 귀퉁이에는 #37이라는 번호가있는데, 이것이 노드 ID다. Workflow를 API 형태로 Export하고JSON 파일을 열어보면 “37”번 키에 해당 노드의 정보가 들어있음을 알 수 있다. 우리는 이런식으로 JSON 파일을 읽고, 입력값을 바꾸길..

[FastAPI] 요청/응답 로깅하는 법

Python 웹서버 프레임워크 FastAPI의 모든 요청과 응답, 응답시간을 로깅하는 미들웨어를 추가하는 코드다.import logginglogging.basicConfig(level=logging.INFO)logger = logging.getLogger("request_logger")@app.middleware("http")async def log_requests(request: Request, call_next): start_time = time.time() # 요청 정보 로깅 logger.info(f"Request: {request.method} {request.url}") logger.info(f"Headers: {request.headers}") logger.i..

[ComfyUI] AI를 이용한 배너광고 자동 생성 워크플로우

가능한 사람의 손을 거치지 않고 다음과 같은 형식의 배너 광고를 생성하는 것이 나의 목표였다.사실 이 첨부사진은 자동으로 만들어낸 이미지다!입력으로는 게임 일러스트 사진을주고, 광고 문구를 제공해주었다.이 광고 배너를 만든 ComfyUI 워크플로우를 하나하나 뜯어보면서 어떻게 구성했는지 설명해보겠다. Step1. 배너 크기만큼 늘리기어떤 AspectRatio를 가진 이미지라도 가로배너 이미지로 만들어주기 위해 좌측의 Padding 값을 계산하는 단계다. 세로형 이미지의 경우 이미지가 정방형이라고 가정했을때 생기는 좌우 패딩만큼의 간격을 오른쪽에 추가해준다. 을 하게되면 패딩한 만큼 이미지 옆에 회색 공간이 생기고, 마스크도 그에 맞춰서 생성된다. Step2. 마스킹된 영역 흐리게 채우기이전 단계에서 마스..

[LangChain] LLM Workflow: Routing 구현

Routing은 이전 단계의 결과에따라 다음 단계를 비결정적으로 정의할 수 있도록 한다.  RunnableLambda 혹은 RunnableBranch를 이용하는 방법이있지만, 현재는 RunnableLambda를 사용하는 방법이 권장된다.  RunnableLambda는 Python callable을 Runnable로 바꿔주기만하는데, 별도로 RunnableBranch를 사용하기보다는 Python 코드 분기문을 통해 처리를 하라는 것이다. 실습유저의 질문이 파이썬 혹은 코틀린 프로그래밍과 관련 있을 경우, 이에 최적화된 프롬프트로 답변할 수 있도록 분기처리를 추가해볼 것이다. 먼저, 질문이 파이썬이나 코틀린과 관련되어있는지만 확인하는 체인을 준비한다.from langchain_core.prompts impo..