Fluid fields are designed to allow the user creating a channel entry to choose which fields are included in the entry. So when you are designing your template you cannot make assumptions about which fields the user will have chosen, or (to some extent) how many, or in what order. So template processing of Fluid fields needs to be handled differently to what you may be used to.
In your example code it is written as though you are confident that the user will provide values for each of the three 'fluid' fields you have defined. For this kind of scenario you might be better off using a Grid field - where you can specify that to complete the entry the user must provide all three grid field values before they can save the entry. The template code you have provided would work if your field was a grid field.
To use a Fluid field you approach things slightly differently. Your code would look more like this:
... HTML to insert if (and every time) a caption field is speciied in channel entry...
... HTML to insert if (and every time) an image field is speciied in channel entry...
... HTML to insert if (and every time) an alt-text field is speciied in channel entry...
Within each of the fluid field HTML blocks you still need to be able to specify where the actual values assigned to each fluid field appear, and you do this using the special tag
The Fluid Field documentation is now pretty clear on how to use the field, and has some good examples, so if you are still not sure go back and give it a read.
Based on what you describe in your question however, I think you really should consider using a Grid field instead.