class JSONOutputParser(BaseOutputParser):def parse(self, text: str):""" Parse the output of an LLM call to a valid JSON format. """return json.loads(text.replace('```json', '').replace('```', ''), strict=False)
In [19]:
def summarize_article(headline, summary, body, pillar):""" This function takes a headline, a summary, and the content of a news article and it sends a call to Google's Gemini to summarize a article and provide an impact score focusing on a specific pillar of the Rule of Law. """ idx =str(pillar)# Setting up the Prompt Template chat_prompt = ChatPromptTemplate.from_messages([ ("system", pts.context), ("human", pts.instructions) ])# Defining our chain chain_gemini = chat_prompt | ChatGoogleGenerativeAI(model ="gemini-pro", temperature =0.1, safety_settings = safety_settings, convert_system_message_to_human =True) | JSONOutputParser()try: llm_response = chain_gemini.invoke({"headline" : headline,"summary" : summary,"body" : body,"pillar_name" : pts.pillar_names[idx],"pillar_bullets" : pts.pillar_bullets[idx] }) status =True time.sleep(3) # We need to slow down the calls. given that the Gemini API has a limit of 60 calls per second# The API can still block some of our prompts due to undefined reasons. Sadly, we can't do anything about it, so we# predefine the outcome except (BlockedPromptException, StopCandidateException):print("Prompt BLOCKED") status =Falseexcept JSONDecodeError:print("Decode error... trying again...")try: llm_response = chain_gemini.invoke({"headline" : headline,"summary" : summary,"body" : body,"pillar_name" : pts.pillar_names[idx],"pillar_bullets" : pts.pillar_bullets[idx] }) status =True time.sleep(3)except JSONDecodeError:print("Failed. Skipping article.") status =False# We use the STATUS variable to throw an outcome to our call depending if our prompt was blocked or notif status ==True: outcome = [llm_response["summary"], llm_response["impact_score"]]else: outcome ="Skipped article"return outcome