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>