Introduction
On this tutorial, we’ll construct a sophisticated AI-powered information agent that may search the online for the most recent information on a given subject and summarize the outcomes. This agent follows a structured workflow:
- Searching: Generate related search queries and gather info from the online.
- Writing: Extracts and compiles information summaries from the collected info.
- Reflection: Critiques the summaries by checking for factual correctness and suggests enhancements.
- Refinement: Improves the summaries based mostly on the critique.
- Headline Era: Generates acceptable headlines for every information abstract.
To reinforce usability, we will even create a easy GUI utilizing Streamlit. Just like earlier tutorials, we’ll use Groq for LLM-based processing and Tavily for net shopping. You possibly can generate free API keys from their respective web sites.
Setting Up the Setting
We start by establishing setting variables, putting in the required libraries, and importing mandatory dependencies:
Set up Required Libraries
pip set up langgraph==0.2.53 langgraph-checkpoint==2.0.6 langgraph-sdk==0.1.36 langchain-groq langchain-community langgraph-checkpoint-sqlite==2.0.1 tavily-python streamlit
Import Libraries and Set API Keys
import os
import sqlite3
from langgraph.graph import StateGraph
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_groq import ChatGroq
from tavily import TavilyClient
from langgraph.checkpoint.sqlite import SqliteSaver
from typing import TypedDict, Record
from pydantic import BaseModel
import streamlit as st
# Set API Keys
os.environ['TAVILY_API_KEY'] = "your_tavily_key"
os.environ['GROQ_API_KEY'] = "your_groq_key"
# Initialize Database for Checkpointing
sqlite_conn = sqlite3.join("checkpoints.sqlite", check_same_thread=False)
reminiscence = SqliteSaver(sqlite_conn)
# Initialize Mannequin and Tavily Consumer
mannequin = ChatGroq(mannequin="Llama-3.1-8b-instant")
tavily = TavilyClient(api_key=os.environ["TAVILY_API_KEY"])
Defining the Agent State
The agent maintains state info all through its workflow:
- Subject: The subject on which consumer needs the most recent information Drafts: The primary drafts of the information summaries
- Content material: The analysis content material extracted from the search outcomes of the Tavily
- Critique: The critique and proposals generated for the draft within the reflection state.
- Refined Summaries: Up to date information summaries after incorporating suggesstions from Critique
Headings: Headlines generated for every information article class
class AgentState(TypedDict):
subject: str
drafts: Record[str]
content material: Record[str]
critiques: Record[str]
refined_summaries: Record[str]
headings: Record[str]
Defining Prompts
We outline system prompts for every section of the agent’s workflow:
BROWSING_PROMPT = """You're an AI information researcher tasked with discovering the most recent information articles on given subjects. Generate as much as 3 related search queries."""
WRITER_PROMPT = """You're an AI information summarizer. Write an in depth abstract (1 to 2 paragraphs) based mostly on the given content material, making certain factual correctness, readability, and coherence."""
CRITIQUE_PROMPT = """You're a instructor reviewing draft summaries in opposition to the supply content material. Guarantee factual correctness, determine lacking or incorrect particulars, and counsel enhancements.
----------
Content material: {content material}
----------"""
REFINE_PROMPT = """You're an AI information editor. Given a abstract and critique, refine the abstract accordingly.
-----------
Abstract: {abstract}"""
HEADING_GENERATION_PROMPT = """You're an AI information summarizer. Generate a brief, descriptive headline for every information abstract."""
Structuring Queries and Information
We use Pydantic to outline the construction of queries and Information articles. Pydantic permits us to outline the construction of the output of the LLM. That is essential as a result of we wish the queries to be a listing of string and the extracted content material from net could have a number of information articles, therefore a listing of strings.
from pydantic import BaseModel
class Queries(BaseModel):
queries: Record[str]
class Information(BaseModel):
information: Record[str]
Implementing the AI Brokers
1. Searching Node
This node generates search queries and retrieves related content material from the online.
def browsing_node(state: AgentState):
queries = mannequin.with_structured_output(Queries).invoke([
SystemMessage(content=BROWSING_PROMPT),
HumanMessage(content=state['topic'])
])
content material = state.get('content material', [])
for q in queries.queries:
response = tavily.search(question=q, max_results=2)
for r in response['results']:
content material.append(r['content'])
return {"content material": content material}
2. Writing Node
Extracts information summaries from the retrieved content material.
def writing_node(state: AgentState):
content material = "nn".be part of(state['content'])
information = mannequin.with_structured_output(Information).invoke([
SystemMessage(content=WRITER_PROMPT),
HumanMessage(content=content)
])
return {"drafts": information.information}
3. Reflection Node
Critiques the generated summaries in opposition to the content material.
def reflection_node(state: AgentState):
content material = "nn".be part of(state['content'])
critiques = []
for draft in state['drafts']:
response = mannequin.invoke([
SystemMessage(content=CRITIQUE_PROMPT.format(content=content)),
HumanMessage(content="draft: " + draft)
])
critiques.append(response.content material)
return {"critiques": critiques}
4. Refinement Node
Improves the summaries based mostly on critique.
def refine_node(state: AgentState):
refined_summaries = []
for abstract, critique in zip(state['drafts'], state['critiques']):
response = mannequin.invoke([
SystemMessage(content=REFINE_PROMPT.format(summary=summary)),
HumanMessage(content="Critique: " + critique)
])
refined_summaries.append(response.content material)
return {"refined_summaries": refined_summaries}
5. Headlines Era Node
Generates a brief headline for every information abstract.
def heading_node(state: AgentState):
headings = []
for abstract in state['refined_summaries']:
response = mannequin.invoke([
SystemMessage(content=HEADING_GENERATION_PROMPT),
HumanMessage(content=summary)
])
headings.append(response.content material)
return {"headings": headings}
Constructing the UI with Streamlit
# Outline Streamlit app
st.title("Information Summarization Chatbot")
# Initialize session state
if "messages" not in st.session_state:
st.session_state["messages"] = []
# Show previous messages
for message in st.session_state["messages"]:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# Enter area for consumer
user_input = st.chat_input("Ask concerning the newest information...")
thread = 1
if user_input:
st.session_state["messages"].append({"position": "consumer", "content material": user_input})
with st.chat_message("assistant"):
loading_text = st.empty()
loading_text.markdown("*Considering...*")
builder = StateGraph(AgentState)
builder.add_node("browser", browsing_node)
builder.add_node("author", writing_node)
builder.add_node("replicate", reflection_node)
builder.add_node("refine", refine_node)
builder.add_node("heading", heading_node)
builder.set_entry_point("browser")
builder.add_edge("browser", "author")
builder.add_edge("author", "replicate")
builder.add_edge("replicate", "refine")
builder.add_edge("refine", "heading")
graph = builder.compile(checkpointer=reminiscence)
config = {"configurable": {"thread_id": f"{thread}"}}
for s in graph.stream({"subject": user_input}, config):
# loading_text.markdown(f"*{st.session_state['loading_message']}*")
print(s)
s = graph.get_state(config).values
refined_summaries = s['refined_summaries']
headings = s['headings']
thread+=1
# Show closing response
loading_text.empty()
response_text = "nn".be part of([f"{h}n{s}" for h, s in zip(headings, refined_summaries)])
st.markdown(response_text)
st.session_state["messages"].append({"position": "assistant", "content material": response_text})
Conclusion
This tutorial lined your entire strategy of constructing an AI-powered information summarization agent with a easy Streamlit UI. Now you possibly can mess around with this and make some additional enhancements like:
- A higher GUI for enhanced consumer interplay.
- Incorporating Iterative refinement to ensure the summaries are correct and acceptable.
- Sustaining a context to proceed dialog about specific information.
Joyful coding!
Additionally, be at liberty to observe us on Twitter and don’t neglect to hitch our 75k+ ML SubReddit.
Vineet Kumar is a consulting intern at MarktechPost. He’s at present pursuing his BS from the Indian Institute of Know-how(IIT), Kanpur. He’s a Machine Studying fanatic. He’s captivated with analysis and the most recent developments in Deep Studying, Laptop Imaginative and prescient, and associated fields.