Setting up the guide for this DAG model

I have setup a DAG model as follows:

import torch
import pyro
import pyro.distributions as dist
import pandas as pd

def model(data: pd.DataFrame):
    # Set up some prior distributions
    prior_dir = pyro.sample("prior_dir", dist.Dirichlet(concentration=torch.ones(9)))
    prior_mean = pyro.sample('prior_mean', 
                             dist.Normal(loc=torch.zeros([9, 7, 9]), 
                                         scale=torch.ones([9, 7, 9]) * 1000))

    prior_std = pyro.sample('prior_std', 
                            dist.Gamma(concentration=torch.ones([9, 7, 9]) * 0.5,
                                       rate=torch.ones([9, 7, 9])))

    for i in pyro.plate("data_loop", len(data)):
        row = data.iloc[i]
        A = pyro.sample("obs_A_{}".format(i), 
                        dist.Categorical(prior_dir), obs=row['A'])
        B = pyro.sample("obs_B_{}".format(i), 
                        dist.Categorical(prior_dir), obs=row['B'])
        C = pyro.sample("obs_C_{}".format(i), 
                        dist.Categorical(prior_dir), obs=row['C'])
        D = pyro.sample("obs_D_{}".format(i), 
                        dist.Normal(loc=prior_mean[row['A'], row['B'], row['C']],
                                    scale=prior_std[row['A'], row['B'], row['C']]),
        E = pyro.sample("obs_E_{}".format(i), 
                        dist.Normal(loc=prior_mean[row['A'], row['B'], row['C']],
                                    scale=prior_std[row['A'], row['B'], row['C']]),

So here A, B, C are parents and D and E are child nodes (connected to A, B and C). I have a few questions:

1: Is the model definition correct. I keep getting confused about pyro.param and pyro.sample.

2: If I want to write a custom guide, what variables should be exposed in the guide function. Should it be A, B, C, D, E or also the prior_dir, prior_mean and prior_std. I am a bit confused about how the model and guide functions need to be connected.

3: What should the guide function return? Also, does the model function need to return something?