Basic Components
Components are the elements that constitute workflows in MASFactory. These components include Node class components, Edge components, and Message components.
Node: Abstract computational unit onGraph, where Graph, Agent, control logic, etc. are all derived classes ofNodeEdge: Connects two nodes for flow control and automatic message forwarding.Message: Provides unified message parsing and distribution mechanism.Messageis automatically handled by MASFactory, developers only need to tell MASFactory whichMessageFormatterto use for processing node messages.
Node Components
Node components do not appear directly in MASFactory workflows, but appear as their derived classes, such as Graph, Agent, Switch, etc. They undertake core functions such as sub-workflows, computation, and control. All components introduced below are Node class components.
Top-level Components:
Top-level components refer to objects that can be directly instantiated and run independently by users. They are the outermost nodes that neither belong to any Graph nor serve as Node or subgraphs of other Graph. MASFactory provides two types of top-level components: SingleAgent and RootGraph.
RootGraph
Top-level executable workflow container. Can be directly instantiated by users, serving as a "canvas" to host nodes and edges, organize the overall DAG, and responsible for one-time execution and result output. Main methods:
- Constructor parameters:
name,attributes?
Wherenameis the name of RootGraph;attributesare node variables of RootGraph, accessible to all subgraphs and nodes.
Node Variables
For detailed introduction to node variables, please refer to: Concepts-Node Variables
- Related methods:
Method Description
RootGraphis derived fromGraph, so the methodscreate_node,create_edge,edge_from_entryandedge_to_exitbelow are actually inherited fromGraph.
At the same time, bothRootGraphandGraphare subclasses ofNode, where thebuildmethod is declared inNodeand has different implementations in all its subclasses.create_node: Parameters includecls,*args,**kwargs; returnsNode.
Create a node onRootGraph(such asAgent,DynamicAgent,AgentSwitch,LogicSwitch,Graph,Loop,CustomNode, etc.). Whereclsmust be aNodesubclass (SingleAgentandRootGraphare prohibited as intra-graph nodes). Other parameters are passed as-is to the corresponding constructor, returning the node instance.create_edge: Parameters includesender,receiver,keys?; returnsEdge.
Create a directed edge between two nodes in the current graph. Wherekeysdefine fields to be passed and their natural language descriptions. Internal validation includes loop and duplicate-edge checking; created edges are automatically registered to both endpoint nodes and graph.edge_from_entry: Parameters includereceiver,keys?; returnsEdge.
Create a directed edge from graph entry to nodereceiverin the graph.edge_to_exit: Parameters includesender,keys?; returnsEdge.
Create a directed edge from nodesenderin the graph to graph exit.build: No parameters.
Recursively buildRootGraphand its subgraphs and nodes, and complete consistency checking. Must execute this method before callinginvoke.invoke: Parameters includeinput,attributes?; returns(dict, dict).
Start workflow execution. Whereinputformat needs to match entry edgekeys; returns(output_dict, attributes_dict).
Graph Constraints
A correct Graph must satisfy the following conditions:
- There are no isolated nodes in the Graph (nodes with in-degree or out-degree of 0);
- When creating edges connected to
entryandexit, must useedge_from_entryoredge_to_exitinterfaces, cannot usecreate_edgeinterface; - The
receiverandsendernodes increate_edgeinterface must beNodeobjects created using the current Graph'screate_nodeinterface; - All
NodeandEdgecannot form loops. If you need to use loop workflows, please useLoopcomponent.
- Example reference: Create a linear workflow
SingleAgent
Single agent component. An Agent component that can be used independently without relying on any Graph, users can directly instantiate and use it.
Suitable for quick Q&A, simple tool calls, scripted batch processing and other tasks that do not require complete workflow orchestration.
- Constructor parameters:
name,model,instructions,prompt_template?,tools?,memories?,model_settings?,role_name?
Parameter meanings refer to Agent. - Related methods:
invoke: Parameters includeinput(dict); returnsdict.SingleAgentinput/output both use dictionary payloads.
- Example: Create a single agent workflow
Subgraph Components
Subgraph components cannot be directly instantiated by users, but are created through the create_node interface of other Graph instances. The resulting subgraph objects also have create_node and create_edge interfaces and can have their own internal Node. Subgraphs connect with other Node at the same level through the parent graph's create_edge interface, thus forming DAG structure.
Graph
Sub-workflow node supporting reuse and nesting.
- Constructor parameters:
name,pull_keys?,push_keys?,attributes?
Wherenameis the graph name for identification in logs;pull_keys,push_keysandattributesare all node variable control logic.pull_keyscontrols extracting corresponding fields from node variables in parent graph;push_keyscontrols updating corresponding fields in parent graph;attributesare node variable fields that this node carries. Related introduction reference: Concepts-Node Variables. - Features: Built-in
Entry/Exit, serving as "stages" hosting multiple nodes; inheritsBaseGraph's node/edge management and consistency validation. - Related methods:
edge_from_entry,edge_to_exit,create_nodeandcreate_edge, specific introduction reference: RootGraph. - Application scenarios: Divide complex processes into several sub-stages for easy reuse and debugging.
Loop
Loop subgraph, encapsulating iteration control and optional LLM termination judgment functionality.
- Constructor parameters:
name,max_iterations,model?,terminate_condition_prompt?,terminate_condition_function?,pull_keys?,push_keys?,attributes?,initial_messages?max_iterations: Controls maximum loop count.modelandterminate_condition_prompt: Used to set up model and logic for using LLM to determine termination conditions.pull_keys,push_keysandattributes: Control node variable logic, detailed reference: Concepts-Node Variables.
- Features: Contains an internal
Controllernode that checksmax_iterationscondition andterminate_condition_promptcondition at the beginning of each loop;TerminateNodesupports early exit within loop body. - Related methods:
create_nodeandcreate_edge: Usage same as: RootGraph.edge_from_controller: Parameters includereceiver,keysetc.; returnsEdge(start each iteration from controller).edge_to_controller: Parameters includesender,keysetc.; returnsEdge(result flows back to controller forming next round input).edge_to_terminate_node: Parameters includesender,keysetc.; returnsEdge(trigger forced termination within loop body).
- Termination conditions: Terminate when reaching
max_iterationsor when LLM determinesterminate_condition_promptis satisfied. - Force exit loop: Immediately exit when
terminate_nodereceives any message. - Example: Loop example
Loop Constraints
Loopmust form a loop path centered onController, and no other loops are allowed except this loop.Controlleronly makes loop exit judgment at the beginning of each iteration. If you need to exit the loop midway, please useTerminateNodenode to exit the loop.- Edges connected to
Controllernode andTerminateNodenode must be created throughedge_from_controller,edge_to_controllerandedge_to_terminate_nodeinterfaces, cannot be created throughcreate_edgeinterface. - When
TerminateNodereceives a message, it will immediately trigger the exit mechanism (equivalent tobreaklogic in programming languages to exit loops). - The
keysonedge_from_controller,edge_to_controller,edge_to_terminate_nodeandLoop'sin_edgesandout_edgesmust be the same to avoid errors.
Agent Components
Agent
Standard agent node.
Constructor parameters:
name,model,instructions,prompt_template?,formatters?,tools?,memories?,retrievers?,pull_keys?,push_keys?,model_settings?,role_name?,hide_unused_fields?name: Node name for identifying current Agent;model: Large model called by Agent, receives aModelobject, adapted for mainstream LLM APIs. Detailed reference: Model Adapters;instructions: Instruction information sent to Agent. Receives a string or string list; when it's a list, it will be joined with newline characters into complete instructions. Supports using{replacement_field}to embed fields fromin_edgeskeys, fields from node variablesattributes,role_nameinto instructions;prompt_template: Agent's prompt template (corresponding to user prompt). Supportsstrorlist[str]; when it's a list, it will be joined with newline characters; can be used in combination withinstructions; defaults toNone;formatters: Message formatter(s) that define the LLM I/O protocol. Pass a single formatter (used for both in/out) or a list of two formatters[in, out]. Defaults to “paragraph-style input + JSON output”.tools: List of tool functions available for Agent to call. Function names, parameter names, return value types and docstrings will be automatically added to LLM context by MASFactory, automatically call corresponding tools based on LLM call results, and return results to LLM;memories: Memory adapters (write + read). Except forHistoryMemory, memories act as context sources viaget_blocks(...)(injected intoCONTEXT), and Agents willinsert(...)after each step.retrievers: Read-only RAG / external context sources injected viaget_blocks(...). MCP sources can also be plugged in here.model_settings: Additional settings passed to underlying model interface (refer to OpenAI Chat Completions Legacy interface). Supports:temperature(float, range [0.0, 2.0]),top_p(float, range [0.0, 1.0]),max_tokens(positive integer),stop(stop words,strorlist[str]). Unlisted keys will be passed as-is to model adapter (if model supports). Example:{"temperature": 0.7, "top_p": 0.95, "max_tokens": 512, "stop": ["</end>"]};
role_name: Agent's role name. Can use{role_name}to insert it into instructions. Ifrole_nameis not set,role_namedirectly uses the value ofname.hide_unused_fields: IfTrue, input fields not consumed by template placeholders will not be appended into the user payload.
Features:
- Model adaptation: Adapts mainstream model API interfaces.
- Automatic tool calling: When LLM returns tool calls, automatically execute corresponding tools, backfill results and request LLM again until final content is returned.
- Context injection (RAG/Memory/MCP): Providers emit
ContextBlocks which are injected into the user payload as aCONTEXTfield during Observe. Supports passive (auto-inject) and active (on-demand via tools) modes. - System instructions and user templates:
instructionssupportsstrorlistwith placeholders (like{role_name}, incoming edgekeys, node variables); can useprompt_templateto modify input fromin_edges. - Structured output constraints: Automatically generate JSON field constraint prompts based on outgoing edge
output_keysto guide model strict output. - Node variable support: Follows
Node'spull_keys,push_keysandattributesrules;Agentdefaultspull_keysandpush_keysto empty dictionaries.
Related methods:
build(): MarkAgentas executable (usually called uniformly byGraph).add_memory(memory: Memory): Add a memory adapter (used forget_blocksinjection and step-timeinsert).add_retriever(retriever: Retrieval): Add a retrieval/context source (used forget_blocksinjection and/or active retrieval tools).
Example: Agent example
Deep dive
- Observe/Think/Act runtime:
/guide/agent_runtime - Context adapters (RAG/Memory/MCP):
/guide/context_adapters
DynamicAgent
Dynamic agent node.DynamicAgent node is similar to Agent, the only difference is that DynamicAgent node's instructions are not determined at coding time, but extracted from in_edges messages at runtime.
When DynamicAgent runs, it will retrieve fields containing those specified in instruction_key (default is "instructions") from messages sent by all in_edges. If the messages from in_edges contain this field, the content of this field will be used as DynamicAgent's instructions; if this field is not included, it will search for this field in node variables attributes; if neither is found, default_instructions will be used as instructions.
- Constructor parameters:
name,model,default_instructions,instruction_key?,prompt_template?,tools?,memories?,retrievers?,pull_keys?,push_keys?,model_settings?,role_name?default_instructions: Default instructions. Same semantics as Agent'sinstructions, used when incoming edge messages do not provide the field corresponding toinstruction_key; supports using placeholders ininstructions(like{role_name}, incoming edge keys, node variables) and formatting before execution;instruction_key: Key name in incoming edge messages for "dynamically overriding instructions", default value is"instructions". If this key is detected in incoming edge messages, this round of execution will use its value as instructions and overridedefault_instructions;name,model,tools,memories,pull_keys,model_settings,model_settings,prompt_template: Same as Agent;
- Usage example: DynamicAgent example
Conditional Branch Components
Branch components are similar to if branches in programming languages, deciding the direction of the next path based on current state and conditions. MASFactory provides two branch components: logic branch component LogicSwitch based on callback functions and semantic branch component AgentSwitch based on Agent semantic judgment.
LogicSwitch
Conditional routing component based on callback functions, using condition_binding(callback, out_edge) to bind branch conditions.
- Constructor parameters:
name,pull_keys?,push_keys? (meaning same asAgent) - Related methods:
condition_binding(callback, out_edge): Bind anout_edgewith condition callback function.callback(message, attributes) -> bool: Wheremessageis the aggregated message from incoming edges (strordict),attributesis node variables dict; when returningTrue, forward message to thatout_edgeand put thetargetnode connected by thatout_edgeinto the execution queue.
LogicSwitch and AgentSwitch
LogicSwitchwill pass the messagemessagefromin_edgesand node variablesattributesinherited from parent graph into callback functions corresponding to all out_edges, and decide whether to put target nodes connected by thoseout_edgesinto the execution queue based on the return values of callback functions.LogicSwitchsupports "multi-path matching", that is, if multipleout_edgecorresponding condition functions returnTrue, nodes on these paths are all put into the execution queue.AgentSwitchhas similar processing logic toLogicSwitch. The difference is thatLogicSwitchuses callback functions for condition judgment, whileAgentSwitchuses LLM for condition judgment based on condition semantics.
Situations to Avoid
- If an
out_edgeis not bound with condition callback function or condition semantics, the target node corresponding to this edge will never be added to the execution queue. This situation should be avoided in development. - If all conditions bound to all
out_edgeevaluate toFalsein a certain execution, the switch will close all outgoing edges and forward nothing. If the execution queue becomes empty, the workflow ends early. To avoid surprises, add a default/fallback branch (e.g., a predicate that always returnsTrue) or handle the “no match” case explicitly.
- Usage example: Logic branch example
AgentSwitch
LLM-based semantic routing component, using condition_binding(prompt, out_edge) to bind routing semantics.
- Constructor parameters:
name,model,pull_keys?,push_keys? (meaning same asAgent) - Related methods:
condition_binding(prompt, out_edge): Bind semantic judgment promptpromptfor a certain outgoing edge.AgentSwitchwill combine incoming edge messages with each outgoing edge'spromptone by one, callmodelfor judgment (supports multiple outgoing edges hitting simultaneously).
- Usage example: Semantic branch example
Custom Nodes
CustomNode
Node that customizes runtime process with callback functions, convenient for integrating external computation or rules. Supports setting processing functions during initialization or later through set_forward.
Constructor parameters:
name,forward?,memories?,tools?,pull_keys?,push_keys?forward: Custom runtime callback, must returndict; ifforwardisNone, this node passes input through as-is (input is alsodict);memories,tools,retrievers: Available memory/tool/retriever lists for current node (as optional callback parameters);pull_keys,push_keys: Same meaning asNode(node variables).
Related methods:
set_forward(forward_callback): Set callback function.
Callback function:
- Callback parameter forms (automatically matched by parameter count, up to
self):forward(input);forward(input, attributes);forward(input, attributes, memories);forward(input, attributes, memories, tools);forward(input, attributes, memories, tools, retrievers);forward(input, attributes, memories, tools, retrievers, self);
- Return value: Callback return value is automatically sent to downstream nodes through all outgoing edges (return type must be
dict).
- Callback parameter forms (automatically matched by parameter count, up to
Usage example: CustomNode example