Observed since 20 Oct, 19:06 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
adaptivegraph
Learnable conditional edges for agentic workflows using contextual bandits
from adaptivegraph import LearnableEdge
AdaptiveGraph provides LearnableEdge – a conditional edge that improves routing decisions over time through reinforcement learning.
LearnableEdge replaces static routing logic with a learning-based approach. Instead of hard-coded if/else statements, it learns from feedback which routes work best for different inputs.
Key Features:
Traditional routing logic is static and brittle. LearnableEdge adds plasticity – it learns which routes work best through experience, automatically adapting as patterns change.
From PyPI:
pip install adaptivegraph
From source:
git clone https://github.com/BharathBillawa/adaptivegraph.git
cd adaptivegraph
pip install -e .
With optional dependencies:
# For semantic embeddings
pip install adaptivegraph[embed]
# For persistent storage
pip install adaptivegraph[faiss]
# For development
pip install adaptivegraph[dev]
# Everything
pip install adaptivegraph[all]
from adaptivegraph import LearnableEdge
# Create edge with routing options
edge = LearnableEdge(options=["expert_model", "fast_model", "cheap_model"])
# Make decisions
route = edge({"user": "premium", "query": "complex question"})
# Provide feedback so it learns
edge.record_feedback(result={}, reward=1.0)
See more examples:
examples/basic_routing.py - Simple routing with feedbackexamples/customer_support_agent.py - LangGraph integrationnotebooks/interactive_demo.ipynb - Interactive walkthroughThink of LearnableEdge as a smart traffic router that learns which highway to recommend:
record_feedback(reward)The algorithm balances:
- **Semantic Routing**: Use sentence transformers for similarity-based decisions (requires `adaptivegraph[embed]`)
- **Async Feedback**: Provide feedback hours later using event IDs
- **Trajectory Rewards**: Reward entire multi-step sessions with decay
- **Policy Persistence**: Save and restore learned routing policies
## Usage Examples
### Async Feedback
Pass `event_id` in the state to track decisions, then use it to record feedback later.
```python
# 1. Make decision with event_id
state = {"user": "premium", "query": "async test", "event_id": "req_123"}
route = edge(state)
# 2. Record feedback later using the same ID (no state needed)
edge.record_feedback(result={}, reward=1.0, event_id="req_123")
```
### Trajectory (Multi-step) Rewards
Pass `trace_id` in the state to group decisions into a session.
```python
# Step 1
edge({"step": 1, "intent": "greeting", "trace_id": "session_abc"})
# Step 2
edge({"step": 2, "intent": "params", "trace_id": "session_abc"})
# Reward the whole trace
edge.complete_trace(trace_id="session_abc", final_reward=1.0)
```
### Statistics
Inspect memory to see what the model has learned.
```python
stats = edge.memory.get_statistics()
print(f"Total decisions: {stats['total_decisions']}")
print(f"Average reward: {stats['average_reward']:.2f}")
# Access raw history
print(f"History size: {len(edge.memory.state_history)}")
```
## Notes & Gotchas
* **Numpy Arrays**: Must match `feature_dim` (default 32). E.g., `np.random.randn(32)`.
* **Factory Method**: `LearnableEdge.create()` defaults to `embedding="sentence-transformers"`, which requires the optional dependency.
* To use **without** optional dependencies, set `embedding=None` (uses hashing).
* **Optional Dependencies**:
* `embedding="sentence-transformers"` requires `pip install adaptivegraph[embed]`
* `memory="faiss"` requires `pip install adaptivegraph[faiss]`
See [`examples/`](examples/) and [`notebooks/`](notebooks/) for detailed usage.
LearnableEdge vs alternatives:
On a typical customer support routing task (3 options, 1000 decisions):
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
# Clone and setup
git clone https://github.com/BharathBillawa/adaptivegraph.git
cd adaptivegraph
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
# Format code
black src/ tests/
isort src/ tests/
If you use AdaptiveGraph in your research, please cite:
@software{adaptivegraph2024,
title = {AdaptiveGraph: Learnable Conditional Edges for Agentic Workflows},
author = {BharathPoojary},
year = {2024},
url = {https://github.com/BharathBillawa/adaptivegraph}
}
MIT License - see LICENSE for details.
Made with ❤️ for the AI agent community
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
numpyEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | numpy>=1.24.0 | runtime |
langgraphEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | langgraph>=0.2.0; extra == "dev" | runtime |
pytestEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pytest; extra == "dev" | runtime |
matplotlibEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | matplotlib; extra == "dev" | runtime |
jupyterEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | jupyter; extra == "dev" | runtime |
blackEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | black>=23.0.0; extra == "dev" | runtime |
isortEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | isort>=5.12.0; extra == "dev" | runtime |
flake8Environment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | flake8>=7.0.0; extra == "dev" | runtime |
sentence-transformersEnvironment{
"extras": "",
"marker": "extra == \"embed\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | sentence-transformers>=3.0.0; extra == "embed" | runtime |
faiss-cpuEnvironment{
"extras": "",
"marker": "extra == \"faiss\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | faiss-cpu>=1.8.0; extra == "faiss" | runtime |
adaptivegraphEnvironment{
"extras": "embed,faiss",
"marker": "extra == \"all\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | adaptivegraph[embed,faiss]; extra == "all" | runtime |
bdist_wheel · 15.96 KB · Python py3
sdist · 61.64 KB · Python source
Shared repository data · GitHub
Observed since 20 Oct, 19:06 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:6cbf12909a4b5347ca20f79c163bdcc61ecc1425bf02e082d6381b958567a9d2