Spaces:
Running
Running
| from __future__ import annotations | |
| from langchain.prompts import ChatPromptTemplate | |
| from langchain.schema.runnable import RunnableLambda | |
| from langchain_core.output_parsers import StrOutputParser | |
| STUDY_ASSISTANT_PROMPT = ChatPromptTemplate.from_messages( | |
| [ | |
| ( | |
| "system", | |
| """๋๋ Azure ์๊ฒฉ์ฆ ํ์ต์ ๋๋ ํ๊ตญ์ด ํํฐ๋ค. | |
| ๋ฐ๋์ ํ๊ตญ์ด๋ก ๋ต๋ณํ๋ผ. Azure Docs๊ฐ ์์ด์ฌ๋ ๊ทธ๋๋ก ๋ฒ์ญํด์ ๊ธธ๊ฒ ์ฎ๊ธฐ์ง ๋ง๊ณ ํ๊ตญ์ด๋ก ์์ฝํ๋ผ. | |
| ์์ด ์ ํ๋ช /๊ธฐ์ ์ฉ์ด๋ ํ์ํ ๋๋ง ๊ดํธ๋ก ๋ณ๊ธฐํ๋ผ. ์: ๋คํธ์ํฌ ๋ณด์ ๊ทธ๋ฃน(NSG) | |
| ์ฌ์ฉ์๊ฐ ํ์ฌ ๋ฌธ์ ๋ฅผ ํฌํจํด์ ์ง๋ฌธํ๋ฉด ํ์ฌ ๋ฌธ์ ๋ฅผ 1์์ ๊ทผ๊ฑฐ๋ก ๋ต๋ณํ๋ผ. | |
| Azure Docs ๊ณต์ ๋ฌธ์๋ ๊ฐ๋ ์ค๋ช ๊ณผ ์ ๋ต ๊ทผ๊ฑฐ ๋ณด๊ฐ์ ์ฌ์ฉํ๋ผ. | |
| ๊ฒ์๋ ์ ์ฌ ๋ฌธ์ ๋ ํ์ฌ ๋ฌธ์ ๋ฅผ ์ค๋ช ํ๊ธฐ ์ํ ๋ณด์กฐ ๊ทผ๊ฑฐ๋ก๋ง ์ฌ์ฉํ๋ผ. | |
| ๊ทผ๊ฑฐ ์ฐ์ ์์๋ ํ์ฌ ๋ฌธ์ > Azure Docs ๊ณต์ ๋ฌธ์ > ์ ์ฌ ๋ฌธ์ ๋ค. | |
| ์ฐธ๊ณ ๋ฌธ์ ๊ฐ ํ์ฌ ๋ฌธ์ ์ ๋ค๋ฅด๋ฉด ์ฐจ์ด๋ฅผ ๋จผ์ ๋งํ๊ณ , ์ฐธ๊ณ ๋ฌธ์ ์ ๋ต์ ํ์ฌ ๋ฌธ์ ์ ๋ต์ฒ๋ผ ๋งํ์ง ๋ง๋ผ. | |
| ๊ทผ๊ฑฐ๊ฐ ๋ถ์กฑํ๋ฉด ๋ถ์กฑํ๋ค๊ณ ๋งํ๊ณ , ์ถ์ธกํ์ง ์๋๋ค. | |
| ๋ต๋ณ์ ์ ์ฒด 8๋ฌธ์ฅ ์ด๋ด๋ก ์์ฝํ๋ผ. | |
| ๋ต๋ณ ํ์: | |
| 1. ์์ฝ | |
| 2. ํ์ฌ ๋ฌธ์ ๊ธฐ์ค | |
| 3. ๊ทผ๊ฑฐ | |
| 4. ํท๊ฐ๋ฆด ํฌ์ธํธ | |
| ํ์ด ํ๋ฆ์ ๋ด๋ถ ์ฌ๊ณ ๊ณผ์ ์ ๊ทธ๋๋ก ๊ธธ๊ฒ ๋ ธ์ถํ์ง ๋ง๊ณ , | |
| ์ฐธ๊ณ ๋ฌธ์ /ํด์ค์์ ํ์ธ ๊ฐ๋ฅํ ๊ทผ๊ฑฐ์ ํ๋จ ์์๋ง ๊ฐ๋จํ ์์ฝํ๋ผ.""", | |
| ), | |
| ( | |
| "human", | |
| """์ง๋ฌธ: | |
| {question} | |
| ์ฐธ๊ณ ๋ฌธ์ /ํด์ค: | |
| {context} | |
| ์ ๊ทผ๊ฑฐ๋ฅผ ๋ฐํ์ผ๋ก ๋ฐ๋์ ํ๊ตญ์ด๋ก ์งง๊ฒ ์์ฝํด์ ๋ต๋ณํ๋ผ.""", | |
| ), | |
| ] | |
| ) | |
| def format_context(results: list, max_chars: int = 2400) -> str: | |
| if not results: | |
| return "๊ฒ์๋ ์ฐธ๊ณ ๋ฌธ์ ๊ฐ ์์ต๋๋ค." | |
| chunks = [] | |
| remaining = max_chars | |
| for idx, item in enumerate(results, start=1): | |
| if remaining <= 0: | |
| break | |
| metadata = item.metadata or {} | |
| answer = metadata.get("answer") or "" | |
| source = metadata.get("source") or "unknown" | |
| source_type = metadata.get("source_type") or "question" | |
| title = metadata.get("title") or "" | |
| url = metadata.get("url") or "" | |
| score = f"{item.score:.4f}" if item.score is not None else "n/a" | |
| text = str(item.text or "") | |
| text = text[: max(300, remaining)] | |
| chunk = "\n".join( | |
| [ | |
| f"[๋ฌธ์ {idx}] type={source_type}, id={item.id}, source={source}, score={score}", | |
| f"title={title}" if title else "", | |
| f"url={url}" if url else "", | |
| text, | |
| f"์ ๋ต: {answer}" if answer else "", | |
| ] | |
| ) | |
| chunks.append(chunk) | |
| remaining -= len(chunk) | |
| return "\n\n".join(chunks) | |
| def build_study_assistant_chain(llm): | |
| """langchain-kr ํํ ๋ฆฌ์ผ์ฒ๋ผ LCEL ํ์ดํ(|)๋ก ๊ตฌ์ฑํ RAG ๋ต๋ณ ์ฒด์ธ.""" | |
| return ( | |
| { | |
| "question": RunnableLambda(lambda payload: payload["question"]), | |
| "context": RunnableLambda(lambda payload: format_context(payload["results"], payload.get("max_context_chars", 2400))), | |
| } | |
| | STUDY_ASSISTANT_PROMPT | |
| | llm | |
| | StrOutputParser() | |
| ) | |
| def build_ollama_llm(model: str, base_url: str, temperature: float = 0.2, num_predict: int = 320): | |
| try: | |
| from langchain_community.chat_models import ChatOllama | |
| try: | |
| return ChatOllama(model=model, base_url=base_url, temperature=temperature, num_predict=num_predict) | |
| except TypeError: | |
| return ChatOllama(model=model, base_url=base_url, temperature=temperature) | |
| except ImportError: | |
| from langchain_community.llms import Ollama | |
| try: | |
| return Ollama(model=model, base_url=base_url, temperature=temperature, num_predict=num_predict) | |
| except TypeError: | |
| return Ollama(model=model, base_url=base_url, temperature=temperature) | |