Jump to content

langChain ChatClovaX Structured Tool 지원 관련 문의


Recommended Posts

안녕하세요 langchain-naver를 통해 ChatClovaX를 사용하고 있는데요.

랭체인 도구중 StructuredTool을 지원하지 않는 것으로 확인되는데..

혹시 지원 계획이 있을까요?

docstring이나 description에 적은 형태로 매개변수를 생성하여 tool calling이 잘 안되는 것 같아서 문의드립니다.

그리고 혹시 각 tool의 결과값을 다음 tool의 매개변수로 잘 활용하기 위해서 명시해야하는 prompt나 desc, docstring이 있을까요?

 

 

Edited by 탱구탱구
링크 복사
다른 사이트에 공유하기

안녕하세요 @탱구탱구님, 

Function calling 기능을 지원하는 HCX-005, HCX-DASH-002 두 모델을 사용하실 경우, langchain-naver를 통한 Tool 관련 기능 역시 사용하실 수 있습니다.

다만 max_tokens를 1024 이상으로 정의하셔야 하는 점 참고 부탁드립니다. (API 가이드)

또한 아마 정의하시는 Tool의 복잡도에 따라 기대하시는 바에 맞게 동작하지 않을 수 있는데요. 간단한 예제로는 StructuredTool도 잘 작동하는 것으로 확인되어 혹시 지원하지 않는 것으로 확인하신 이유 또는 실행하신 코드 스니펫을 공유해주실 수 있을까요? 확인해보고 보다 상세히 답변드릴 수 있도록 하겠습니다.  

감사합니다.

링크 복사
다른 사이트에 공유하기

안녕하세요 일단 날짜 조회 하는 부분부터 이슈가 있어서 전달드립니다.

Tool.fromFunction을 통해서 호출할 때는 년도가 잘못 나오는 경우를 제외하면 요청 및 응답은 오는데요.

다만 @tool 데코레이션이나 StructuredTool을 통해 tool을 정의할 경우 디버그 오류가 아래 볼드처리된 부분만 나오고 끝이라서요.

httpx.HTTPStatusError: Client error '400 Bad Request' for url 'https://clovastudio.stream.ntruss.com/v1/openai/chat/completions'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400

 

같은 코드에서 ChatOpenAi나 ChatAnthropic을 사용했을 때는 두 모델 모두 정상이라서요.

혹시 코드상에 문제가 되는 부분이 있다면 피드백 부탁드립니다.

아래는 도구 정의 및 호출하는 코드입니다.


def get_current_datetime(dummy: str = "now") -> str:
    """오늘 날짜를 ISO 8601 형식으로 반환합니다."""
    print("[tool 호출] 날짜 조회->", datetime.now().isoformat())
    kst = timezone(timedelta(hours=9))
    current_time = datetime.now()
    return {"current_time": current_time.isoformat()}

TOOLS = [
    StructuredTool.from_function(
        func=get_current_datetime,
        name="get_current_datetime",
        description="오늘 시간을 ISO 8601 형식으로 반환합니다. 입력은 무시됩니다."
    )
]

 

model = ChatClovaX(temperature=0.5, model="HCX-DASH-002", max_tokens=3000) # HCX-005, HCX-DASH-002
# create_react_agent 
app = create_react_agent(
    model=model,
    tools=tools,
    prompt=system_prompt,
    interrupt_before=None,
    interrupt_after=None,
    debug=True
)
async def run_graph_stream(query: str, user_id: str, room_id: str):
    state = {
        "messages": [
            HumanMessage(
                content=query,
              # additional_kwargs={"user_id": user_id, "meeting_id": room_id},
            )
        ]
    }

    print(f"=== DEBUG: 상태 생성 완료 ===")
    print(f"메시지 개수: {len(state['messages'])}")
    try:
        async for msg, metadata in app.astream(state, stream_mode="messages"):
            print(f"=== DEBUG: 스트림 응답 ===")
            print(f"메시지 타입: {type(msg)}")
            print(f"메시지 내용: {msg}")
            
            if isinstance(msg, AIMessageChunk):
                content_text = ""
                if hasattr(msg, 'content') and msg.content:
                    if isinstance(msg.content, str):
                        content_text = msg.content
                    elif isinstance(msg.content, list):
                        # content list인 경우 (Anthropic 형식)
                        for item in msg.content:
                            if isinstance(item, dict) and item.get('type') == 'text':
                                content_text += item.get('text', '')
                            elif hasattr(item, 'text'):
                                content_text += item.text
                
                if content_text:
                    data = {
                        "type": "token",
                        "content": content_text,
                        "timestamp": datetime.now().isoformat()
                    }
                    yield f"data: {json.dumps(data)}\n\n"

        yield f"data: {json.dumps({'type': 'done'})}\n\n"

    except Exception as e:
        print(f"=== DEBUG: 스트림 에러 ===")
        print(f"에러: {str(e)}")
        error_data = {
            "type": "error",
            "content": f"에러 발생: {str(e)}",
            "timestamp": datetime.now().isoformat()
        }
        yield f"data: {json.dumps(error_data)}\n\n"
링크 복사
다른 사이트에 공유하기

게시글 및 댓글을 작성하려면 로그인 해주세요.



로그인
×
×
  • Create New...