graphflow

module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 16, 2026 License: MIT

README

Graphflow

Go Version Go Report Card

Graphflow is a Go-native Agent development framework built on a type-safe graph execution engine.

中文文档


Why Graphflow

Most Agent frameworks are Python-first, bring heavy runtimes, and blur the line between orchestration and AI logic. Graphflow is different:

Graphflow LangGraph Eino
Language Go Python Go
Core abstraction Graph engine StateGraph Graph + Chain
Config-driven YAML + code Code only Code only
Zero-dependency core Yes No No
Single binary deploy Yes No No
Built-in resilience Retry / CB / Bulkhead Limited Limited

Architecture

┌──────────────────────────────────────────┐
│  Your Application                        │
│  Business workflows · AI Agent apps      │
└─────────────────────┬────────────────────┘
                      │
┌─────────────────────▼────────────────────┐
│  agent/   — Agent Development Layer      │
│  MessageState · LLMNode · ToolNode       │
│  ReAct · RAG · Supervisor patterns       │
│  ToolRegistry · Memory management        │
└─────────────────────┬────────────────────┘
                      │ depends on
┌─────────────────────▼────────────────────┐
│  graph/   — Graph Execution Engine       │
│  Graph[S] · Engine[S] · NodeFunc[S]      │
│  Sequential · Conditional · Parallel     │
│  Loop · Checkpoint · Hook · OTel         │
│  middleware/ · node/ · checkpoint/       │
└──────────────────────────────────────────┘

The graph/ package is AI-agnostic — it works equally well for business process orchestration, ETL pipelines, and event-driven workflows. The agent/ package adds the AI-specific layer on top.


Quick Start

LLM Configuration

Graphflow uses llmgate as the LLM gateway (19 providers).

# Option 1: config file (recommended)
cp config/llmgate.toml.example config/llmgate.toml   # edit your API keys
go run ./examples/agent_demo

# Option 2: environment variables
export DEEPSEEK_KEY="sk-xxx"
go run ./examples/agent_demo -env -provider deepseek

# Option 3: mock mode (no API key needed)
go run ./examples/agent_demo
ReAct Agent

Use ReActAgent.BuildGraph() for zero-boilerplate setup:

import (
    "github.com/wzhongyou/graphflow/agent"
    llmgate_adapter "github.com/wzhongyou/graphflow/agent/llmgate"
    "github.com/wzhongyou/graphflow/graph"
    "github.com/wzhongyou/llmgate/sdk"
)

gw, _ := sdk.NewFromFile("config/llmgate.toml")
adapter := llmgate_adapter.New(gw, llmgate_adapter.Config{Provider: "deepseek"})

ag := agent.NewReActAgent(agent.ReActAgentConfig{
    Name:         "react-agent",
    LLM:          adapter,
    SystemPrompt: "You are a helpful assistant.",
    Tools:        []agent.Tool{&agent.CalculatorTool{}},
})
g, _ := ag.BuildGraph()

engine := graph.NewEngine(g)
result, _ := engine.Run(ctx, &agent.MessageState{
    Messages: []agent.Message{{Role: agent.RoleUser, Content: "What is 123 * 456?"}},
}, graph.WithHook(myReactHook))

Or build the graph by hand for full control:

llm      := agent.NewLLMNode(agent.LLMNodeConfig{Model: adapter, Tools: tools})
toolNode := agent.NewToolNode(tools...)

g := graph.NewGraph[*agent.MessageState]("react-agent")
g.AddNode("llm", llm.Run)
g.AddNode("tool", toolNode.Run)
g.SetEntryPoint("llm")
g.AddCondition("llm", graph.Condition[*agent.MessageState]{
    If:     agent.HasPendingToolCalls,
    Target: "tool",
})
g.AddEdge("tool", "llm")   // loop back
g.SetMaxIterations("llm", 20)
g.Compile()
Observing the ReAct loop with Hook
type reactHook struct{}

func (h *reactHook) OnNodeEnd(_ context.Context, node string, s *agent.MessageState, _ error, dur time.Duration) {
    last := s.Messages[len(s.Messages)-1]
    switch node {
    case "llm":
        if len(last.ToolCalls) > 0 {
            fmt.Printf("[Thought] → Action: %s  (%s)\n", last.ToolCalls[0].Name, dur)
        } else {
            fmt.Printf("[Thought] → Answer: %s\n", last.Content)
        }
    case "tool":
        for _, m := range s.Messages {
            if m.Role == agent.RoleTool {
                fmt.Printf("[Observation] %s: %s\n", m.ToolName, m.Content)
            }
        }
    }
}
// ... other Hook methods

Output:

[react-agent] question: What is 123 * 456?
  [Thought] → Action: calculator  (12ms)
  [Observation] calculator: 56088
  [Thought] → Answer: The answer is 56088.

[done] steps=3  duration=21ms
Business Workflow (pure graph, no AI)
g := graph.NewGraph[OrderState]("order-pipeline")
g.AddNode("validate",  validateOrder)
g.AddNode("charge",    chargePayment)
g.AddNode("fulfill",   fulfillOrder)
g.AddNode("notify",    sendNotification)
g.SetEntryPoint("validate")
g.AddEdge("validate", "charge")
g.AddEdge("charge",   "fulfill")
g.AddEdge("fulfill",  "notify")
g.Compile()

engine := graph.NewEngine(g)
result, err := engine.Run(ctx, initialState,
    graph.WithTimeout(30*time.Second),
    graph.WithCheckpoint(checkpoint.NewFileManager("/tmp/cp")),
)

Resilience Middleware

Node functions are plain func(ctx, state) (state, error) — wrap them with middleware:

// Recommended composition order (outer → inner)
node := middleware.WithRecover("payment",           // panic → error
    middleware.WithTimeout(chargePayment, 5*time.Second,
        middleware.WithRetry(chargePayment, middleware.RetryPolicy{
            MaxAttempts: 3,
            Backoff:     500 * time.Millisecond,
        }),
    ),
)
g.AddNode("charge", node)

Available middleware: WithRecover · WithTimeout · WithRetry · WithCircuitBreaker · WithRateLimit · WithBulkhead · WithValidate · WithCache


Package Layout

graphflow/
├── graph/                  # Core graph engine (import "…/graph")
│   ├── graph.go            # Graph[S], NodeFunc, Condition, MergeFunc
│   ├── engine.go           # Engine[S].Run — Pregel superstep loop
│   ├── hooks.go            # Hook[S] interface, ComposeHooks
│   ├── errors.go           # Structured error types
│   ├── middleware/         # NodeFunc decorators
│   │   ├── retry.go
│   │   ├── circuitbreaker.go
│   │   ├── bulkhead.go
│   │   └── ...
│   ├── node/               # Built-in nodes (HTTP, Delay, Transform, Noop)
│   └── checkpoint/         # Persistence (memory · file · redis · sqlite)
│
├── agent/                  # Agent layer (import "…/agent")
│   ├── state.go            # MessageState, Message, ToolCall
│   ├── llm.go              # LLMModel, Embedder, VectorStore interfaces
│   ├── nodes.go            # LLMNode, ToolNode, VectorRetrieveNode, HumanInputNode
│   ├── tools.go            # Tool interface, ToolRegistry, CalculatorTool
│   ├── agents.go           # ReActAgent, RAGAgent, SupervisorAgent
│   ├── memory.go           # ShortTermMemory, LongTermMemory
│   └── llmgate/            # llmgate adapter (LLMModel impl)
│
├── config/                 # Configuration templates
│   └── llmgate.toml.example
│
└── examples/
    └── agent_demo/         # ReAct agent with Hook tracing (mock + real LLM)

Roadmap

Core (graph/)
  • Graph model — sequential, conditional routing
  • Loop / back-edge detection with iteration limits
  • Hook interface + ComposeHooks
  • Resilience middleware suite
  • Built-in nodes (HTTP, Delay, Transform, Noop)
  • Structured error types
  • Parallel fan-out / fan-in
  • Stream[T] — Send / Chan / Merge / Broadcast
  • Checkpoint — InMemory, File
  • OTelHook
  • YAML config + LoadFromFile
Agent (agent/)
  • MessageState, Message, ToolCall types (A1)
  • LLMModel / Embedder / VectorStore interfaces (A2)
  • LLMNode, ToolNode — real implementation with tool calling (A3)
  • VectorRetrieveNode, HumanInputNode (A3)
  • Tool interface + ToolRegistry + CalculatorTool (A4)
  • ShortTermMemory, LongTermMemory (A5)
  • ReActAgent.BuildGraph (A6)
  • RAGAgent.BuildGraph (A7)
  • llmgate adapter — 19 providers, fallback, strategy routing
  • SupervisorAgent.BuildGraph (A8)
  • Stream agent + SSE (A9)
  • Structured Output (A10)

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push and open a Pull Request

Please ensure: go vet ./... passes, new public APIs have doc comments, non-trivial logic has unit tests.


License

MIT © 2026 Wang Zhongyou

Directories

Path Synopsis
Package agent provides AI Agent abstractions built on top of the graphflow core engine.
Package agent provides AI Agent abstractions built on top of the graphflow core engine.
llmgate
Package llmgate adapts github.com/wzhongyou/llmgate to the graphflow agent.LLMModel interface.
Package llmgate adapts github.com/wzhongyou/llmgate to the graphflow agent.LLMModel interface.
examples
agent_demo command
agent_demo shows how to build a ReAct agent using graphflow.
agent_demo shows how to build a ReAct agent using graphflow.
Package graph is the core graph execution engine.
Package graph is the core graph execution engine.
checkpoint/redis
Package redis provides a Redis-backed checkpoint.Manager.
Package redis provides a Redis-backed checkpoint.Manager.
checkpoint/sqlite
Package sqlite provides a SQLite-backed checkpoint.Manager.
Package sqlite provides a SQLite-backed checkpoint.Manager.
node
Package node provides reusable built-in node implementations for the graph engine.
Package node provides reusable built-in node implementations for the graph engine.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL