툴 실행 결과 중 일부는 모델에는 숨기고, 체인이나 후속 툴에서는 활용할 수 있도록 따로 관리하고 싶을 수 있다.예를 들어, 전체 Document 대신 모델에는 요약만 보여주고, 실제 데이터는 내부적으로 유지하고 활용하고자 할 수 있다.
Tool과 Tool Message 인터페이스를 사용하면, 모델에게 보여줄 툴 출력 부분(TooleMessage.content)과 모델 외부에서 사용할 출력 부분(ToolMessage.artifact)을 구분할 수 있다. 해당 기능은 langchain-core 0.2.19 이상 버전에서 도입되었으며, 사용하려면 최신 버전이 설치되어 있어야 한다.
툴에서 메시지 내용과 그 외 데이터를 구분해서 반환하고 싶다면 툴을 정의할 때 response_format="content_and_artifact"를 명시하고, 리턴값을 (content, artifact) 형태의 튜플로 반환해야 한다.
import random
from typing import List, Tuple
from langchain_core.tools import tool
@tool(response_format="content_and_artifact")
def generate_random_ints(min: int, max: int, size: int) -> Tuple[str, List[int]]:
"""Generate size random ints in the range [min, max]."""
array = [random.randint(min, max) for _ in range(size)]
content = f"Successfully generated array of {size} random ints in [{min}, {max}]."
return content, array
result = generate_random_ints.invoke({"min": 0, "max": 9, "size": 10})
print(result)
# Successfully generated array of 10 random ints in [0, 9].
툴을 ToolCall 형식으로 실행하면, 툴은 TooleMessage 객체를 반환하며, 그 안에는 모델에게 보여줄 메시지(content)와 모델 외부에서 사용할 수 있는 데이터(artifact)가 모두 담겨 있다.
import random
from typing import List, Tuple
from langchain_core.tools import tool
@tool(response_format="content_and_artifact")
def generate_random_ints(min: int, max: int, size: int) -> Tuple[str, List[int]]:
"""Generate size random ints in the range [min, max]."""
array = [random.randint(min, max) for _ in range(size)]
content = f"Successfully generated array of {size} random ints in [{min}, {max}]."
return content, array
result = generate_random_ints.invoke(
{
"name": "generate_random_ints",
"args": {"min": 0, "max": 9, "size": 10},
"id": "123", # required
"type": "tool_call", # required
}
)
print(result)
# content='Successfully generated array of 10 random ints in [0, 9].' name='generate_random_ints' tool_call_id='123' artifact=[5, 4, 4, 6, 2, 5, 5, 6, 9, 9]
직접 BaseToole을 상속하고 커스텀 툴 클래스를 만들어서, 같은 작업을 수행할 수 있다.
import random
from typing import List, Tuple
from langchain_core.tools import BaseTool
class GenerateRandomFloats(BaseTool):
name: str = "generate_random_floats"
description: str = "Generate size random floats in the range [min, max]."
response_format: str = "content_and_artifact"
ndigits: int = 2
def _run(self, min: float, max: float, size: int) -> Tuple[str, List[float]]:
range_ = max - min
array = [
round(min + (range_ * random.random()), ndigits=self.ndigits)
for _ in range(size)
]
content = f"Generated {size} floats in [{min}, {max}], rounded to {self.ndigits} decimals."
return content, array
# Optionally define an equivalent async method
# async def _arun(self, min: float, max: float, size: int) -> Tuple[str, List[float]]:
# ...
rand_gen = GenerateRandomFloats(ndigits=4)
result = rand_gen.invoke(
{
"name": "generate_random_floats",
"args": {"min": 0.1, "max": 3.3333, "size": 3},
"id": "123",
"type": "tool_call",
}
)
print(result)
# content='Generated 3 floats in [0.1, 3.3333], rounded to 4 decimals.' name='generate_random_floats' tool_call_id='123' artifact=[3.2962, 3.0685, 0.757]
Reference
'AI4C' 카테고리의 다른 글
LangChain Handling Tool Errors (0) | 2025.05.14 |
---|---|
LangChain tool 등록 (0) | 2025.05.14 |
LangGraph Persistence Layer 동작 원리 (0) | 2025.05.13 |
LangGraph 코드 예제 (0) | 2025.05.11 |
LangGraph 아키텍처 (0) | 2025.05.11 |