Skip to content

Kauakfm/SharpGraph

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 

Repository files navigation

🔀 MultiAgentGraph

LangGraph-style Multi-Agent Orchestration for .NET

Uma implementação em C# do paradigma LangGraph para construção de agentes de IA com grafos de estado, roteamento condicional e human-in-the-loop.

.NET License LangGraph


🤔 Por que esse projeto existe?

O ecossistema de agentes de IA é dominado por Python (LangChain, LangGraph, AutoGen, CrewAI). Mas e quem trabalha com .NET?

O Semantic Kernel da Microsoft é ótimo, mas não implementa o conceito de grafo de estados com nós e arestas condicionais — o padrão que o LangGraph popularizou.

Esse projeto preenche essa lacuna.


✨ Features

Feature Status Descrição
StateGraph Grafo de estados com nós e arestas
Conditional Edges Roteamento dinâmico baseado no estado
Checkpointing Persistência de estado entre execuções
Human-in-the-Loop Pausar execução para aguardar input do usuário
Multi-Agent Orquestração de múltiplos agentes especializados
Streaming Eventos em tempo real via SSE
Retry + Circuit Breaker Resiliência para chamadas de LLM
Tool Calling Integração com function calling da OpenAI

🏗️ Arquitetura

┌─────────────────────────────────────────────────────────────────┐
│                         ChatController                          │
│                              │                                  │
│                              ▼                                  │
│                         ChatService                             │
│                              │                                  │
│                              ▼                                  │
│  ┌─────────────────── StateGraph ───────────────────┐          │
│  │                                                   │          │
│  │    ┌──────────────┐                              │          │
│  │    │ Orchestrator │ ← Entry Point                │          │
│  │    └──────┬───────┘                              │          │
│  │           │                                       │          │
│  │           ▼ (conditional edge)                   │          │
│  │    ┌──────┴──────┬──────────────┐               │          │
│  │    ▼             ▼              ▼               │          │
│  │ ┌────────┐ ┌──────────┐ ┌─────────┐            │          │
│  │ │ Pedido │ │Financeiro│ │ Usuario │            │          │
│  │ │ Agent  │ │  Agent   │ │  Agent  │            │          │
│  │ └────┬───┘ └────┬─────┘ └────┬────┘            │          │
│  │      │          │            │                  │          │
│  │      └──────────┴────────────┘                  │          │
│  │                 │                                │          │
│  │                 ▼ (conditional edge)            │          │
│  │    ┌────────────┴────────────┐                  │          │
│  │    ▼                         ▼                  │          │
│  │ ┌─────────────┐    ┌─────────────────┐         │          │
│  │ │ Human Input │    │ Response Builder│ ← END   │          │
│  │ └─────────────┘    └─────────────────┘         │          │
│  │                                                   │          │
│  └───────────────────────────────────────────────────┘          │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

🚀 Quick Start

1. Configuração

# Clone o repositório
git clone https://github.com/seu-usuario/MultiAgentGraph.git
cd MultiAgentGraph

# Configure sua API key da OpenAI
# Via variável de ambiente:
$env:OPENAI_API_KEY = "sk-..."

# Ou via appsettings.json:
# { "OpenAI": { "ApiKey": "sk-..." } }

# Execute
dotnet run

2. Teste a API

curl -X POST http://localhost:5000/api/chat \
  -H "Content-Type: application/json" \
  -d '{"message": "Quero cancelar meu pedido 12345", "clienteId": "999"}'

📖 Como Funciona

Definindo um Grafo

var graph = new StateGraph()
    .AddNode("orchestrator", orchestrator.ExecuteAsync)
    .AddNode("pedido_agent", pedidoAgent.ExecuteAsync)
    .AddNode("financeiro_agent", financeiroAgent.ExecuteAsync)
    .AddNode("human_input", HumanInputNode)
    .AddNode("response_builder", BuildResponse)
    .SetEntryPoint("orchestrator")
    .AddConditionalEdge("orchestrator", RouteAfterOrchestrator)
    .AddConditionalEdge("pedido_agent", RouteAfterAgent)
    .SetFinishPoint("response_builder")
    .Compile(new MemoryCheckpointer());

var result = await graph.InvokeAsync(initialState);

Conditional Routing

public static string RouteAfterOrchestrator(GraphState state)
{
    var targetAgent = state.Get<string>("target_agent", "unknown");
    
    return targetAgent switch
    {
        "pedido" => "pedido_agent",
        "financeiro" => "financeiro_agent",
        "usuario" => "usuario_agent",
        _ => "response_builder"
    };
}

Criando um Agente

public class MeuAgent : BaseAgent
{
    public MeuAgent(ILlmClient llm, SharedMemory memory, ToolRegistry tools, IEventEmitter emitter)
        : base("meu_agent", "Descrição do agente", llm, memory, emitter)
    {
        Skills.Add(new MinhaSkill(tools));
    }

    public override async Task<GraphState> ExecuteAsync(GraphState state)
    {
        var action = state.Get<string>("target_action", "");
        var skill = FindSkillForAction(action);
        
        if (skill != null)
        {
            var result = await skill.ExecuteAsync(action, GetParamsFromState(state));
            state.Set("response", result);
        }
        
        return state;
    }
}

Criando uma Tool

public class BuscarPedidoTool : ITool
{
    public string Name => "buscar_pedido";
    public string Description => "Busca informações de um pedido pelo ID";
    public List<string> RequiredParams => new() { "pedido_id" };

    public Task<ToolResult> ExecuteAsync(Dictionary<string, string> parameters)
    {
        var pedidoId = parameters["pedido_id"];
        
        // Sua lógica aqui (banco de dados, API, etc.)
        var pedido = new { Id = pedidoId, Status = "Ativo", Produto = "Notebook" };
        
        return Task.FromResult(ToolResult.Success(pedido));
    }
}

🔄 Human-in-the-Loop

Quando o agente precisa de mais informações:

Usuário: "Cancela meu pedido"
Bot: "Qual o número do pedido?" + sessionId: "abc123"

[Estado salvo no SessionManager]

Usuário: "12345" + sessionId: "abc123"

[Estado restaurado, grafo continua de onde parou]

Bot: "Pedido 12345 cancelado com sucesso!"

📁 Estrutura do Projeto

MultiAgentGraph/
├── Agents/                 # Agentes do sistema
│   ├── BaseAgent.cs
│   ├── AgentRegistry.cs
│   ├── OrchestratorAgent.cs
│   ├── PedidoAgent.cs
│   ├── FinanceiroAgent.cs
│   └── UsuarioAgent.cs
├── Core/                   # Engine do grafo
│   ├── StateGraph.cs
│   ├── CompiledGraph.cs
│   ├── GraphState.cs
│   └── Constants.cs
├── Tools/                  # Ferramentas por domínio
│   ├── ITool.cs
│   ├── ToolRegistry.cs
│   ├── Financeiro/
│   ├── Pedido/
│   └── Usuario/
├── Skills/                 # Skills dos agentes
├── LLM/                    # Abstração do LLM
├── Memory/                 # Memória compartilhada
├── Events/                 # Sistema de eventos/streaming
├── Checkpointing/          # Persistência de estado
├── Resilience/             # Circuit breaker + retry
├── Sessions/               # Gerenciamento de sessões
├── Service/                # Serviços da aplicação
├── Controllers/            # API endpoints
└── Models/                 # DTOs

🆚 Comparação com LangGraph

Conceito LangGraph (Python) MultiAgentGraph (C#)
StateGraph
add_node() ✅ AddNode()
add_edge() ✅ AddEdge()
add_conditional_edges() ✅ AddConditionalEdge()
Checkpointer ✅ ICheckpointer
Human-in-the-loop
Streaming ✅ SSE
Subgraphs ❌ (roadmap)
State Reducers ❌ (roadmap)
Parallel Execution ❌ (roadmap)

Cobertura aproximada: ~80% das features core do LangGraph


🛣️ Roadmap

  • Subgraphs (grafos aninhados)
  • State Reducers (append/merge de valores)
  • Parallel Node Execution
  • SQL Server SessionStore
  • Redis Checkpointer
  • Breakpoints (interrupt_before/after)
  • Time Travel (replay de checkpoints)
  • Dashboard de visualização do grafo

🤝 Contribuindo

Contribuições são bem-vindas!

  1. Fork o projeto
  2. Crie sua branch (git checkout -b feature/MinhaFeature)
  3. Commit suas mudanças (git commit -m 'Adiciona MinhaFeature')
  4. Push para a branch (git push origin feature/MinhaFeature)
  5. Abra um Pull Request

📄 Licença

Este projeto está sob a licença MIT. Veja o arquivo LICENSE para mais detalhes.


⭐ Gostou?

Se esse projeto te ajudou, deixa uma ⭐ no repositório!


Feito com 💙 e muito C#

About

LangGraph for .NET — Stateful multi-agent orchestration with StateGraph, human-in-the-loop and streaming events.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages