Skip to main content
Back to all essays
Logistics6 min read

AI pricing agents: keep the margin calculation in code

A worked freight quote explains margin versus markup, decimal rounding, missing inputs and how programmatic tool calling fits a pricing workflow.

Illustrative freight pricing: USD 1,150 cost produces a USD 1,437.50 price at 20 percent margin; 20 percent markup gives USD 1,380. Read source facts, run an approved calculation rule, and hold incomplete quotes.
Open full-size workflow diagram
Read the workflow steps
  1. Read source amounts, currency and quote validity. The fictional cost is USD 1,000 linehaul, USD 120 fuel and USD 30 handling.
  2. The approved rule targets margin: price equals cost divided by one minus margin. USD 1,150 divided by 0.80 equals USD 1,437.50.
  3. A 20 percent markup gives USD 1,380 and a 16.67 percent margin. The rule must state which measure applies.
  4. Return the calculation and source versions for review. Missing currency, uncertain charges or expired evidence holds the quote; sending still requires a separate release decision.
Cover graphic for AI pricing agents: keep the margin calculation in code, Logistics

A freight quote can contain correct arithmetic and still use the wrong commercial rule. Suppose an AI assistant reads a carrier cost of $1,150 and a request for a 20% margin. It returns $1,380. That price adds 20% to cost, but its margin is about 16.67%. The operator needs a way to see which calculation ran before sending the quote.

This is a fictional pricing example. The charges and policy below are illustrative, not a client result or a recommendation for a particular trade lane. I would let the assistant identify relevant facts and explain exceptions, while a reviewed calculation function applies the business's chosen rule. The function needs explicit inputs and a version the team can inspect.

Write the pricing rule before choosing the model

In this example, margin means profit divided by selling price. Markup means profit divided by cost. If cost is C, price is P and target margin is m, then (P - C) / P = m, so P = C / (1 - m). A request to add a markup r instead uses P = C × (1 + r). Those definitions belong in the application contract; a conversational phrase such as 'add twenty percent' is too ambiguous to release a quote.

Two different rules applied to the same fictional cost
RuleCalculationResult
20% margin$1,150 / 0.80$1,437.50 price; $287.50 profit
20% markup$1,150 × 1.20$1,380.00 price; $230.00 profit
Margin of the marked-up price$230 / $1,38016.67%, rounded for display

Agree what belongs in cost. Our hypothetical rule includes linehaul, fuel and handling, excludes tax, and uses USD throughout. Another business may treat pass-through charges differently. Currency conversion, minimum fees and customer agreements need their own approved rules. A decimal library cannot choose those policies for the team.

Carry the source facts into the calculation

Consider quote Q-501, version 7. The carrier record states USD 1,000 linehaul, USD 120 fuel and USD 30 handling. The customer pricing policy specifies a 20% margin. I would pass those separate charges, their source references and the policy version to the calculation tool, rather than accepting a model's combined total without provenance.

Illustrative input contract, not a vendor API schema
quote_id: Q-501
source_version: 7
currency: USD
linehaul: '1000.00'
fuel: '120.00'
handling: '30.00'
pricing_rule: margin-v3
target_margin: '0.20'
source_validity: confirmed

Now change one input: the email says 'handling included', while the rate sheet lists $30 separately. The assistant should show that conflict and hold the calculation for resolution. Substituting zero would silently select a commercial interpretation. Preserve both references and assign the question to the person who owns the rate.

Use decimal arithmetic with a stated rounding policy

Python's Decimal type supports decimal representation and configurable rounding. Constructing a Decimal from a float preserves that float's approximation; constructing it from a decimal string avoids introducing that conversion. The decimal documentation also explains quantize for rounding to a fixed number of places. Python: Decimal representation and rounding

Arithmetic demonstration for the fictional USD policy
from decimal import Decimal, ROUND_HALF_UP

charges = [Decimal(s) for s in ('1000.00', '120.00', '30.00')]
margin = Decimal('0.20')
assert all(x.is_finite() and x >= 0 for x in charges)
assert margin.is_finite() and 0 <= margin < 1

cost = sum(charges, Decimal('0'))
price = (cost / (1 - margin)).quantize(
    Decimal('0.01'), rounding=ROUND_HALF_UP
)
print(cost, price)  # 1150.00 1437.50

That snippet demonstrates the arithmetic only. A production tool must enforce its input schema, currency rules, amount limits and source validity, and handle invalid input without relying on Python assertions. It also needs the business's choice of rounding stage. Rounding each line before summing can differ from rounding a final total. Keep that choice in a tested policy version and show the operator how it affects the displayed amount.

Where programmatic tool calling helps

Claude's programmatic tool calling lets generated code invoke tools inside a code execution container. Intermediate results can be processed before the final output reaches the model context. It can suit a workflow that reads many candidate rates and returns a compact comparison. Small, strictly sequential jobs can gain little from the extra container and script work. Claude: programmatic tool calling and workload fit

For Q-501, I would expose a bounded read endpoint and a calculate_quote function implementing the reviewed margin rule. Generated code could organize the candidate reads, but it would call that function for the commercial calculation. An ad hoc script that writes its own formula has not gained policy correctness merely because it runs successfully.

The current Claude documentation warns that allowed_callers is guidance, not a hard security boundary. It also lists strict tools and MCP-connector tools as incompatible with programmatic calling. Check those constraints against the intended integration and validate tool inputs in the application. Claude: caller guidance and current limitations

Return an auditable result: input charge IDs, currency, cost, calculated price, formula version and unresolved fields. Keep the endpoint read-only during the pilot. The ability to calculate a quote should not also allow changing a customer agreement or sending an offer. Measure the complete workflow before enabling programmatic calling broadly; this article does not report a model benchmark or a token-saving result.

Test mistakes that change a quote

Proposed acceptance cases for a pricing pilot
Input or eventExpected behaviorEvidence to inspect
20% margin on USD 1,150Calculate USD 1,437.50 under margin-v3Exact output and formula version
'Add twenty percent' without a policyAsk whether margin or markup appliesNo released price before clarification
Fuel charge appears twiceResolve duplicate source chargesEach charge included once
Currency is missing or amounts mix currenciesHold until currency and conversion rules existNo inferred currency in a release item
Carrier revises the rate while approval is pendingRefresh and recalculateOld source version cannot be released
Caller asks the calculation tool to send the quoteReject the unsupported actionNo downstream message or booking

Track wrong prices separately from cases correctly held for clarification. Record operator correction time and unresolved cases alongside model and tool costs. A system that returns fewer prices can be useful if it makes genuine ambiguity visible, but unnecessary holds can overwhelm a desk. Agree both the permitted error types and the review capacity before comparing providers.

After the calculation passes, release the quote through a separate operation that checks the current rate version and the exact approved contents. If sending times out, recover the downstream status before sending again. Our retry article carries that part of the workflow through an uncertain outcome. Read: recovering an uncertain agent action

Implementation considerations

What to establish before automating freight quotes

Preserve the commercial inputs

A useful RFQ record includes lane, dates, weight, dimensions and service requirements. Missing or conflicting inputs should produce a clarification request rather than a plausible-looking quote.

Make pricing traceable

Keep carrier rate versions, surcharges, currencies and margin rules attached to the calculation. Compare proposed quotes with desk-approved examples, including expired rates and unusual cargo.

Define release authority

Separate quote preparation from authority to send or accept it. Agree which exceptions go to the pricing desk and record overrides so the team can review the reason for each decision.

Putting this into practice?