Skip to lesson

NVIDIANVIDIA-Certified Professional: Agentic AI2026-101.8 Ensure adaptability and scalability of the agent’s architecture.

Replace components through explicit interfaces

Completed by the knowledge check

Learning objective

Separate model, tool, memory, and orchestration interfaces so components are replaceable via configuration.

Core idea

A component is replaceable when its caller depends on an interface and a configured reference rather than constructing one implementation internally. Moving a hardcoded model name into YAML helps, but it does not separate tools, memory, or control flow that still instantiate their own dependencies.

NeMo Agent Toolkit expresses these dependencies through llms, functions, memory, and workflow. Instance names select configured objects; _type selects their registered implementations. Preserve that distinction: changing a reference chooses another instance, while changing its type can require different configuration and runtime capabilities.

The architectural decision is which behavior stays stable when an implementation changes. Configuration supplies the selection mechanism; your adapters must preserve the meaning of inputs, outputs, errors, and state.

How it works

Resolve dependencies by their configured names

The toolkit’s workflow configuration defines typed references including LLMRef, FunctionRef, and MemoryRef. A custom component uses the appropriate reference type for a dependency so the builder can initialize components in dependency order. A plain string that happens to contain another component’s name does not express that typed dependency relationship.

For a ReAct workflow, llm_name names an entry under llms, and tool_names names entries under functions. The workflow._type selects the orchestration implementation; the workflow can be any registered toolkit function. See 1.2.2 for ReAct execution controls. Here the important property is that the workflow refers to dependencies rather than owning their concrete constructors.

Do not interpret configuration as arbitrary interchangeability. A component still has to accept the chosen dependencies. A tool-calling workflow needs a model integration that supports its expected tool interface; a workflow configured for one input shape cannot consume a replacement that produces a different meaning merely because both expose a function.

Put provider differences behind the model interface

Within llms, _type: nim selects the NVIDIA NIM provider, while _type: openai selects the OpenAI provider. The LLM configuration page defines model_name and provider-specific settings. For NIM, these include base_url, api_key, max_tokens, and max_retries. These settings belong with the model instance, rather than being scattered through tool code.

The same YAML can serve several deployments through environment interpolation: ${VAR} uses the variable or an empty string if unset, while ${VAR:-default} supplies a fallback. For example, set base_url: ${NIM_BASE_URL} and api_key: ${NIM_API_KEY} from each deployment’s environment, and validate that required variables are populated. For one-off changes, nat run and nat serve accept dot-notation overrides such as --override llms.nim_llm.temperature 0.7.

Provider configuration is also a capability boundary. NVIDIA documents temperature and top_p as model-gated: explicitly setting an unsupported field causes validation to fail. Copying an entire provider block to a different model can therefore fail even when the workflow’s model reference stays unchanged. Remove or change unsupported fields according to the target’s documented configuration; do not treat a validation failure as an inference outage.

An existing LangGraph agent illustrates the difference between wrapping and separating dependencies. The toolkit’s langgraph_wrapper uses graph to locate a graph definition and requires nvidia-nat-langchain. It can run an agent with hardcoded model construction. To make that model configurable, NVIDIA instead demonstrates SyncBuilder.current().get_llm("agent", wrapper_type=LLMFrameworkEnum.LANGCHAIN). The wrapper does not rewrite the graph’s constructors for you.

Separate tool implementation from orchestration

A custom toolkit function registers with @register_function, using a configuration class derived from FunctionBaseConfig. Its registered name is selected by _type; its instance is selected through the workflow’s function references. FunctionInfo.from_fn() supplies a callable interface, while a Function subclass can implement _ainvoke and _astream for single and streaming output.

Keep backend client construction inside the tool adapter. For example, an order lookup tool can keep its workflow-facing order identifier and result schema while replacing the service it calls. The adapter owns translation from the replacement’s response to that stable result. If the replacement cannot preserve the meaning, change the interface deliberately rather than hiding the difference behind the same tool name.

Swapping the root workflow._type is a larger change than swapping a tool. It changes who chooses the next action. Preserve the application’s expected input and terminal result, then reassess the internal sequence and tool permissions. See 1.6.1 for validating intermediate results; replaceability does not remove those checks.

Give memory its own provider boundary

The toolkit’s memory extension interface uses MemoryBaseConfig for provider configuration and MemoryEditor for runtime operations. The documented methods include add_items, search, and remove_items; builder.get_memory_client() resolves a configured memory client. A provider can therefore change without every agent learning its storage API.

Method compatibility does not migrate records. Replacing a memory provider still requires a deliberate choice about existing items, retrieval behavior, and deletion. See 1.4.2 for tenant scope and lifecycle. At this boundary, the memory owner verifies that the replacement preserves those semantics before the workflow references it.

Key distinctions and trade-offs

Use the following boundaries to decide what configuration can change:

BoundaryDeciding conditionMechanismCost or obligation
ModelSame workflow, different inference targetllms, LLMRef, llm_name, provider _typeVerify target capabilities and provider fields
ToolSame operation, different backendfunctions, FunctionRef, @register_functionTranslate backend results and errors
MemorySame memory operations, different storememory, MemoryRef, MemoryEditorMigrate data and verify retrieval and deletion
OrchestrationDifferent control strategyworkflow._type or langgraph_wrapper.graphReassess ordering, termination, and output behavior

These boundaries add adapter work. They earn that cost where implementations genuinely vary across deployments or evaluations. A single universal adapter that erases streaming, tool support, or error distinctions makes replacement less predictable, even if its method list is short.

Architecture / decision scenario

A retail employee assistant serves two regions. One region permits a hosted model; the other requires a regional NIM endpoint. Both must query the same inventory operation and preserve 90 days of approved preference records. The team has two engineers and a four-week regional rollout deadline. Its acceptance target is at least 95 successful inventory answers out of 100 fixed cases, with a two-second response budget.

The tempting proposal is to fork the whole agent for each region. That duplicates the orchestration and tool fixes the team must maintain. The architect instead gives the workflow one model reference under llms. The platform owner sets each deployment’s approved base_url and api_key through ${NIM_BASE_URL} and ${NIM_API_KEY}, keeping the YAML shared. The model owner verifies capability and gated-field support rather than copying every sampling setting unchanged.

The inventory owner registers a stable function interface and isolates regional service translation inside that function. The memory owner implements the selected MemoryEditor provider and separately verifies that the 90-day records remain retrievable and removable after migration. The orchestration owner keeps the root workflow selection explicit and checks the same terminal answer format for both deployments.

If the regional model scores only 87 of 100, changing YAML has succeeded as dependency selection but failed the release criterion. The model owner also measures the regional endpoint against the two-second response budget; failing either target requires improving or rejecting the implementation. Replaceability reduces the code needed to compare options; it does not establish their quality or latency equivalence.

Common exam traps

  • Treating an instance name as the registered _type.
  • Expecting an unset ${VAR} to raise an interpolation error instead of becoming an empty string.
  • Wrapping a graph and assuming its hardcoded dependencies become configurable.
  • Changing a memory provider and assuming its records move automatically.
  • Copying unsupported sampling fields into a replacement model configuration.
  • Replacing orchestration while ignoring changes to control flow and terminal output.

What to remember

Use typed component references and resolve implementations at the boundary that owns them. Configuration can select models, tools, memory providers, and workflows, but each replacement must preserve the behavior its caller relies on. Separate selection from capability validation, data migration, and release acceptance.

Knowledge check

References