Typically the receiver is used for the result so you have the option to reuse an existing big.Int instance. If you don't want to reuse an existing one, you may create a new one for the result and call the method on that.
This is mentioned in the package doc of math/big:
By always passing in a result value via the receiver, memory use can be much better controlled. Instead of having to allocate new memory for each result, an operation can reuse the space allocated for the result value, and overwrite that value with the new result in the process.
The result is also returned so you can chain invocations. This is also mentioned in the package doc:
For instance, the arguments for (*Int).Add are named x and y, and because the receiver specifies the result destination, it is called z:
func (z *Int) Add(x, y *Int) *Int
Methods of this form typically return the incoming receiver as well, to enable simple call chaining.
So you may do something like this:
one := big.NewInt(1)
two := big.NewInt(2)
three := big.NewInt(3)
sum := new(big.Int)
sum.Add(sum, one).Add(sum, two).Add(sum, three)
fmt.Println(sum)
Which will output (try it on the Go Playground):
6
If you don't want to reuse an existing value for the result of an operation, you may allocate a new like this:
one := big.NewInt(1)
two := big.NewInt(2)
fmt.Println(new(big.Int).Add(one, two))
Which prints 3 (try it on the Go Playground).