Spaces:
Running
Running
File size: 9,492 Bytes
adbaa04 f8c2ae8 eabbc65 adbaa04 | 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 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>A Lang Graph study - Experimental Setup</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 20px;
}
h1, h2 {
color: #333;
}
h2 {
margin-top: 30px;
}
ul {
list-style-type: disc;
margin-left: 20px;
}
p {
margin-bottom: 15px;
}
table{
border-collapse: collapse;
width: 95%;
border: 2px solid #2c3e50;
}
tr{
border-bottom: 2px solid #b60e0e;
}
td{
width: 15%;
vertical-align: top;
border: 2px solid #3498db;
}
</style>
</head>
<body>
<h1>An experimental setup for working with Lang Graph</h1>
<p>
Continue to read this article if you want to experiment with Lang Graph.
LangGraph is a Python framework designed to build cyclical, state-driven AI applications (often called AI Agents).
</p>
<pre>
ββββββββββββββββββββββββββ
β STATE |
| (The Shared Memory) β
βββββββββββββ¬βββββββββββββ
β
βββββββββββ΄ββββββββββ
βΌ βΌ
βββββββββββββ βββββββββββββ
β NODE β ββββββΊβ EDGE β
β (Actions) β β(Routing/If)
βββββββββββββ βββββββββββββ
</pre>
<h3>Practice time</h3>
<p>
<h3>High Level Understanding</h3>
<ul>
<li>State: Central data object to which every action writes</li>
<li>Node: An actionable function</li>
<li>Edge: Connection between Nodes</li>
</ul>
</p>
<p>
<b>Let's work with a very basic example, not to complicate things, we don't make any external call(no llm calls etc) </b><br>
<pre>
from typing import Annotated, TypedDict
from langchain_core.messages import BaseMessage, HumanMessage
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
# 1. Define the Shared State structure
class State(TypedDict):
value: str
def First_Node(state: State):
print("I am from first Node")
return {"value": "First Node done"}
def Second_Node(state: State):
print("I am from Second Node")
return {"value": "Second Node done"}
workflow = StateGraph(State)
workflow.add_node(First_Node)
workflow.add_node(Second_Node)
workflow.add_edge(START, "First_Node")
workflow.add_edge("First_Node", "Second_Node")
workflow.add_edge("Second_Node", END)
graph = workflow.compile()
final_response = graph.invoke({"value": []})
print(graph.get_graph().draw_mermaid())
print(f"the final value is : {final_response}")
</pre>
Here is the output we get
<pre>
I am from first Node
I am from Second Node
---
config:
flowchart:
curve: linear
---
graph TD;
__start__([<p>__start__</p>]):::first
First_Node(First_Node)
Second_Node(Second_Node)
__end__([<p>__end__</p>]):::last
First_Node --> Second_Node;
__start__ --> First_Node;
Second_Node --> __end__;
classDef default fill:#f2f0ff,line-height:1.2
classDef first fill-opacity:0
classDef last fill:#bfb6fc
the final value is : {'value': 'Second Node done'}
</pre>
</p>
<p>
Going little further into the topic. Use an annotated list to preserve the history
<pre>
class State(TypedDict):
value: str
history: Annotated[list[str], operator.add]
def First_Node(state: State):
print("I am from first Node")
return {"value": "First Node done", "history": ["First Node Activated"]}
def Second_Node(state: State):
print("I am from Second Node")
return {"value": "Second Node done", "history": ["Second Node Activated"]}
...
final_response = graph.invoke({"value": [], "history": ["User initiated session"]})
</pre>
You would see an output like this. <br>
the final value is : {'value': 'Second Node done', 'history': ['User initiated session', 'First Node Activated', 'Second Node Activated']}
Try running the nodes in parallel by trying something like this.<br>
<pre>
workflow.add_edge(START, "Node_A")
workflow.add_edge(START, "Node_B")
</pre>
</p>
<p>
Now, apart from nodes being python functions, we can add variety of things like LCEL (Lang Chain Expression Language), sub graphs etc.
Consider the following:
<pre>
..
model = ChatOpenAI(model="..")
prompt = ChatPromptTemplate.from_template("Summarize this text in one sentence: {input_text}")
lcel_chain = prompt | model | (lambda msg: {"summary": msg.content})
we can pass this as a node to a lang graph.
workflow.add_node("summarizer_node", lcel_chain)
</pre>
Or sometimes, we may need a placeholder node, something like below
<pre>
def DUMMY(state: State):
pass
workflow.add_node(DUMMY)
</pre>
You may also try to pass another workflow graph as subgraph.
</p>
<h3>Detailed article coming soon ..</h3>
<!--
<table >
<tr>
<th>The time telling myth</th>
<th>Why bloom in the evening</th>
<th>What type of pollinators are attracted</th>
</tr>
<tr>
<td>
How Exactly Does the Four OβClock Plant Tell the Time? The four oβclock plant, and many other plants are able to βtell the timeβ because of pigments such as phytochromes that are able to detect the amount of daylight.
</td>
<td>
The four oβclock plant particularly opens at 4 PM to avoid competition with most other flowers, which open in mornings to attract pollinators such as bees.
At 4 PM, these pollinators are less active and nocturnal pollinators like moths, hummingbirds, and butterflies are active instead.
</td>
<td>
Four oβclock plants have a distinct shape, and are attracted by a specific audience of pollinators, more specifically those with long tongues that are able to consume the nectar.
</td>
</tr>
</table>
<h4>Starting your own garden</h4>
<table style="border-collapse: collapse;">
<tr>
<th>Initial Stage</th>
<th>Small plant stage</th>
<th>Intermediate stage</th>
<th>Bloom Time</th>
</tr>
<tr >
<td>
Soaking seeds in water before planting them is helpful and can increase germination rates, since the seeds are typically quite hard.
<img src="images/Four_O_Clock.jpeg" height="200" width="200"/>
</td>
<td>
The plants require regular watering (though overwatering can be detrimental), and in some cases adding mulch around them can be helpful to retain moisture.
<img src="images/Four_O_Clock_Garden.jpeg" height="200" width="200"/>
</td>
<td>
These plants typically bloom in the summer all the way until fall, and thrive in warmer weather.
<img src="images/Mirabilis_Closeup.jpeg" height="200" width="200"/>
</td>
<td>
These plants die in the winter, and come back in the following spring, as the roots underneath the soil stay alive and will push for new growth once temperature increases.
<img src="images/Mirabilis_Full_Circl.jpeg" height="200" width="200"/>
</td>
</tr>
</table>
<h3>Conclusion</h3>
<p>Adding these wonderful environment friendly plants to your garden can be very rewarding experience that offers a sustainable and fulfilling way to connect with nature.
It's a simple yet powerful way to reduce your environmental impact, save money, and enjoy this beautiful colorful plant in your garden.
You can save the seeds, which are produced in abundance and can be shared with friends and family. Start your journey today!</p>
-->
</body>
</html> |