tools =[{"name":"get_weather","description":"특정 도시의 현재 날씨를 조회합니다.","input_schema":{"type":"object","properties":{"city":{"type":"string","description":"날씨를 조회할 도시 이름 (예: Seoul, Tokyo)"},"unit":{"type":"string","enum":["celsius","fahrenheit"],"description":"온도 단위"}},"required":["city"]}},{"name":"calculate","description":"수학 계산을 수행합니다.","input_schema":{"type":"object","properties":{"expression":{"type":"string","description":"계산할 수식 (예: '2 + 3 * 4')"}},"required":["expression"]}}]
importmathdefget_weather(city:str, unit:str="celsius")->dict:"""날씨 API 호출 (예시 - 실제 API 연동 필요)"""# 실제 구현에서는 OpenWeatherMap 등 API 사용 weather_data ={"Seoul":{"temp":18,"condition":"맑음","humidity":60},"Tokyo":{"temp":22,"condition":"흐림","humidity":75},"New York":{"temp":15,"condition":"비","humidity":80},} data = weather_data.get(city,{"temp":20,"condition":"알 수 없음","humidity":50})if unit =="fahrenheit": data["temp"]= data["temp"]*9/5+32return{"city": city,"temperature": data["temp"],"unit": unit,"condition": data["condition"],"humidity": data["humidity"]}defcalculate(expression:str)->dict:"""수식 계산"""try:# 안전한 계산 (eval 대신 제한된 표현식만 허용) allowed_names ={k: v for k, v in math.__dict__.items()ifnot k.startswith("_")} result =eval(expression,{"__builtins__":{}}, allowed_names)return{"result": result,"expression": expression}except Exception as e:return{"error":str(e),"expression": expression}defexecute_tool(tool_name:str, tool_input:dict)->str:"""도구 실행 디스패처"""if tool_name =="get_weather": result = get_weather(**tool_input)elif tool_name =="calculate": result = calculate(**tool_input)else: result ={"error":f"알 수 없는 도구: {tool_name}"}importjsonreturn json.dumps(result, ensure_ascii=False)
importanthropicimportjsonclient = anthropic.Anthropic()defrun_agent(user_request:str, tools:list)->str:"""
에이전트 메인 루프
Args:
user_request: 사용자 요청
tools: 사용 가능한 도구 목록
Returns:
최종 응답 텍스트
""" messages =[{"role":"user","content": user_request}]print(f"사용자: {user_request}\n")whileTrue:# Claude API 호출 response = client.messages.create( model="claude-opus-4-5", max_tokens=4096, tools=tools, messages=messages
)print(f"[stop_reason: {response.stop_reason}]")# 최종 응답인 경우 루프 종료if response.stop_reason =="end_turn":# 텍스트 응답 추출 final_response =""for block in response.content:ifhasattr(block,"text"): final_response += block.text
return final_response
# 도구 사용 요청인 경우if response.stop_reason =="tool_use":# 어시스턴트 응답을 메시지 히스토리에 추가 messages.append({"role":"assistant","content": response.content
})# 각 도구 실행 tool_results =[]for block in response.content:if block.type =="tool_use":print(f"도구 실행: {block.name}({block.input})") result = execute_tool(block.name, block.input)print(f"도구 결과: {result}\n") tool_results.append({"type":"tool_result","tool_use_id": block.id,"content": result
})# 도구 결과를 메시지에 추가 messages.append({"role":"user","content": tool_results
})else:# 예상치 못한 stop_reasonprint(f"예상치 못한 stop_reason: {response.stop_reason}")breakreturn"에이전트 실행 중 오류가 발생했습니다."# 실행 예시if __name__ =="__main__": result = run_agent("서울과 도쿄의 날씨를 비교해주고, 두 도시 온도 차이를 계산해줘", tools
)print(f"\n최종 답변:\n{result}")
실행하면 다음과 같은 흐름으로 동작합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
사용자: 서울과 도쿄의 날씨를 비교해주고, 두 도시 온도 차이를 계산해줘
[stop_reason: tool_use]
도구 실행: get_weather({'city': 'Seoul', 'unit': 'celsius'})
도구 결과: {"city": "Seoul", "temperature": 18, ...}
도구 실행: get_weather({'city': 'Tokyo', 'unit': 'celsius'})
도구 결과: {"city": "Tokyo", "temperature": 22, ...}
도구 실행: calculate({'expression': '22 - 18'})
도구 결과: {"result": 4, "expression": "22 - 18"}
[stop_reason: end_turn]
최종 답변:
서울은 현재 18°C 맑음, 도쿄는 22°C 흐림입니다. 두 도시의 온도 차이는 4°C로...
defcreate_coding_agent(language:str="Python")-> callable:"""특정 언어 전문 코딩 에이전트 생성""" system_prompt =f"""당신은 {language} 전문 시니어 엔지니어입니다.
역할:
- 코드 리뷰 및 개선 제안
- 버그 분석 및 수정 방법 설명
- 베스트 프랙티스 안내
- 성능 최적화 조언
원칙:
- 항상 코드 예시와 함께 설명합니다
- 이유를 설명하지 않고 답변하지 않습니다
- 보안과 성능 양쪽을 고려합니다
- 간결하고 읽기 쉬운 코드를 지향합니다"""defagent(user_input:str, messages:list=None)->str:if messages isNone: messages =[] messages.append({"role":"user","content": user_input}) response = client.messages.create( model="claude-opus-4-5", max_tokens=2048, system=system_prompt, messages=messages
) reply = response.content[0].text
messages.append({"role":"assistant","content": reply})return reply
return agent
# 사용 예시python_expert = create_coding_agent("Python")conversation =[]print(python_expert("이 코드의 문제점이 뭐야?\n\ndef get_users():\n users = db.execute('SELECT * FROM users')\n return users", conversation))