dspygraph


Namedspygraph JSON
Version 0.1.0 PyPI version JSON
download
home_pageNone
SummaryA lightweight framework for building graph-based workflows with DSPy nodes
upload_time2025-07-11 18:30:04
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
licenseMIT License Copyright (c) 2025 Joel Grus Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords ai dspy graph language-models llm machine-learning workflow
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # DSPy Graph Framework

A lightweight framework for building graph-based workflows with DSPy nodes. Combine DSPy's powerful language model programming with flexible graph execution, conditional routing, and state management.

## Installation

```bash
pip install dspygraph
```

## Quick Start

```python
import dspy
from dspygraph import Node, Graph, START, END

# Configure DSPy
lm = dspy.LM("openai/gpt-4o-mini")
dspy.configure(lm=lm)

# Create a simple node
class QuestionAnswerNode(Node):
    def _create_module(self):
        return dspy.ChainOfThought("question -> answer")
    
    def process(self, state):
        result = self.module(question=state["question"])
        return {"answer": result.answer}

# Create and run a graph
graph = Graph("MyGraph")
graph.add_node(QuestionAnswerNode("qa"))
graph.add_edge(START, "qa")
graph.add_edge("qa", END)

result = graph.run(question="What is the capital of France?")
print(result["answer"])
```

## Core Concepts

### Node
The base class for all graph nodes. Extend it to create custom DSPy-powered components:

```python
class MyNode(Node):
    def _create_module(self):
        # Return any DSPy module
        return dspy.ChainOfThought("input -> output")
    
    def process(self, state):
        # Process the state and return updates
        result = self.module(input=state["input"])
        return {"output": result.output}
```

### Graph
The execution engine that manages nodes and their connections:

```python
graph = Graph("MyGraph")
graph.add_node(my_node)
graph.add_edge(START, "my_node")
graph.add_edge("my_node", END)

# Conditional routing
graph.add_conditional_edges(
    "classifier",
    {"route_a": "node_a", "route_b": "node_b"},
    lambda state: "route_a" if state["condition"] else "route_b"
)
```

## Features

- **🔗 Graph-based execution**: Build complex workflows with conditional routing and cycles
- **🤖 DSPy integration**: Seamlessly integrate with DSPy's language model programming
- **🔄 State management**: Automatic state passing between nodes with full observability
- **⚡ Flexible routing**: Support for conditional edges and dynamic graph execution
- **🛡️ Error handling**: Built-in protection against infinite loops and execution failures
- **📊 Observability**: Complete execution tracking with timing, token usage, and metadata

## Example Applications

This repository includes complete example applications that demonstrate the framework's capabilities:

### 1. Question Classifier System
An intelligent agent that:
- **Classifies** incoming questions into categories (factual, creative, tool-use, or unknown)
- **Routes** each question to the most appropriate specialized response module  
- **Generates** tailored responses using different reasoning patterns for each category

### 2. ReAct Agent
A reasoning and acting agent that:
- Uses iterative reasoning with tool execution
- Demonstrates graph-based loops and state management
- Includes calculator and search tools

## Key Features

### Clean Architecture
- **Reusable Framework**: dspygraph/ provides a base Node class that can be used for any DSPy project
- **Application-Specific Code**: question_classifier_app/ contains the specific implementations for this question-answering system
- **Clear Separation**: Framework concerns are separated from application logic

### Intelligent Routing
- Uses DSPy's compilation system to optimize question classification
- Conditional routing based on question type
- Specialized response modules for different reasoning patterns

### Production-Ready
- Compiled models for optimized performance
- Proper error handling and validation
- Type safety with comprehensive type annotations
- Clean compilation API with explicit paths

## Quick Start

### Prerequisites
- Python 3.11+
- OpenAI API key (set as environment variable)

### Installation
```bash
# Clone and navigate to the project
git clone <repository-url>
cd dspygraph

# Install dependencies
uv sync
```

### Running the Examples

#### Simple Example (Quick Start)
```bash
# Run the basic example (no compilation needed)
python simple_example.py
```

This shows basic DSPy graph integration with a single agent that answers questions.

#### Question Classifier App (Advanced Example)
```bash
# 1. Compile the classifier (required first time)
python -m examples.question_classifier_app.compile_classifier

# 2. Run the main application
python -m examples.question_classifier_app.main
```

This demonstrates an intelligent routing system that classifies questions and routes them to specialized response modules.

#### React Agent (Tool Integration Example)
```bash
# Run the React agent (no compilation needed)
python -m examples.react_agent.main

# Or run the demonstration
python -m examples.react_agent.graph
```

This showcases a ReAct (Reasoning + Acting) agent that uses iterative reasoning with tool execution, demonstrating graph-based loops and state management.

## How It Works

### Architecture Overview

```
User Question -> QuestionClassifier -> Router -> Specialized Module -> Response
```

1. **Question Classification**: DSPy module analyzes the question and assigns a category
2. **Intelligent Routing**: Graph routes to the appropriate response module
3. **Specialized Processing**: Each module uses different reasoning patterns:
   - **Factual**: Chain-of-thought reasoning for factual questions
   - **Creative**: Optimized for creative content generation
   - **Tool Use**: ReAct pattern for computational tasks
4. **Response Generation**: Tailored response based on question type

### Framework Design

The project showcases a reusable pattern for DSPy + Graph integration:

- **Node**: Base class that unifies DSPy modules with graph nodes
- **Clean Interfaces**: Each node implements both DSPy module creation and graph state processing
- **Compilation Support**: Built-in support for DSPy's optimization system

### Compilation API

The framework provides a clean API for compiling agents:

```python
# Create agent and compiler
agent = QuestionClassifier()
compiler = BootstrapFewShot(metric=classification_metric)
trainset = get_training_data()

# Compile with optional save path
agent.compile(compiler, trainset, compile_path="my_model.json")

# Load compiled model
agent.load_compiled("my_model.json")

# Save compiled model
agent.save_compiled("my_model.json")
```

## Extending the System

### Adding New Question Types
1. Create a new agent in question_classifier_app/agents/
2. Add the new category to QuestionCategory type
3. Update training data and routing logic
4. Recompile the classifier

### Creating New Applications
The dspygraph/ framework can be reused for entirely different applications:

```python
from dspygraph import Node, configure_dspy

class MyCustomAgent(Node):
    def _create_module(self):
        return dspy.ChainOfThought("input -> output")
    
    def _process_state(self, state):
        # Your custom logic here
        return {"result": "processed"}
```

## Technical Details

### Dependencies
- **DSPy**: Language model programming framework
- **Graph Engine**: State graph framework for complex workflows
- **OpenAI**: Language model provider

### Project Structure
```
dspygraph/                         # Reusable framework
├── base.py                        # Node base class
├── config.py                      # DSPy configuration
└── constants.py                   # Framework constants

examples/                          # Example applications
├── question_classifier_app/       # Question classifier example
│   ├── main.py                    # Main application entry point
│   ├── compile_classifier.py      # Compilation script
│   ├── graph.py                   # Graph workflow definition
│   ├── nodes.py                   # Node implementations
│   └── types.py                   # Application types
└── react_agent/                   # React agent with tools example
    ├── main.py                    # Interactive React agent
    ├── graph.py                   # Graph workflow with reasoning loops
    ├── nodes.py                   # React agent and tool executor nodes
    ├── tools.py                   # Calculator and search tools
    └── types.py                   # State and result types

simple_example.py                  # Basic framework demo
```

## Contributing

This project demonstrates patterns for:
- Clean architecture in AI systems
- DSPy best practices
- Graph integration
- Type-safe Python development

Feel free to use this as a template for your own DSPy + Graph projects!

## License

[Add your license here]
            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "dspygraph",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": "Joel Grus <joel@joelgrus.com>",
    "keywords": "ai, dspy, graph, language-models, llm, machine-learning, workflow",
    "author": null,
    "author_email": "Joel Grus <joel@joelgrus.com>",
    "download_url": "https://files.pythonhosted.org/packages/70/bb/ad4df292c4a72eebafeb083fa504e0ee3b5f464672eec50ccbc50c8f5818/dspygraph-0.1.0.tar.gz",
    "platform": null,
    "description": "# DSPy Graph Framework\n\nA lightweight framework for building graph-based workflows with DSPy nodes. Combine DSPy's powerful language model programming with flexible graph execution, conditional routing, and state management.\n\n## Installation\n\n```bash\npip install dspygraph\n```\n\n## Quick Start\n\n```python\nimport dspy\nfrom dspygraph import Node, Graph, START, END\n\n# Configure DSPy\nlm = dspy.LM(\"openai/gpt-4o-mini\")\ndspy.configure(lm=lm)\n\n# Create a simple node\nclass QuestionAnswerNode(Node):\n    def _create_module(self):\n        return dspy.ChainOfThought(\"question -> answer\")\n    \n    def process(self, state):\n        result = self.module(question=state[\"question\"])\n        return {\"answer\": result.answer}\n\n# Create and run a graph\ngraph = Graph(\"MyGraph\")\ngraph.add_node(QuestionAnswerNode(\"qa\"))\ngraph.add_edge(START, \"qa\")\ngraph.add_edge(\"qa\", END)\n\nresult = graph.run(question=\"What is the capital of France?\")\nprint(result[\"answer\"])\n```\n\n## Core Concepts\n\n### Node\nThe base class for all graph nodes. Extend it to create custom DSPy-powered components:\n\n```python\nclass MyNode(Node):\n    def _create_module(self):\n        # Return any DSPy module\n        return dspy.ChainOfThought(\"input -> output\")\n    \n    def process(self, state):\n        # Process the state and return updates\n        result = self.module(input=state[\"input\"])\n        return {\"output\": result.output}\n```\n\n### Graph\nThe execution engine that manages nodes and their connections:\n\n```python\ngraph = Graph(\"MyGraph\")\ngraph.add_node(my_node)\ngraph.add_edge(START, \"my_node\")\ngraph.add_edge(\"my_node\", END)\n\n# Conditional routing\ngraph.add_conditional_edges(\n    \"classifier\",\n    {\"route_a\": \"node_a\", \"route_b\": \"node_b\"},\n    lambda state: \"route_a\" if state[\"condition\"] else \"route_b\"\n)\n```\n\n## Features\n\n- **\ud83d\udd17 Graph-based execution**: Build complex workflows with conditional routing and cycles\n- **\ud83e\udd16 DSPy integration**: Seamlessly integrate with DSPy's language model programming\n- **\ud83d\udd04 State management**: Automatic state passing between nodes with full observability\n- **\u26a1 Flexible routing**: Support for conditional edges and dynamic graph execution\n- **\ud83d\udee1\ufe0f Error handling**: Built-in protection against infinite loops and execution failures\n- **\ud83d\udcca Observability**: Complete execution tracking with timing, token usage, and metadata\n\n## Example Applications\n\nThis repository includes complete example applications that demonstrate the framework's capabilities:\n\n### 1. Question Classifier System\nAn intelligent agent that:\n- **Classifies** incoming questions into categories (factual, creative, tool-use, or unknown)\n- **Routes** each question to the most appropriate specialized response module  \n- **Generates** tailored responses using different reasoning patterns for each category\n\n### 2. ReAct Agent\nA reasoning and acting agent that:\n- Uses iterative reasoning with tool execution\n- Demonstrates graph-based loops and state management\n- Includes calculator and search tools\n\n## Key Features\n\n### Clean Architecture\n- **Reusable Framework**: dspygraph/ provides a base Node class that can be used for any DSPy project\n- **Application-Specific Code**: question_classifier_app/ contains the specific implementations for this question-answering system\n- **Clear Separation**: Framework concerns are separated from application logic\n\n### Intelligent Routing\n- Uses DSPy's compilation system to optimize question classification\n- Conditional routing based on question type\n- Specialized response modules for different reasoning patterns\n\n### Production-Ready\n- Compiled models for optimized performance\n- Proper error handling and validation\n- Type safety with comprehensive type annotations\n- Clean compilation API with explicit paths\n\n## Quick Start\n\n### Prerequisites\n- Python 3.11+\n- OpenAI API key (set as environment variable)\n\n### Installation\n```bash\n# Clone and navigate to the project\ngit clone <repository-url>\ncd dspygraph\n\n# Install dependencies\nuv sync\n```\n\n### Running the Examples\n\n#### Simple Example (Quick Start)\n```bash\n# Run the basic example (no compilation needed)\npython simple_example.py\n```\n\nThis shows basic DSPy graph integration with a single agent that answers questions.\n\n#### Question Classifier App (Advanced Example)\n```bash\n# 1. Compile the classifier (required first time)\npython -m examples.question_classifier_app.compile_classifier\n\n# 2. Run the main application\npython -m examples.question_classifier_app.main\n```\n\nThis demonstrates an intelligent routing system that classifies questions and routes them to specialized response modules.\n\n#### React Agent (Tool Integration Example)\n```bash\n# Run the React agent (no compilation needed)\npython -m examples.react_agent.main\n\n# Or run the demonstration\npython -m examples.react_agent.graph\n```\n\nThis showcases a ReAct (Reasoning + Acting) agent that uses iterative reasoning with tool execution, demonstrating graph-based loops and state management.\n\n## How It Works\n\n### Architecture Overview\n\n```\nUser Question -> QuestionClassifier -> Router -> Specialized Module -> Response\n```\n\n1. **Question Classification**: DSPy module analyzes the question and assigns a category\n2. **Intelligent Routing**: Graph routes to the appropriate response module\n3. **Specialized Processing**: Each module uses different reasoning patterns:\n   - **Factual**: Chain-of-thought reasoning for factual questions\n   - **Creative**: Optimized for creative content generation\n   - **Tool Use**: ReAct pattern for computational tasks\n4. **Response Generation**: Tailored response based on question type\n\n### Framework Design\n\nThe project showcases a reusable pattern for DSPy + Graph integration:\n\n- **Node**: Base class that unifies DSPy modules with graph nodes\n- **Clean Interfaces**: Each node implements both DSPy module creation and graph state processing\n- **Compilation Support**: Built-in support for DSPy's optimization system\n\n### Compilation API\n\nThe framework provides a clean API for compiling agents:\n\n```python\n# Create agent and compiler\nagent = QuestionClassifier()\ncompiler = BootstrapFewShot(metric=classification_metric)\ntrainset = get_training_data()\n\n# Compile with optional save path\nagent.compile(compiler, trainset, compile_path=\"my_model.json\")\n\n# Load compiled model\nagent.load_compiled(\"my_model.json\")\n\n# Save compiled model\nagent.save_compiled(\"my_model.json\")\n```\n\n## Extending the System\n\n### Adding New Question Types\n1. Create a new agent in question_classifier_app/agents/\n2. Add the new category to QuestionCategory type\n3. Update training data and routing logic\n4. Recompile the classifier\n\n### Creating New Applications\nThe dspygraph/ framework can be reused for entirely different applications:\n\n```python\nfrom dspygraph import Node, configure_dspy\n\nclass MyCustomAgent(Node):\n    def _create_module(self):\n        return dspy.ChainOfThought(\"input -> output\")\n    \n    def _process_state(self, state):\n        # Your custom logic here\n        return {\"result\": \"processed\"}\n```\n\n## Technical Details\n\n### Dependencies\n- **DSPy**: Language model programming framework\n- **Graph Engine**: State graph framework for complex workflows\n- **OpenAI**: Language model provider\n\n### Project Structure\n```\ndspygraph/                         # Reusable framework\n\u251c\u2500\u2500 base.py                        # Node base class\n\u251c\u2500\u2500 config.py                      # DSPy configuration\n\u2514\u2500\u2500 constants.py                   # Framework constants\n\nexamples/                          # Example applications\n\u251c\u2500\u2500 question_classifier_app/       # Question classifier example\n\u2502   \u251c\u2500\u2500 main.py                    # Main application entry point\n\u2502   \u251c\u2500\u2500 compile_classifier.py      # Compilation script\n\u2502   \u251c\u2500\u2500 graph.py                   # Graph workflow definition\n\u2502   \u251c\u2500\u2500 nodes.py                   # Node implementations\n\u2502   \u2514\u2500\u2500 types.py                   # Application types\n\u2514\u2500\u2500 react_agent/                   # React agent with tools example\n    \u251c\u2500\u2500 main.py                    # Interactive React agent\n    \u251c\u2500\u2500 graph.py                   # Graph workflow with reasoning loops\n    \u251c\u2500\u2500 nodes.py                   # React agent and tool executor nodes\n    \u251c\u2500\u2500 tools.py                   # Calculator and search tools\n    \u2514\u2500\u2500 types.py                   # State and result types\n\nsimple_example.py                  # Basic framework demo\n```\n\n## Contributing\n\nThis project demonstrates patterns for:\n- Clean architecture in AI systems\n- DSPy best practices\n- Graph integration\n- Type-safe Python development\n\nFeel free to use this as a template for your own DSPy + Graph projects!\n\n## License\n\n[Add your license here]",
    "bugtrack_url": null,
    "license": "MIT License\n        \n        Copyright (c) 2025 Joel Grus\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE.",
    "summary": "A lightweight framework for building graph-based workflows with DSPy nodes",
    "version": "0.1.0",
    "project_urls": {
        "Documentation": "https://github.com/joelgrus/dspygraph#readme",
        "Homepage": "https://github.com/joelgrus/dspygraph",
        "Issues": "https://github.com/joelgrus/dspygraph/issues",
        "Repository": "https://github.com/joelgrus/dspygraph"
    },
    "split_keywords": [
        "ai",
        " dspy",
        " graph",
        " language-models",
        " llm",
        " machine-learning",
        " workflow"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9a5e42cc0d5976c99364cfd52cddced90ced37511dd11685438d8e107797c20c",
                "md5": "9b86dd8e91890786fa4a08e30d18326d",
                "sha256": "ff6c16e0f9e6ed537bc80fc9674404d22fbcebf39fc902a97a9ec82ccec8e50d"
            },
            "downloads": -1,
            "filename": "dspygraph-0.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "9b86dd8e91890786fa4a08e30d18326d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 11119,
            "upload_time": "2025-07-11T18:30:03",
            "upload_time_iso_8601": "2025-07-11T18:30:03.160980Z",
            "url": "https://files.pythonhosted.org/packages/9a/5e/42cc0d5976c99364cfd52cddced90ced37511dd11685438d8e107797c20c/dspygraph-0.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "70bbad4df292c4a72eebafeb083fa504e0ee3b5f464672eec50ccbc50c8f5818",
                "md5": "8b238681c2cf1cebedba8e086c6db4fe",
                "sha256": "89cdd5dbb31f762180627e07f6070a9c0969c5ed0362e65798ff6f6c56303eaa"
            },
            "downloads": -1,
            "filename": "dspygraph-0.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "8b238681c2cf1cebedba8e086c6db4fe",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 9316,
            "upload_time": "2025-07-11T18:30:04",
            "upload_time_iso_8601": "2025-07-11T18:30:04.541540Z",
            "url": "https://files.pythonhosted.org/packages/70/bb/ad4df292c4a72eebafeb083fa504e0ee3b5f464672eec50ccbc50c8f5818/dspygraph-0.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-11 18:30:04",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "joelgrus",
    "github_project": "dspygraph#readme",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "dspygraph"
}
        
Elapsed time: 0.45323s