feat: add new examples from pocketflow-academy
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
# PocketFlow Summarize
|
||||
|
||||
A practical example demonstrating how to use PocketFlow to build a robust text summarization tool with error handling and retries. This example showcases core PocketFlow concepts in a real-world application.
|
||||
|
||||
## Features
|
||||
|
||||
- Text summarization using LLMs (Large Language Models)
|
||||
- Automatic retry mechanism (up to 3 attempts) on API failures
|
||||
- Graceful error handling with fallback responses
|
||||
- Clean separation of concerns using PocketFlow's Node architecture
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
.
|
||||
├── docs/ # Documentation files
|
||||
├── utils/ # Utility functions (LLM API wrapper)
|
||||
├── flow.py # PocketFlow implementation with Summarize Node
|
||||
├── main.py # Main application entry point
|
||||
└── README.md # Project documentation
|
||||
```
|
||||
|
||||
## Implementation Details
|
||||
|
||||
The example implements a simple but robust text summarization workflow:
|
||||
|
||||
1. **Summarize Node** (`flow.py`):
|
||||
- `prep()`: Retrieves text from the shared store
|
||||
- `exec()`: Calls LLM to summarize text in 10 words
|
||||
- `exec_fallback()`: Provides graceful error handling
|
||||
- `post()`: Stores the summary back in shared store
|
||||
|
||||
2. **Flow Structure**:
|
||||
- Single node flow for demonstration
|
||||
- Configured with 3 retries for reliability
|
||||
- Uses shared store for data passing
|
||||
|
||||
## Setup
|
||||
|
||||
1. Create a virtual environment:
|
||||
```bash
|
||||
python -m venv venv
|
||||
source venv/bin/activate # On Windows: venv\Scripts\activate
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
3. Configure your environment:
|
||||
- Set up your LLM API key (check utils/call_llm.py for configuration)
|
||||
|
||||
4. Run the example:
|
||||
```bash
|
||||
python main.py
|
||||
```
|
||||
|
||||
## Example Usage
|
||||
|
||||
The example comes with a sample text about PocketFlow, but you can modify `main.py` to summarize your own text:
|
||||
|
||||
```python
|
||||
shared = {"data": "Your text to summarize here..."}
|
||||
flow.run(shared)
|
||||
print("Summary:", shared["summary"])
|
||||
```
|
||||
|
||||
## What You'll Learn
|
||||
|
||||
This example demonstrates several key PocketFlow concepts:
|
||||
|
||||
- **Node Architecture**: How to structure LLM tasks using prep/exec/post pattern
|
||||
- **Error Handling**: Implementing retry mechanisms and fallbacks
|
||||
- **Shared Store**: Using shared storage for data flow between steps
|
||||
- **Flow Creation**: Setting up a basic PocketFlow workflow
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [PocketFlow Documentation](https://the-pocket.github.io/PocketFlow/)
|
||||
- [Node Concept Guide](https://the-pocket.github.io/PocketFlow/node.html)
|
||||
- [Flow Design Patterns](https://the-pocket.github.io/PocketFlow/flow.html)
|
||||
@@ -0,0 +1,28 @@
|
||||
from pocketflow import Node, Flow
|
||||
from utils.call_llm import call_llm
|
||||
|
||||
class Summarize(Node):
|
||||
def prep(self, shared):
|
||||
"""Read and preprocess data from shared store."""
|
||||
return shared["data"]
|
||||
|
||||
def exec(self, prep_res):
|
||||
"""Execute the summarization using LLM."""
|
||||
if not prep_res:
|
||||
return "Empty text"
|
||||
prompt = f"Summarize this text in 10 words: {prep_res}"
|
||||
summary = call_llm(prompt) # might fail
|
||||
return summary
|
||||
|
||||
def exec_fallback(self, shared, prep_res, exc):
|
||||
"""Provide a simple fallback instead of crashing."""
|
||||
return "There was an error processing your request."
|
||||
|
||||
def post(self, shared, prep_res, exec_res):
|
||||
"""Store the summary in shared store."""
|
||||
shared["summary"] = exec_res
|
||||
# Return "default" by not returning
|
||||
|
||||
# Create the flow
|
||||
summarize_node = Summarize(max_retries=3)
|
||||
flow = Flow(start=summarize_node)
|
||||
@@ -0,0 +1,23 @@
|
||||
from flow import flow
|
||||
|
||||
def main():
|
||||
# Example text to summarize
|
||||
text = """
|
||||
PocketFlow is a minimalist LLM framework that models workflows as a Nested Directed Graph.
|
||||
Nodes handle simple LLM tasks, connecting through Actions for Agents.
|
||||
Flows orchestrate these nodes for Task Decomposition, and can be nested.
|
||||
It also supports Batch processing and Async execution.
|
||||
"""
|
||||
|
||||
# Initialize shared store
|
||||
shared = {"data": text}
|
||||
|
||||
# Run the flow
|
||||
flow.run(shared)
|
||||
|
||||
# Print result
|
||||
print("\nInput text:", text)
|
||||
print("\nSummary:", shared["summary"])
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,2 @@
|
||||
pocketflow
|
||||
openai>=1.0.0
|
||||
@@ -0,0 +1,13 @@
|
||||
from openai import OpenAI
|
||||
|
||||
def call_llm(prompt):
|
||||
client = OpenAI(api_key="YOUR_API_KEY_HERE")
|
||||
r = client.chat.completions.create(
|
||||
model="gpt-4o",
|
||||
messages=[{"role": "user", "content": prompt}]
|
||||
)
|
||||
return r.choices[0].message.content
|
||||
|
||||
if __name__ == "__main__":
|
||||
prompt = "What is the meaning of life?"
|
||||
print(call_llm(prompt))
|
||||
Reference in New Issue
Block a user