Yoon-gu Hwang commited on
Commit
00237bb
·
1 Parent(s): 812e2f4

일단 돌아는 가는 코드 추가

Browse files
Files changed (1) hide show
  1. app_chatbot_mcp.py +231 -0
app_chatbot_mcp.py ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import gradio as gr
3
+ from mcp import ClientSession
4
+ from mcp.client.sse import sse_client
5
+ from langchain_mcp_adapters.tools import load_mcp_tools
6
+ from langgraph.prebuilt import create_react_agent
7
+ import traceback
8
+ from typing import List, Tuple, Optional
9
+ from pprint import pprint
10
+
11
+ class MCPChatbot:
12
+ def __init__(self):
13
+ self.session: Optional[ClientSession] = None
14
+ self.agent = None
15
+ self.tools = None
16
+ self.sse_url = "http://127.0.0.1:7860/gradio_api/mcp/sse"
17
+ self.is_initialized = False
18
+
19
+ async def initialize(self):
20
+ """MCP 연결 및 에이전트 초기화"""
21
+ try:
22
+ # SSE 클라이언트 연결
23
+ self.sse_client_context = sse_client(self.sse_url)
24
+ read, write = await self.sse_client_context.__aenter__()
25
+
26
+ # 클라이언트 세션 생성
27
+ self.session_context = ClientSession(read, write)
28
+ self.session = await self.session_context.__aenter__()
29
+
30
+ # 세션 초기화
31
+ await self.session.initialize()
32
+
33
+ # 도구 로드
34
+ self.tools = await load_mcp_tools(self.session)
35
+ tool_names = [tool.name for tool in self.tools]
36
+ print(f"로드된 도구들: {tool_names}")
37
+
38
+ # 에이전트 생성
39
+ self.agent = create_react_agent("openai:gpt-4o", self.tools)
40
+ self.is_initialized = True
41
+
42
+ return f"✅ 초기화 완료! 사용 가능한 도구: {', '.join(tool_names)}"
43
+
44
+ except Exception as e:
45
+ error_msg = f"❌ 초기화 실패: {str(e)}\n{traceback.format_exc()}"
46
+ print(error_msg)
47
+ return error_msg
48
+
49
+ async def cleanup(self):
50
+ """리소스 정리"""
51
+ try:
52
+ if hasattr(self, 'session_context') and self.session_context:
53
+ await self.session_context.__aexit__(None, None, None)
54
+ if hasattr(self, 'sse_client_context') and self.sse_client_context:
55
+ await self.sse_client_context.__aexit__(None, None, None)
56
+ self.is_initialized = False
57
+ except Exception as e:
58
+ print(f"정리 중 오류: {e}")
59
+
60
+ async def chat(self, message: str) -> str:
61
+ """메시지 처리 및 응답 생성"""
62
+ if not self.is_initialized:
63
+ return "❌ 먼저 '초기화' 버튼을 클릭해주세요!"
64
+
65
+ try:
66
+ # 에이전트에게 메시지 전달
67
+ response = await self.agent.ainvoke({
68
+ "messages": [{"role": "user", "content": message}]
69
+ })
70
+ pprint(response)
71
+
72
+ # 응답에서 마지막 메시지 추출
73
+ if "messages" in response and response["messages"]:
74
+ last_message = response["messages"][-1]
75
+ if hasattr(last_message, 'content'):
76
+ return last_message.content
77
+ elif isinstance(last_message, dict) and 'content' in last_message:
78
+ return last_message['content']
79
+ else:
80
+ return str(last_message)
81
+ else:
82
+ return "응답을 받지 못했습니다."
83
+
84
+ except Exception as e:
85
+ error_msg = f"❌ 오류 발생: {str(e)}\n{traceback.format_exc()}"
86
+ print(error_msg)
87
+ return error_msg
88
+
89
+ # 전역 챗봇 인스턴스
90
+ chatbot = MCPChatbot()
91
+
92
+ # 비동기 함수들을 동기 함수로 래핑
93
+ def initialize_chatbot():
94
+ """챗봇 초기화"""
95
+ try:
96
+ loop = asyncio.get_event_loop()
97
+ except RuntimeError:
98
+ loop = asyncio.new_event_loop()
99
+ asyncio.set_event_loop(loop)
100
+
101
+ return loop.run_until_complete(chatbot.initialize())
102
+
103
+ def process_message(message: str, history: List[Tuple[str, str]]) -> Tuple[List[Tuple[str, str]], str]:
104
+ """메시지 처리"""
105
+ try:
106
+ loop = asyncio.get_event_loop()
107
+ except RuntimeError:
108
+ loop = asyncio.new_event_loop()
109
+ asyncio.set_event_loop(loop)
110
+
111
+ response = loop.run_until_complete(chatbot.chat(message))
112
+
113
+ # 히스토리에 대화 추가
114
+ history.append((message, response))
115
+
116
+ return history, ""
117
+
118
+ def cleanup_chatbot():
119
+ """챗봇 정리"""
120
+ try:
121
+ loop = asyncio.get_event_loop()
122
+ except RuntimeError:
123
+ loop = asyncio.new_event_loop()
124
+ asyncio.set_event_loop(loop)
125
+
126
+ loop.run_until_complete(chatbot.cleanup())
127
+ return "정리 완료"
128
+
129
+ # Gradio 인터페이스 생성
130
+ def create_interface():
131
+ with gr.Blocks(title="MCP 챗봇", theme=gr.themes.Soft()) as demo:
132
+ gr.Markdown("# 🤖 MCP 도구 연동 챗봇")
133
+ gr.Markdown("MCP(Model Context Protocol) 도구들을 사용할 수 있는 AI 챗봇입니다.")
134
+
135
+ with gr.Row():
136
+ with gr.Column(scale=3):
137
+ # 채팅 인터페이스
138
+ chatbot_interface = gr.Chatbot(
139
+ label="대화",
140
+ height=500,
141
+ show_copy_button=True
142
+ )
143
+
144
+ with gr.Row():
145
+ msg_input = gr.Textbox(
146
+ placeholder="메시지를 입력하세요... (예: (3 + 5) x 12는 뭐야?)",
147
+ label="메시지",
148
+ scale=4
149
+ )
150
+ send_btn = gr.Button("전송", variant="primary", scale=1)
151
+
152
+ # 예시 메시지들
153
+ gr.Examples(
154
+ examples=[
155
+ "(3 + 5) x 12는 뭐야?",
156
+ "1234의 소인수분해를 해줘",
157
+ "오늘 날씨는 어때?",
158
+ "안녕하세요!"
159
+ ],
160
+ inputs=msg_input
161
+ )
162
+
163
+ with gr.Column(scale=1):
164
+ # 제어 패널
165
+ gr.Markdown("### 🛠️ 제어 패널")
166
+
167
+ init_btn = gr.Button("🚀 초기화", variant="secondary")
168
+ init_status = gr.Textbox(
169
+ label="초기화 상태",
170
+ value="초기화가 필요합니다",
171
+ interactive=False
172
+ )
173
+
174
+ cleanup_btn = gr.Button("🧹 정리", variant="secondary")
175
+ cleanup_status = gr.Textbox(
176
+ label="정리 상태",
177
+ interactive=False
178
+ )
179
+
180
+ # 도움말
181
+ gr.Markdown("""
182
+ ### 📝 사용법
183
+ 1. **초기화** 버튼을 클릭하여 MCP 서버에 연결
184
+ 2. 초기화가 완료되면 메시지를 입력하여 대화 시작
185
+ 3. 수학 계산, 날씨 정보 등 다양한 질문 가능
186
+ 4. 사용 완료 후 **정리** 버튼으로 연결 종료
187
+
188
+ ### 🔧 사용 가능한 기능
189
+ - 수학 계산 및 소인수분해
190
+ - 날씨 정보 조회
191
+ - 이미지 처리 (방향 확인, 세피아 필터)
192
+ - 기타 MCP 도구들
193
+ """)
194
+
195
+ # 이벤트 핸들러 설정
196
+ init_btn.click(
197
+ initialize_chatbot,
198
+ outputs=init_status
199
+ )
200
+
201
+ cleanup_btn.click(
202
+ cleanup_chatbot,
203
+ outputs=cleanup_status
204
+ )
205
+
206
+ # 메시지 전송 처리
207
+ def handle_submit(message, history):
208
+ if not message.strip():
209
+ return history, ""
210
+ return process_message(message, history)
211
+
212
+ send_btn.click(
213
+ handle_submit,
214
+ inputs=[msg_input, chatbot_interface],
215
+ outputs=[chatbot_interface, msg_input]
216
+ )
217
+
218
+ msg_input.submit(
219
+ handle_submit,
220
+ inputs=[msg_input, chatbot_interface],
221
+ outputs=[chatbot_interface, msg_input]
222
+ )
223
+
224
+ return demo
225
+
226
+ # 애플리케이션 실행
227
+ if __name__ == "__main__":
228
+ demo = create_interface()
229
+ demo.launch(
230
+ share=False,
231
+ )