챗봇 v2.10 공개: 향상된 속도, 확장성, 단순성으로 사용자 경험 한 단계 높이기
FastAPI와 비동기 처리로 챗봇을 재구축하여 응답 시간을 단축하고 인터페이스를 단순화했습니다 — 타겟팅된 최적화가 어떻게 사용자 경험을 변화시켰는지 소개합니다.
업데이트 (2026): 이 챗봇은 Sydney로 발전했습니다! Flask에서 FastAPI, FAISS에서 Weaviate, 그리고 Supabase pgvector까지 — 여러 반복을 거쳐 Sydney는 이제 /ask/에 있으며 스트리밍 응답과 함께 Claude를 사용합니다. 아래의 FastAPI 패턴은 현재 위치까지의 발판이었습니다.
2024년 2월 원본 글은 맥락을 위해 아래에 보존됩니다.
2주 전, 저는 Langchain 프레임워크를 활용하고 FAISS를 벡터 저장소로 사용한 챗봇 v2에 대한 소식을 공유했습니다. 몇 달간의 반복적인 작업 끝에 코딩 수렁에서 빠져나온 방법에 대한 날것의 이야기였습니다.
버전 2가 버전 1에 비해 상당한 개선이었지만, 여전히 만족스럽지 못한 많은 문제가 있었습니다. 가장 큰 문제는 아마 성능이었을 것입니다; 더 정확히 말하면, 너무 느렸습니다 :P 또한 프론트엔드 인터페이스가 너무 많은 소개 문장으로 복잡해서 채팅 박스가 화면 아래쪽에 위치해 있었습니다.
이 글에서는 2.10이 더 부드럽고, 빠르고, 더 능력 있는 대화 경험을 제공하기 위해 타겟팅된 성능 최적화와 UX 개선을 어떻게 적용하는지 강조할 것입니다.
FastAPI로의 전환: 성능의 도약
v2.10의 향상된 성능의 핵심은 FastAPI로의 전환에 있습니다. 이 현대적인 웹 프레임워크는 응답 시간을 가속화할 뿐만 아니라 더 견고하고 확장 가능한 아키텍처를 도입합니다.
v2 Flask 프레임워크
# Initialize Flask app and Langchain agent
app = Flask(__name__)
CORS(app, resources=\{r"/query_blog": {"origins": "https://www.chandlernguyen.com"\}})
app.debug = False
limiter = Limiter(app=app, key_func=get_remote_address)
Flask는 단순성과 유연성을 제공하며 잘 작동했습니다. 그러나 사용자 기반이 커짐에 따라 더 성능이 좋은 솔루션의 필요성이 분명해졌습니다.
v2.1 FastAPI 프레임워크
# FastAPI with advanced CORS and async support
# Initialize FastAPI app
app = FastAPI()
# Configure CORS for production, allowing only your frontend domain
origins = ["https://www.chandlernguyen.com"]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
# allow_origins=["*"],
allow_credentials=True,
allow_methods=["POST"],
allow_headers=["Content-Type"],
)
FastAPI는 비동기 지원을 통해 성능을 향상시킵니다.
비동기 처리: 더 부드러운 대화
FastAPI의 비동기 기능을 활용하여, v2는 비차단 요청 처리를 도입하여 더 부드럽고 역동적인 사용자 상호작용을 가능하게 합니다. 아래는 예시입니다.
# Function to check content with OpenAI Moderation API (sensitive keys are loaded from environment variables)
async def is_flagged_by_moderation(content: str) -> bool:
openai_api_key = os.getenv('OPENAI_API_KEY')
if not openai_api_key:
logging.error("OPENAI_API_KEY not set in environment variables")
raise HTTPException(status_code=500, detail="Server configuration error")
headers = \{"Authorization": f"Bearer {openai_api_key\}"}
data = \{"input": content\}
async with httpx.AsyncClient() as client:
response = await client.post("https://api.openai.com/v1/moderations", json=data, headers=headers)
if response.status_code == 200:
response_json = response.json()
return any(result.get("flagged", False) for result in response_json.get("results", []))
else:
logging.error(f"Moderation API error: {response.status_code} - {response.text}")
return False
사용자 인터페이스 개선
v2.10의 프론트엔드는 시각적 매력과 사용자 참여를 향상시키기 위해 재설계되었습니다. 접근성과 사용자 경험에 중점을 두고, 새로운 디자인은 더 단순하고 직관적입니다.
과도한 소개 콘텐츠 줄이기
이 텍스트 블록은 이제 없어졌습니다.
<div class="container mt-5">
<h2 style="color: #454545; text-align: center;">Welcome to My Expat Life in America Chatbot!</h2>
<h3 style="margin-top: 15px; text-align: center;">
Get Answers to Your Questions on Living, Working, and Thriving in the US
</h3>
<h4 style="margin-top: 10px; text-align: center;">Ask about:</h4>
<ul style="list-style: none; text-align: center; color: #333;">
<li>Adapting to American Culture & Lifestyle</li>
<li>Navigating US Personal Finance & Banking</li>
<li>Tips for Relocation and Settling In</li>
<li>Understanding Healthcare and Insurance</li>
<li>Getting Around - Driving and Transportation</li>
<li>Education Opportunities and Resources</li>
<li>Professional Development and Networking</li>
</ul>
<h5 style="margin-top: 10px; color: grey; text-align: center;">
I'm here to provide helpful info and insights on the expat experience. What would you like to know?
</h5>
<h6 style="margin-top: 5px; color: grey; text-align: center;">
Go ahead, ask me anything! I'll do my best to give a thoughtful response <span style="font-weight: bold; color: #007bff;">in a few seconds.</span>
</h6>
이것이 대체 코드입니다
<h2 style="color: #454545; text-align: center;">Welcome to Chandler's Expat Life Chatbot!</h2>
<p style="text-align: center; margin-bottom: 20px;">Ask me anything about expat life in the US, from culture to finance.</p>
시각적으로, 변경된 모습은 이렇습니다
여백 줄이기 및 레이아웃 개선을 위한 추가 스타일
<style>
/* Additional styles to reduce white space and improve layout */
body, html \{
height: 100%;
margin: 0;
display: flex;
flex-direction: column;
\}
.container \{
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: center; /* Center vertically in the available space */
\}
#conversation \{
height: 300px; /* Adjust based on your preference */
overflow-y: auto;
border: 1px solid #ccc; /* Add border to conversation box */
padding: 10px;
border-radius: 5px; /* Optional: round corners */
\}
</style>
지정된 높이와 오버플로우 제어가 있는 #conversation 박스 스타일링은 깔끔하고 사용자 친화적인 채팅 인터페이스를 유지하는 데 특히 효과적입니다.
<!-- Area to display the conversation -->
<div id="conversation" aria-live="polite" class="mb-5" style="height: 300px; overflow-y: auto;"></div>
conversation div에 aria-live="polite"를 추가하는 것은 스크린 리더 사용자를 위한 세심한 추가로, 동적 콘텐츠 변경에 대한 알림을 받을 수 있게 합니다.
입력 필드 자동 포커스
AJAX 성공 및 에러 콜백 끝에 $('#user-query').focus();를 추가한 것은 사용자 친화적인 기능으로, 각 메시지 전송 후 입력 필드에 자동으로 포커스가 맞춰져 더 부드러운 채팅 경험을 제공합니다.
성능 모니터링 및 관찰을 위한 Langsmith 활용
이 버전 2.10에서는 langsmith를 활용하고 있습니다. 설정이 꽤 쉽고 대시보드 인터페이스가 충분히 직관적입니다.
그리고 특정 쿼리가 너무 오래 걸리는 것을 발견할 때마다, "클릭"하여 여정의 어느 부분이 문제인지 정확히 더 이해할 수 있습니다.
버전 2.1의 전체 백엔드 코드
늘 그렇듯이, 전체 백엔드 코드를 GitHub 여기에 공유했습니다. 이전 버전 챗봇 2.0과 같은 저장소에 있습니다.
챗봇을 한번 사용해보시길 바랍니다 :D 지난 16년간 제가 쓴 것에 대해 무엇이든 물어보세요.
챗봇을 만들어보거나 프레임워크 간 마이그레이션을 해보신 적이 있으신가요? 어떤 성능 트릭이 효과적이었는지 듣고 싶습니다.
감사합니다,
Chandler








