Skip to content

Commit 4e581a9

Browse files
authored
Add example LangChain app. Add Jupyter. Add container dependencies for GraphViz. (#3)
1 parent 4511462 commit 4e581a9

4 files changed

Lines changed: 104 additions & 6 deletions

File tree

Dockerfile

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,18 @@ ENV PYTHONDONTWRITEBYTECODE=1
77
# Turns off buffering for easier container logging
88
ENV PYTHONUNBUFFERED=1
99

10-
# install git
10+
# install system dependencies
1111
RUN apt-get update && apt-get install -y \
12-
git gnupg2 \
12+
git \
13+
gnupg2 \
14+
python3-dev \
15+
graphviz \
16+
graphviz-dev \
17+
pkg-config \
18+
gcc \
19+
libcairo2-dev \
20+
libpango1.0-dev \
21+
libgdk-pixbuf2.0-dev \
1322
&& rm -rf /var/lib/apt/lists/*
1423

1524
# Install pip requirements

README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
Use a VSCode dev container as your virtual Python development environment.
44

5-
## Features
5+
Includes dependencies for LangChain, LangGraph, Juypter Notebook, and PyGraphviz (for visualization).
66

7-
- Dockerized development environment and VSCode devcontainer setup
8-
- Use `pip` to install Python packages
9-
- Set environment variables in `.env` file
7+
Example LangChain and LangGraph code.
8+
9+
Load environment variables via `.env` file.
1010

1111
## Getting Started
1212

@@ -34,3 +34,11 @@ Open up a terminal in VSCode.
3434
Run `env` to verify env vars look good.
3535

3636
`python app.py`
37+
38+
## Running a Jupyter Notebook
39+
40+
In VSCode terminal, run `jupyter notebook --allow-root`. Open up a browser and navigate to the URL shown in terminal. `--allow-root` is fine since Python is running in a dev container.
41+
42+
In browser UI, create a new Python 3 notebook to get started.
43+
44+
If you copy in `app.py` into the notebook, you can run the code in the notebook and also see graphviz visualizations of the workflow.

app.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,86 @@
1+
from typing import TypedDict
2+
3+
from IPython.display import Image, display
14
from langchain.prompts import ChatPromptTemplate
25
from langchain_openai import ChatOpenAI
6+
from langgraph.graph import END, StateGraph
7+
8+
# EXAMPLE LANGCHAIN
9+
print("Example: Create a haiku with LangChain:\n\n")
310

411
llm = ChatOpenAI(temperature=0.9, model="gpt-4o-mini")
512
prompt = ChatPromptTemplate.from_template("Create a haiku from:\n\n{content}")
613
chain = prompt | llm
714

815
response = chain.invoke({"content": "The quick brown fox jumps over the lazy dog."})
916
print(response.content)
17+
18+
# EXAMPLE LANGGRAPH
19+
print(
20+
"\n\nExample: Determine if prompt is discussing colors or not with LangGraph:\n\n"
21+
)
22+
23+
24+
# Define the state of our graph
25+
class State(TypedDict):
26+
prompt: str
27+
is_color: bool
28+
result: str
29+
30+
31+
# Define our nodes
32+
def ask_for_prompt(state: State) -> State:
33+
prompt = input("Please enter a prompt to indentify if it mentions a color or not: ")
34+
return {"prompt": prompt, "is_color": False, "result": ""}
35+
36+
37+
def evaluate_prompt(state: State) -> State:
38+
prompt = state["prompt"]
39+
is_color = False
40+
41+
llm = ChatOpenAI()
42+
prompt = ChatPromptTemplate.from_template(
43+
"Evaluate if this prompt discusses colors: '{prompt}'. Respond with 'Yes' or 'No'."
44+
)
45+
response = llm.invoke(prompt.format_prompt(prompt=state["prompt"]))
46+
if isinstance(response.content, str):
47+
is_color = response.content.strip().lower() == "yes"
48+
return {**state, "is_color": is_color}
49+
50+
51+
def show_result(state: State) -> State:
52+
if state["is_color"]:
53+
result = f"The prompt '{state['prompt']}' contains a color!"
54+
else:
55+
result = f"The prompt '{state['prompt']}' does not contain a color."
56+
print(result)
57+
return {**state, "result": result}
58+
59+
60+
# Create the graph
61+
workflow = StateGraph(State)
62+
63+
# Add nodes
64+
workflow.add_node("ask_prompt", ask_for_prompt)
65+
workflow.add_node("evaluate", evaluate_prompt)
66+
workflow.add_node("show_result", show_result)
67+
68+
# Add edges
69+
workflow.add_edge("ask_prompt", "evaluate")
70+
workflow.add_edge("evaluate", "show_result")
71+
workflow.add_edge("show_result", END)
72+
73+
# Set entry point
74+
workflow.set_entry_point("ask_prompt")
75+
76+
# Compile the graph
77+
app = workflow.compile()
78+
79+
display(Image(app.get_graph().draw_png())) # type: ignore
80+
81+
# Run the graph
82+
for output in app.stream({"prompt": "", "is_color": False, "result": ""}):
83+
pass
84+
85+
# Example usage:
86+
# This will run until a color is mentioned in the prompt

requirements.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
langchain==0.2.14
22
langchain-openai==0.1.22
33
langchain-community==0.2.12
4+
langgraph==0.2.16
45
faiss-cpu==1.8.0.post1
6+
jupyter==1.1.1
7+
pygraphviz==1.13
8+

0 commit comments

Comments
 (0)