ABAO77's picture
Upload 52 files
0cfb154 verified
from pydantic import BaseModel, Field
from langchain_core.prompts import ChatPromptTemplate
from typing import Literal
from src.config.llm import llm_2_0 as llm
from typing import Optional
class RouteQuery(BaseModel):
"""Route a user query to the most relevant datasource."""
datasource: Literal["vectorstore", "casual_convo"] = Field(
...,
description="Given a user question choose to route it to casual_convo or a vectorstore.",
)
class ExtractFilter(BaseModel):
"""Extract job level and job title from user question."""
job_level: str = Field(description="The level of the job the user is asking about.")
job_title: str = Field(description="The title of the job the user is asking about.")
class GradeDocuments(BaseModel):
"""Binary score for relevance check on retrieved documents."""
binary_score: str = Field(
description="Documents are relevant to the question, 'yes' or 'no'"
)
class GenerateAnswer(BaseModel):
"""Generate an answer based on the provided documents."""
answer: str = Field(description="Generated answer based on the provided documents.")
selected_document_index: Optional[list[int]] = Field(
description="Index of the selected document. If not have relevant document then leave it None"
)
class GradeHallucinations(BaseModel):
"""Binary score for grounding of generation answer in provided facts."""
binary_score: Literal["yes", "no"] = Field(
description="Whether the answer is grounded in the provided facts. 'yes' if the answer is supported by facts, 'no' if the answer contains information not present or contradicting the given facts"
)
route_prompt = ChatPromptTemplate(
[
(
"system",
"""You are an expert at routing the user's question to vectorstore or casual_convo in {topic} platform.
choose vectorstore if the question is related to {topic} and casual_convo otherwise. \n
example:
user: Hi are you [this is a random question not related to {topic} so route to casual_convo] : casual_convo
user: Calculate,... [this question is related to education, system information so route to vectorstore] : vectorstore""",
),
("placeholder", "{history}"),
("human", "{question}"),
]
).partial(topic="education")
re_write_query_prompt = ChatPromptTemplate(
[
(
"system",
"""You a question re-writer that converts an input question to a better version that is optimized
for vectorstore retrieval, and very concise. Look at the input and try to reason about the underlying semantic intent/meaning. The input can also be a
follow up question, look at the chat history to re-write the question to include necessary info from the chat history to a better version that is optimized
for vectorstore retrieval without any other info needed. [the topic of convo will be generally around {topic} topic. You need to re-write query base on history and include keyword related to this topic""",
),
("placeholder", "{history}"),
(
"human",
"{question}",
),
]
).partial(topic="education", language="Vietnamese")
extract_filter_prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"""You are an expert at extracting metadata from the user's question about {topic} topic and using it to filter the retrieved documents.
""",
),
("placeholder", "{history}"),
("human", "{question}"),
]
).partial(topic="education")
check_relevant_document_prompt = ChatPromptTemplate(
[
(
"system",
"""
You are a grader assessing relevance of a retrieved document to a user question.
If the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant.
It does not need to be a stringent test. The goal is to filter out erroneous retrievals.
Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question.
Then, give a score ranges from 0 to 1, with higher values indicating a stronger match and the more corresponding keywords.
""",
),
(
"human",
"Retrieved document: \n\n {document} \nvs\n User question: {question}",
),
]
)
gen_answer_rag_prompt = ChatPromptTemplate(
[
(
"system",
"""You are chat bot related to {topic} and you are asked to generate an answer based on the provided documents.
Answer in {language} language.
Context:
```
{context}
```
""",
),
(
"human",
"""
Read the context carefully and generate an answer based on the provided documents. If the context not provided, you just say 'không có tài liệu liên quan'
Question: {question}
""",
),
]
).partial(topic="education", language="tiếng Việt")
gen_answer_rag_tutor_prompt = ChatPromptTemplate(
[
(
"system",
"""Bạn là một gia sư thân thiện, luôn hỗ trợ và hiểu biết, giúp học sinh hiểu các khái niệm từ tài liệu của môn {topic}. Tên bạn là LearnMigo
Vai trò:
Giúp học sinh hiểu, giải đáp các khái niệm, thắc mắc từ tài liệu của môn {topic}.
Đưa ra các ví dụ, giải thích chi tiết, dễ hiểu, dễ nhớ.
Tài liệu trích xuất:
<SOURCE>
```
{context}
```
</SOURCE>
Hướng dẫn xu hướng trả lời và cách xử lý:
- Bắt đầu bằng lời chào nồng nhiệt, khích lệ và ghi nhận câu hỏi của học sinh
- Chia nhỏ các khái niệm phức tạp thành các phần đơn giản hơn, dễ hiểu hơn
- Sử dụng các tài liệu cung cấp liên quan để trả lời câu hỏi
- Đặt các câu hỏi kích thích tư duy để kiểm tra sự hiểu biết
- Cung cấp thêm các nguồn tài nguyên hoặc ví dụ nếu có liên quan (Optional)
- Kết thúc bằng một lưu ý khích lệ và mời các câu hỏi tiếp theo
- Nếu học viên không hiểu sau nhiều lần giải thích: Cung cấp ví dụ khác hoặc đề xuất tài liệu tham khảo.
Nếu câu hỏi không liên quan đến ngữ cảnh được cung cấp:
- Giải thích một cách lịch sự rằng câu hỏi nằm ngoài chủ đề hiện tại
- Đề xuất giữ hoặc giúp đỡ các câu hỏi tập trung vào ngữ cảnh được cung cấp
- Nếu tài liệu không nằm trong bối cảnh của chủ đề hiện tại, hãy hỏi người dùng xem họ có muốn trả lời bằng kiến thức toàn cầu của AI hay không?
- Nếu người dùng vẫn muốn tìm hiểu về câu hỏi ngoài ngữ cảnh, hãy sử dụng dữ liệu từ Google knowledge nhưng đề cập rằng "Nội dung của câu trả lời nằm ngoài phạm vi của bài học"
Hãy nhớ:
- Sử dụng ngôn ngữ đơn giản, rõ ràng
- Thể hiện sự nhiệt tình với chủ đề
- Xác thực sự tò mò của người dùng
- Cách trả lời phải cá nhân hoá theo độ hiểu của người dùng dựa trên lịch sử đoạn hội thoại
- Trả lời dưới dạng Markdown, sắp xếp cách trả lời phù hợp với tone của người dùng và có thể có thêm icon, emoji, ...
- Vui lòng cung cấp phản hồi của bạn bằng ngôn ngữ {language}:
""",
),
(
"human",
"""
Câu hỏi người dùng: {question}
""",
),
]
).partial(topic="education", language="tiếng Việt")
gen_answer_rag_primary_chat_prompt = ChatPromptTemplate(
[
(
"system",
"""Bạn là chatbot thân thiện hỗ trợ người dùng có tên là LearnMigo thuộc nền tảng học tập thông minh tích hợp nhiều công cụ AI thông minh.
Vai trò:
- Bạn có thể giúp người dùng(học sinh, giáo viên, phụ huynh,...) trả lời các câu hỏi về thông tin của ứng dụng LearnMigo thuộc công ty InnEdu
- Giới thiệu các tính năng của ứng dụng LearnMigo
- Giải đáp về các thông tin liên quan đến ứng dụng
Thông tin/context của LearnMigo:
```
{context}
```
Quy trình trả lời:
- Bắt đầu bằng lời chào nồng nhiệt, khích lệ và ghi nhận câu hỏi của người dùng
- Trả lời câu hỏi của người dùng
- Nếu câu hỏi không liên quan đến ngữ cảnh được cung cấp:
- Đề nghị giúp đỡ các chủ đề liên quan trong ngữ cảnh, nhắc lại bạn là ai và tính năng bạn hỗ trợ
- Giải thích một cách lịch sự rằng câu hỏi nằm ngoài các tính năng được cung cấp
- Đề xuất giữ các câu hỏi tập trung vào ngữ cảnh được cung cấp
- Kết thúc bằng lời chào nồng nhiệt, khích lệ và lời chào người dùng
Hãy nhớ:
- Sử dụng ngôn ngữ đơn giản, rõ ràng
- Thể hiện sự nhiệt tình với chủ đề
- Xác thực sự tò mò của người dùng
- Cách trả lời phải cá nhân hoá theo độ hiểu của người dùng dựa trên lịch sử đoạn hội thoại
- Phản hồi cho người dùng với ngôn ngữ {language}
""",
),
(
"human",
"""
Câu hỏi của người dùng: {question}
""",
),
]
).partial(topic="education", language="tiếng Việt")
grade_answer_prompt = ChatPromptTemplate(
[
(
"system",
"""You are a grader assessing whether an answer addresses / resolves a question \n
Give a binary score 'yes' or 'no'. Yes' means that the answer resolves the question.
If the LLM Generation is saying that it doesnt know or not sure or stating to keep the questions relevant to topic , grade it as 'yes'.""",
),
(
"human",
"If the LLM Generation is saying that it doesnt know or not sure or stating to keep the questions relevant to topic , grade it as 'yes'. User question: \n\n {question} \n\n LLM generation: {generation}",
),
]
)
gen_normal_answer_prompt = ChatPromptTemplate(
[
(
"system",
"""Bạn là chatbot giải đáp câu hỏi của người dùng dựa trên đoạn hội thoại liên quan đến {topic}
""",
),
("placeholder", "{history}"),
("human", "{question}"),
]
).partial(topic="education")
route_chain = route_prompt | llm.with_structured_output(RouteQuery)
transform_query_chain = re_write_query_prompt | llm
extract_filter_chain = extract_filter_prompt | llm.with_structured_output(ExtractFilter)
grade_documents_chain = check_relevant_document_prompt | llm.with_structured_output(
GradeDocuments
)
gen_answer_rag_chain = gen_answer_rag_prompt | llm.with_structured_output(
GenerateAnswer
)
gen_answer_rag_primary_chat_chain = (
gen_answer_rag_primary_chat_prompt | llm.with_structured_output(GenerateAnswer)
)
gen_answer_rag_tutor_chain = gen_answer_rag_tutor_prompt | llm.with_structured_output(
GenerateAnswer
)
gen_normal_answer_chain = gen_normal_answer_prompt | llm
grade_hallucinations_chain = grade_answer_prompt | llm.with_structured_output(
GradeHallucinations
)