File size: 4,927 Bytes
79e8897 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# %%
# załadowanie bibliotek
import gradio as gr
import pandas as pd
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from pydantic import BaseModel, Field, validator
from pydantic import BaseModel, Field, field_validator
# %%
class QuestionAnswer(BaseModel):
"""
Model reprezentujący pojedyncze pytanie i odpowiedź z analizy ogłoszenia.
Attributes:
question_number (int): Numer kolejny pytania
answer (str): Odpowiedź na pytanie (TAK/NIE)
citation (str): Cytat z tekstu ogłoszenia uzasadniający odpowiedź
"""
question_number: int = Field(..., description="Numer pytania")
answer: str = Field(..., description="Odpowiedź, tylko TAK lub NIE")
citation: str = Field(..., description="Fragment cytatu")
@field_validator("answer")
def validate_answer(cls, v):
if v not in {"TAK", "NIE"}:
raise ValueError("Odpowiedź musi być TAK lub NIE")
return v
class JobAdAnalysis(BaseModel):
"""
Model reprezentujący pełną analizę ogłoszenia o pracę.
Attributes:
answers (list[QuestionAnswer]): Lista odpowiedzi na wszystkie pytania
"""
answers: list[QuestionAnswer]
# %%
# Użycie wbudowanego parsera Pydantic w LangChain:
from langchain.output_parsers import PydanticOutputParser
parser = PydanticOutputParser(pydantic_object=JobAdAnalysis)
# Globalna zmienna do przechowywania mapowania numerów pytań na obszary
question_to_area_map = {}
# %%
# Wczytanie matrycy danych do DataFrame
matryca_df = pd.read_csv('matryca.csv', header=None,
names=['area', 'prompt', 'true', 'false', 'more', 'hint'])
# %%
def prepare_questions(df):
"""
Przygotowuje tekst pytań na podstawie matrycy danych.
Args:
df (pandas.DataFrame): DataFrame zawierający matrycę pytań
Returns:
str: Sformatowany tekst wszystkich pytań
Note:
Funkcja aktualizuje również globalną mapę question_to_area_map
"""
questions_text = ""
# Tworzymy słownik mapujący numer pytania na obszar i inne informacje
global question_to_area_map
question_to_area_map = {}
for index, row in df.iterrows():
question_number = index + 1
questions_text += f"{question_number} {row['prompt']}\n"
# Zapisujemy wszystkie potrzebne informacje
question_to_area_map[question_number] = {
'area': row['area'],
'true': row['true'],
'false': row['false'],
'hint': row['hint'],
'more': row['more']
}
return questions_text
# %%
def analyze_job_ad(job_ad):
"""Analizuje ogłoszenie o pracę przy użyciu LangChain i OpenAI."""
questions = prepare_questions(matryca_df)
prompt_template = PromptTemplate.from_template(
"""Przeanalizuj poniższe ogłoszenie o pracę pod kątem dostępności dla osób z niepełnosprawnościami.
Ogłoszenie:
{job_ad}
Odpowiedz na następujące pytania:
{questions}
Format odpowiedzi powinien być w następującej strukturze JSON:
{{
"answers": [
{{
"question_number": 1,
"answer": "TAK/NIE",
"citation": "dokładny cytat z tekstu"
}}
]
}}
"""
)
model = ChatOpenAI(temperature=0)
chain = prompt_template | model | parser
response = chain.invoke({"job_ad": job_ad, "questions": questions})
output_df = pd.DataFrame(columns=['area', 'answer', 'citation', 'content', 'more'])
for i in range(16):
temp_df = pd.DataFrame()
if response.answers[i].answer == 'TAK':
new_row = {
'area': matryca_df.area[i],
'answer': response.answers[i].answer,
'citation': response.answers[i].citation,
'content': matryca_df.true[i],
'more': matryca_df.more[i]
}
temp_df = pd.DataFrame([new_row])
output_df = pd.concat([output_df, temp_df], ignore_index=True)
elif response.answers[i].answer == 'NIE':
new_row = {
'area': matryca_df.area[i],
'answer': response.answers[i].answer,
'citation': response.answers[i].citation,
'content': matryca_df.false[i],
'more': matryca_df.more[i]
}
temp_df = pd.DataFrame([new_row])
output_df = pd.concat([output_df, temp_df], ignore_index=True)
return output_df.to_json(orient='index')
# %%
# %%
demo=gr.Interface(
fn=analyze_job_ad,
inputs=gr.TextArea(),
outputs=gr.TextArea(show_copy_button=True)
).launch(inbrowser=True)
|