app.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import openai
  2. import uvicorn
  3. from typing import List
  4. from pydantic import BaseModel
  5. from fastapi import FastAPI, Body
  6. from fastapi.middleware.cors import CORSMiddleware
  7. from langchain.schema import SystemMessage, AIMessage, HumanMessage
  8. from langchain_core.prompts import ChatPromptTemplate
  9. from langchain_openai import ChatOpenAI
  10. from langchain.callbacks import get_openai_callback
  11. import os
  12. from dotenv import load_dotenv
  13. load_dotenv()
  14. from supabase.client import Client, create_client
  15. supabase_url = os.environ.get("SUPABASE_URL")
  16. supabase_key = os.environ.get("SUPABASE_KEY")
  17. supabase: Client = create_client(supabase_url, supabase_key)
  18. chat_model = ChatOpenAI(model='gpt-4o-mini')
  19. app = FastAPI()
  20. app.add_middleware(
  21. CORSMiddleware,
  22. allow_origins=["*"],
  23. allow_credentials=True,
  24. allow_methods=["*"],
  25. allow_headers=["*"],
  26. )
  27. from semantic_search import semantic_cache
  28. from api import whisper
  29. app.include_router(whisper.router, prefix='/whisper', tags=['whisper'])
  30. class ChatHistoryItem(BaseModel):
  31. q: str
  32. a: str
  33. @app.post("/chat/")
  34. async def chat(message, chat_history: List[ChatHistoryItem] = Body(...)):
  35. print(chat_history)
  36. messages_list = [
  37. SystemMessage(content="你是一名日照中心的志工,你的職責是陪伴老人聊天,你需要考量到老人的健康與安全,並能安撫老人,只有家人准許時才能離開日照中心。請用繁體中文"),
  38. AIMessage(content="你好!很高興能和您聊天。今天您過得怎麼樣呢?有沒有什麼想分享的事情?")
  39. ]
  40. for item in chat_history[-10:]:
  41. if item.q == "string" or item.a == "string" : continue
  42. messages_list.append(HumanMessage(content=item.q))
  43. messages_list.append(AIMessage(content=item.a))
  44. messages_list.append(HumanMessage(content=message))
  45. print(messages_list)
  46. prompt = ChatPromptTemplate(
  47. messages=messages_list
  48. )
  49. try:
  50. with get_openai_callback() as cb:
  51. # cache_question, cache_answer = semantic_cache(supabase, message)
  52. cache_question, cache_answer, video_cache = semantic_cache(supabase, message, SIMILARITY_THRESHOLD=0.83)
  53. if cache_answer:
  54. save_history(message, cache_answer)
  55. # return {"message": cache_answer}
  56. if video_cache is not None:
  57. return {"message": cache_answer, "video_cache": video_cache}
  58. else:
  59. return {"message": cache_answer}
  60. AIMessage_ = chat_model.invoke(prompt.format_messages()).content
  61. save_history(message, AIMessage_)
  62. except openai.RateLimitError as e:
  63. print(f"Rate limit exceeded: {e}")
  64. return {'message': "Current quota exceeded."}
  65. return {"message": AIMessage_}
  66. def save_history(question, answer):
  67. response = (
  68. supabase.table("INNOLUX_record")
  69. .insert({"question": question, "answer": answer})
  70. .execute()
  71. )
  72. from starlette.responses import JSONResponse
  73. @app.get("/health") # 使用網址給 kuma 監測
  74. async def health_check():
  75. return JSONResponse(content={"status": "ok"}, status_code=200)
  76. if __name__ == "__main__":
  77. try:
  78. uvicorn.run("app:app", reload=False, port=8087, host='cmm.ai', ssl_keyfile="/etc/letsencrypt/live/cmm.ai/privkey.pem", ssl_certfile="/etc/letsencrypt/live/cmm.ai/fullchain.pem")
  79. finally:
  80. import shutil
  81. cache_db = "chroma_db"
  82. shutil.rmtree(cache_db)