peekabook-api / app /tools /api_tools.py
lael
feat: initial deploy
3960e2b
Raw
History Blame Contribute Delete
2.9 kB
import os
from dotenv import load_dotenv
from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from app.state.state import GraphState
from app.tools.tools import (
search_library,
get_popular_books,
check_book_availability,
get_trending_books,
get_book_recommendations,
get_book_isbn,
)
load_dotenv()
os.environ.setdefault("OPENAI_API_KEY", os.getenv("OPENAI_API_KEY", ""))
tools = [
search_library,
get_popular_books,
check_book_availability,
get_trending_books,
get_book_recommendations,
get_book_isbn,
]
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
system_prompt = """당신은 λ„μ„œκ΄€ μ±… μΆ”μ²œ νλ ˆμ΄ν„°μž…λ‹ˆλ‹€.
[좜λ ₯ ν˜•μ‹ - λ°˜λ“œμ‹œ 지킬 것]
μΆ”μ²œ λ„μ„œλ§ˆλ‹€ μ•„λž˜ ν˜•μ‹μœΌλ‘œ μž‘μ„±ν•˜μ„Έμš”.
---
πŸ“š {μ±… 제λͺ©} | {μ €μž}
![μ±… 제λͺ©](이미지URL)
✏️ μΆ”μ²œ 이유
(전달받은 μΆ”μ²œ 이유λ₯Ό κ·ΈλŒ€λ‘œ μž‘μ„±)
πŸ“ λŒ€μΆœ κ°€λŠ₯ μ—¬λΆ€
- (도ꡬ 호좜둜 얻은 μ‹€μ œ λ„μ„œκ΄€ 이름): (λŒ€μΆœ κ°€λŠ₯) or (λŒ€μΆœ λΆˆκ°€) or (λ―Έμ†Œμž₯)
---
[μ£Όμ˜μ‚¬ν•­]
- μΆ”μ²œ λ„μ„œ λͺ©λ‘μ˜ 3κΆŒμ„ λ°˜λ“œμ‹œ λͺ¨λ‘ μœ„ ν˜•μ‹μœΌλ‘œ 좜λ ₯ν•˜μ„Έμš”. μ˜ˆμ™ΈλŠ” μ—†μŠ΅λ‹ˆλ‹€.
- λŒ€μΆœ κ°€λŠ₯ 여뢀와 관계없이 3ꢌ μ „λΆ€ 좜λ ₯ν•˜μ„Έμš”.
- ν•­λͺ©μ—λŠ” search_library λ„κ΅¬λ‘œ μ‘°νšŒν•œ μ‹€μ œ λ„μ„œκ΄€ 이름을 κ·ΈλŒ€λ‘œ μ‚¬μš©ν•˜μ„Έμš”.
- 도ꡬ ν˜ΈμΆœμ— μ‹€νŒ¨ν•˜κ±°λ‚˜ 정보λ₯Ό 확인할 수 μ—†λŠ” 경우 "확인 λΆˆκ°€"둜 ν‘œμ‹œν•˜κ³  좜λ ₯ ν˜•μ‹μ€ λ°˜λ“œμ‹œ μœ μ§€ν•˜μ„Έμš”.
- 이미지 URL을 κ°€μ Έμ˜€μ§€ λͺ»ν•œ 경우 이미지 라인은 μƒλž΅ν•˜μ„Έμš”.
- 책을 μ œκ±°ν•˜κ±°λ‚˜ λ‹€λ₯Έ μ±…μœΌλ‘œ λŒ€μ²΄ν•˜λŠ” 것은 μ ˆλŒ€ κΈˆμ§€μž…λ‹ˆλ‹€.
- λŒ€μΆœ λΆˆκ°€λ₯Ό 이유둜 μΆ”κ°€ 멘트, λŒ€μ•ˆ μ œμ‹œ, λ„μ„œκ΄€ λ°©λ¬Έ ꢌ유 λ“± λΆˆν•„μš”ν•œ λ‚΄μš©μ„ 덧뢙이지 λ§ˆμ„Έμš”.
- ISBN, 이미지 URL, λŒ€μΆœ μ •λ³΄λŠ” λ°˜λ“œμ‹œ 도ꡬ 호좜 결과만 μ‚¬μš©ν•˜μ„Έμš”. μ ˆλŒ€ μ§€μ–΄λ‚΄μ§€ λ§ˆμ„Έμš”.
"""
agent_executor = create_react_agent(llm, tools, prompt=system_prompt)
def api_tool_calling_node(state: GraphState) -> dict:
recommendations = state.get("recommendations", [])
summary = state.get("summary", "")
district = "강남ꡬ"
if isinstance(recommendations, str):
rec_text = recommendations
else:
rec_text = "\n".join([
f"- 제λͺ©: {r['title']}, μ €μž: {r['author']}, ISBN: {r['isbn']}, μΆ”μ²œ 이유: {r['reason']}"
for r in recommendations
])
query = f"""
μ•„λž˜ μΆ”μ²œ λ„μ„œ 3ꢌ의 ν‘œμ§€ 이미지와 {district} λ„μ„œκ΄€ λŒ€μΆœ κ°€λŠ₯ μ—¬λΆ€λ₯Ό ν™•μΈν•΄μ„œ μ΅œμ’… μΆ”μ²œ 닡변을 λ§Œλ“€μ–΄μ€˜.
[μΆ”μ²œ λ„μ„œ]
{rec_text}
[μ‚¬μš©μž ν”„λ‘œνŒŒμΌ]
{summary}
"""
result = agent_executor.invoke({"messages": [HumanMessage(content=query)]})
return {"messages": [result["messages"][-1]]}