This repository contains my implementations and experiments while learning LangChain and LLM application development.
The project is based on concepts covered during a LangChain course, but the implementations have been independently modified and extended to experiment with different models, prompt workflows, integrations, and LangChain concepts.
The repository is being developed incrementally, with additional LangChain experiments, RAG implementations, and LLM applications planned for future branches.
The current main branch contains a prompt-template-based summarization application implemented using LangChain.
The application takes structured information about a person, inserts it into a reusable prompt template, and sends the resulting prompt to an LLM.
The prompt asks the model to generate:
- A short summary
- Two interesting facts
- A creative title
- A fictional interview question and answer
Information
│
▼
PromptTemplate
│
▼
LLM
│
▼
Generated Response
The current implementation explores the same prompt-template workflow using different LLM approaches.
The project includes an implementation using Google's Gemini API.
Model: Gemini: 2.5 flash
The Gemini client is initialized using an API key loaded from environment variables:
load_dotenv()
api_key = os.getenv("GEMINI_API_KEY")
client = genai.Client(api_key=api_key)The application demonstates both direct Gemini invocation without LCEL and a LangChain-based LCEL implementation.
In the non-LCEL approach, the prompt is formatted first and then passed directly to the Gemini API.
prompt_text = summary_prompt_template.format(
information=information
)
response = client.models.generate_content(
model="models/gemini-2.5-flash",
contents=prompt_text
)The flow is:
Information
│
▼
PromptTemplate.format()
│
▼
Formatted Prompt
│
▼
Gemini API
│
▼
Response
This approach keeps prompt creation and model invocation as separate steps.
The project also includes a local LLM implementation using Ollama with Google's Gemma model.
The LangChain integration uses:
from langchain_ollama import ChatOllamaThe model is initialized with:
llm = ChatOllama(
model="gemma3:270m",
temperature=0
)The prompt template is connected to the local model using LCEL:
chain = summary_prompt_template | llm
response = chain.invoke({
"information": information
})The flow is:
Information
│
▼
PromptTemplate
│
▼
Gemma 3 via Ollama
│
▼
Generated Response
This allows the same prompt-template workflow to be tested with a locally running LLM, without sending the inference request to Gemini.
One of the goals of this implementation is to understand the difference between direct invocation and LCEL-based composition.
The components are composed into a reusable chain:
chain = summary_prompt_template | llmand invoked using:
response = chain.invoke({
"information": information
})The resulting pipeline is:
Information
│
▼
PromptTemplate
│
▼
LLM
│
▼
Response
LCEL provides a more declarative, composable, and reusable way of connecting LangChain components.
- Python
- LangChain
- Google Gemini API
- Ollama
- Gemma
- LangChain Core
- LangChain Ollama
- LCEL
- python-dotenv
| Implementation | Model | Execution | API Required |
|---|---|---|---|
| Gemini without LCEL | Gemini | Direct API invocation | Gemini API |
| Gemini with LCEL | Gemini | LangChain + LCEL | Gemini API |
| Ollama + Gemma | Gemma | Local inference + LCEL | Local Ollama |
The implementations allow the same prompt-template workflow to be experimented with using both cloud-based and locally hosted LLMs.
Gemini Output
Ollama instance
Ollama GUI
Ollama + Gemma Output
The Gemini API key is loaded from a local .env file:
GEMINI_API_KEY=your_api_key_here :{The .env file should not be committed to the repository.
Recommended .gitignore entries:
.env
.venv/
__pycache__/
*.pycThis repository will be expanded with additional experiments and implementations.
Planned areas include:
- Retrieval-Augmented Generation (RAG)
- Embeddings
- Vector stores
- Retrievers
- Pinecone
- LCEL-based RAG pipelines
- Tool calling
- Agents
- Additional LLM providers
- Local and cloud-based models
Future implementations will be added through additional branches as the project evolves.