Recreating a tensor might break the computation graph, so you could use torch.stack instead, which should yield a valid gradient in lamb:
lamb = nn.Parameter(torch.tensor(0.0, requires_grad=True, device=device, dtype=torch.float32))
a = torch.tensor([-1], requires_grad=True, device=device, dtype=torch.float32)
b = torch.tensor([1], requires_grad=True, device=device, dtype=torch.float32)

xi = torch.stack((lamb.unsqueeze(0), a, b))
out = xi * torch.randn(1)
out.mean().backward()