neuron-explorer
Steering-first neuron explorer for Qwen3.5-4B: push every MLP neuron, keep every rollout, browse the results
翻译准备中
A magical witch assistant equipped with an enchanted grimoire powered by AI, yet shaped by you: your agents, your prompts, your tools...woven into her spells
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
⭐ We appreciate your star, it helps!
Morgana is a modern and flexible conversational AI framework designed to handle complex scenarios through a sophisticated multi-agent, semantic-routing architecture. Built on cutting-edge .NET 10 and leveraging the actor model via Akka.NET, Morgana orchestrates specialized AI agents that collaborate to understand, classify and resolve customer inquiries with precision and context awareness.查看完整 README ↗Morgana is a modern and flexible conversational AI framework designed to handle complex scenarios through a sophisticated multi-agent, semantic-routing architecture. Built on .NET 10 and leveraging the actor model via Akka.NET, Morgana orchestrates specialized AI agents that collaborate to understand, classify and resolve customer inquiries with precision and context awareness.
The system is powered by Microsoft.Agents.AI, enabling seamless integration with Large Language Models (LLMs) while maintaining strict governance through guard rails and policy enforcement.
Morgana reimagines conversational AI through 6 foundational pillars that work in harmony to deliver an orchestration framework that is powerful yet remarkably simple to configure.
Morgana leverages the actor model to create a fault-tolerant, scalable orchestration layer. Each conversation is managed by a hierarchy of specialized actors that collaborate through asynchronous message passing:
Conversation Flow
graph LR
U@{shape: circle, label: "👤 User"}
%% Channels (reference clients, out-of-the-box)
subgraph Channels["Channels"]
CLD@{shape: rounded, label: "🌐 Cauldron"}
RUN@{shape: rounded, label: "📟 Grimoire/Rune"}
end
%% Backend boundary
subgraph Morgana["Morgana"]
CM@{shape: rounded, label: "Manager"}
SV@{shape: rounded, label: "Supervisor"}
G@{shape: rounded, label: "Guard"}
C@{shape: rounded, label: "Classifier"}
R@{shape: rounded, label: "Router"}
MA@{shape: rounded, label: "Agent"}
end
%% User → Channel
U -- HTML --> CLD
U -- TTY --> RUN
%% Channel → BE
CLD -- SignalR --> CM
RUN -- Webhook --> CM
CM -- 1. Creates conversation and activates actor --> SV
%% Internal BE flow
SV -- 2. Asks for language compliance --> G
SV -- 4. Asks for intent classification --> C
SV -- 6. Asks for agent routing --> R
R -- 7. Activates agent for intent handling --> MA
%% External systems
G -. 3 Prompts for language compliance .-> LLM@{shape: braces, label: "LLM (Anthropic, Azure OpenAI, Google, Ollama, OpenAI)"}
C -. 5 Prompts for intent classification .-> LLM
MA -. 8 MCP tool discovery .-> MCP@{shape: das, label: "MCP Server"}
MA -. 9 Intent handling .-> LLM
Agents in Morgana are domain specialists that self-register through declarative attributes, eliminating manual configuration and enabling true plugin-based extensibility. Each agent inherits from MorganaAgent and declares its responsibilities through simple annotations:
[HandlesIntent("billing")]
[RequiresLLMTier(LLMTier.Efficiency)]
[ConsultsAgent("inventory")] // A2A agent discovery (local)
[ConsultsAgent("shipping", "acme")] // A2A agent discovery (partner)
public class BillingAgent : MorganaAgent { ... }
[HandlesIntent("monkeys")]
[RequiresLLMTier(LLMTier.Efficiency)]
[UsesMCPServer("https://func-monkeymcp-3t4eixuap5dfm.azurewebsites.net/")] // MCP tool discovery
public class MonkeyAgent : MorganaAgent { ... }
At startup, Morgana automatically discovers all agents across configured assemblies and validates bidirectional consistency between declared intents and classifier configuration: fail-fast guarantees ensure errors are caught before reaching production.
Agents express their capabilities through tools, which can be native implementations (inherited from MorganaTool) and also dynamically acquired from external MCP servers:
[ProvidesToolForIntent("billing")]
public class BillingTool : MorganaTool
{
public async Task<string> GetInvoices(string customerCode, int count) { ... }
}
The MCP integration permits agents to extend their capabilities by consuming Model Context Protocol servers, making external tools indistinguishable from native implementations. This enables rapid prototyping, microservice integration and ecosystem-driven feature development, all without writing a single line of tool implementation code.
The A2A integration allows agents to collaborate behind the scenes, consulting their peers on-demand to deliver cross-cutting answers that horizontally cover the entire application domain. This enables seamless agent collaboration, autonomous knowledge sharing and cross-domain reasoning, all without user-facing friction or explicit inter-agent configuration.
graph LR
U@{shape: circle, label: "👤 User"}
subgraph Here["This Morgana"]
B@{shape: rounded, label: "Billing"}
I@{shape: rounded, label: "Inventory"}
end
subgraph Acme["Partner: acme"]
S@{shape: rounded, label: "Shipping"}
end
U -- one question --> B
B -- consult_inventory --> I
I -. answer .-> B
B -- consult_acme_shipping --> S
S -. answer .-> B
B -- one answer --> U
A colleague living in the same installation needs nothing configured: that traffic is signed under a key coined at every start. A colleague living in another Morgana is one Morgana:AgentToAgent:Partners[] entry away, carrying the shared key and one policy per direction (OutboundPolicy for the agents consulted there, InboundPolicy for the agents reachable from there, with the ceiling on how many conversations that partner may open). Where a colleague runs is a deployment decision and the prose of an agent never says.
Prompts are not hardcoded strings in Morgana: they are versioned, maintainable project artifacts managed through the IPromptResolverService. This separation of concerns enables prompt engineering teams to iterate independently from application logic, supporting A/B testing, localization and behavioral evolution without redeployment.
The system distinguishes between two prompt categories:
morgana.json): Define actor behaviors, global policies and orchestration rulesagents.json): Define agent personalities, instructions and tool configurationsA unique characteristic of Morgana is its Layered Personality System. Every interaction maintains a consistent global personality (Morgana's core character) while allowing agents to express domain-appropriate specializations:
For example, BillingAgent might be "a pragmatic and concrete witch" while ContractAgent is "a patient and empathetic witch": both remain recognizably "Morgana" while adapting to domain-specific user needs. This creates vertical consistency across conversations with horizontal variation per expertise area, delivering a unified brand experience that feels naturally specialized.
Prompts also define Global Policies that are automatically composed into agent instructions, ensuring system-wide behavioral consistency without repetition.
Every agent in Morgana keeps its own secure, isolated context: memories, variables and conversation state that no other agent can see or touch by default. This is what lets a dozen specialized agents work side by side without stepping on each other's toes.
Some information, though, is meant to travel. A customer code given to BillingAgent shouldn't have to be asked again the moment ContractAgent takes over. Morgana handles this with self-synchronizing shared variables: information explicitly marked as shared is transparently picked up by any agent that needs it, the instant it needs it (no re-asking the user, no manual wiring between agents).
Conversations survive restarts and agent handoffs without losing this context. Users always see one coherent conversation, even when several specialized agents quietly took turns behind the scenes.
Morgana never asks a channel to keep up: it adapts to whatever capabilities a channel actually declares. A rich card, a quick reply, a streamed chunk: each is offered only where the channel says it can render it, gracefully degraded to plain text everywhere else, with nothing lost in translation and nothing crashing in the attempt.
The same conversation, the same agents, the same policies: only the surface changes. A browser gets Cauldron's full HTML experience (sparkle loaders, rich cards, a floating widget). A terminal gets Grimoire's rendered TTY equivalent of the very same turns. Neither channel carries a line of agent logic: they are pure presentation; Morgana is the one that knows, turn by turn, what each of them can take.
Reaching Morgana from a browser does not require landing on Cauldron: it publishes a launcher any page can host, whatever built it.
<script src="https://your-cauldron-host/widget/morgana-widget.js" defer></script>
No parameters: it reads its own src to learn which Cauldron to open, so a copied snippet points back at the deployment it came from. Closed, it is a floating pill carrying Morgana's animated face; opened, a sandboxed <iframe> running the real Cauldron chat: streaming, rich cards, quick replies, dust gauge. A closed shadow root keeps the two stylesheets from reaching each other while the iframe keeps the conversation on Cauldron's own origin, unreadable from the host page. Framing stays closed until a site is listed in Cauldron:Widget:AllowedEmbedOrigins.
Morgana recognizes that the hardest part of building agents isn't infrastructure: it's authoring clear, internally-consistent domain prompts and tool contracts. Alembic is the authoring workbench that solves this problem by conducting an AI-driven interview with domain experts, distilling their knowledge into a complete, buildable plugin—intents, agent prose, tool contracts and working C#, all ready to drop into production.
Alembic runs standalone (no Morgana instance required), talking only to an LLM, so domain experts can model their business on their own schedule. The interview captures the vocabulary, reasoning patterns and tool interactions unique to each domain, then generates an archive that plugs into Morgana as a plugin DLL.
The result is prose as a first-class artifact: agents are authored by people who understand the domain, not engineers guessing at the automation. Changes to behavior flow from changes to the prompt configuration, versioned and auditable like any source code, without requiring recompilation or redeployment cycles.
# 🔨 Build it
dotnet build ./Alembic
# 🧪 Model a domain, at http://localhost:5005
docker compose --env-file .env --env-file .env.versions --profile authoring up alembic
These pillars are argued at length in the project handbooks.
# 📋 Copy the development template
cp development.env.template .env
# ✏️ Configure your secrets
nano .env
# 🔨 Build .NET projects (from project root)
dotnet build ./Morgana
dotnet build ./Channels/Cauldron
dotnet build ./Channels/Grimoire
dotnet build ./Channels/Rune
# 🐳 Build Docker images
docker compose --env-file .env --env-file .env.versions build
# 🚀 Start the containers (Morgana + Cauldron)
docker compose --env-file .env --env-file .env.versions up
# ✅ Open your browser at http://localhost:5002
# 🛑 Stop the containers (when you are done, whichever channel you used)
docker compose --env-file .env --env-file .env.versions down
docker compose --env-file .env --env-file .env.versions run --rm --service-ports --use-aliases grimoire
docker compose --env-file .env --env-file .env.versions run --rm --service-ports --use-aliases rune