프로그래밍 406

Agent를 고도화하면서 겪은 문제점들

Tool이 늘어날 수록 멍청해지고, Input Token도 빠르게 소모했음다소 무의미해보이는 도구 호출 증가Tool 설명을 위한 Input Token의 증가Tool을 줄이기 위한 노력CAG 활용 → 관련되지 않은 질문에도 들어갔기 때문에 Input Token이 심하게 소모되어 비슷하고 항상 같이 사용되는 Tool을 하나로 합치는 방향으로 다시 작업계속 같은 패턴으로 사용하는 도구를 하나로 합침 → 회사 정보조회 도구Slack 채널을 조회하는 도구Slack UserGroup을 조회하는 도구Slack UserGroup 소속 멤버를 조회하는 도구Tool 설명을 간결하고 명확한 방향으로 수정거대해진 프롬프트, 이를 무시하는 LLMClaude는 주어진 문제에 적절한 도구를 잘 사용하지만, 친근하게 대하라는 Sys..

LangGraph Agent에 장기기억(LTM)추가하기

LangGraph로 만든 Agent에 장기 기억을 추가하기 위해서는 기존 그래프에 새로운 노드와 도구를 추가해야한다.노드대화 전 저장된 기억을 불러오는 노드 (load_memories)도구관련 기억을 검색해서 가져오는 도구 (SearchRecallMemoriesTool)기억하는 도구 (SaveMemoriesTool)load_memories 노드가 하는 일?load_memories 노드부터 살펴보겠다. load_memories는 Agent가 작업을 처리하기 시작할때 이전 대화 내용을 기반으로 관련된 기억을 불러오는 노드다. 불러온 기억은 State에 [”recall_memories”]로 저장되고, 이는 나중에 기억과 관련된 SystemPrompt에 Context로서 제공된다.load_memories를 어떻..

LangGraph ReAct Agent 커스터마이즈하기

Langgraph.prebuilt의 create_react_agent를 이용해 ReAct Agent를 생성하면 이미 StateGraph가 컴파일되어서 반환되기때문에 이걸로 Agent를 만들면 워크플로우를 수정할 수 없다. Agent를 개발하다보니 추가적인 단계를 정의해야할 일이 생겨 더 이상 create_react_agent를 사용할 수 없었다. 그래서 create_react_agent의 코드를 분석해서 커스터마이즈 가능하도록 일부 코드들을 들고와서 create_custom_react_agent를 만들었다. StateGraph가 컴파일 되기전에 customize_workflow로 graph를 받아서 추가로 workflow를 수정한 뒤에 컴파일 할 수 있다. 주석도 열심히 달아두었기때문에 처음부터 ReAc..

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..