A culinary assistant that rescales a classic carbonara recipe from 2 servings to 6. The Agent is given a custom Python function as a tool and a Pydantic model as its response_schema, so the final reply is a fully validated Recipe object instead of free-form text.
"""02 · Recipe builder — tools and structured outputShows two core Agent features on top of the bare loop:1. A custom ``@tool`` function the LLM can call (``scale_ingredient``).2. A Pydantic ``response_schema`` so the final reply is a typed object.Run:: .venv-beta/bin/python 02_recipe_builder.py"""importasynciofrompydanticimportBaseModel,Fieldfromautogen.betaimportAgentfromautogen.beta.configimportGeminiConfigdefsection(title:str)->None:print(f"\n── {title} ───")classIngredient(BaseModel):name:strquantity:floatunit:strclassRecipe(BaseModel):title:str=Field(description="Short human title for the recipe.")servings:int=Field(description="How many portions this recipe yields.")ingredients:list[Ingredient]steps:list[str]=Field(description="Ordered preparation steps.")defscale_ingredient(quantity:float,factor:float)->float:"""Return ``quantity`` multiplied by ``factor``, rounded to 2 decimals. The model uses this any time it needs to rescale a recipe for a different number of servings. """returnround(quantity*factor,2)asyncdefmain()->None:config=GeminiConfig(model="gemini-3-flash-preview",temperature=0)section("Recipe builder — scale an existing dish for 6 servings")agent=Agent("chef",prompt=("You are a culinary assistant. When asked to rescale a recipe, ""use the scale_ingredient tool for every ingredient to compute the ""new quantity. Return a complete Recipe object."),config=config,tools=[scale_ingredient],response_schema=Recipe,)reply=awaitagent.ask("Start from classic carbonara for 2 servings: 200g spaghetti, 2 eggs, ""100g guanciale, 50g pecorino romano. Rescale it for 6 servings and ""produce the full Recipe.")recipe:Recipe|None=awaitreply.content(retries=1)ifrecipeisNone:print("Model returned no body — try again.")returnprint(f"{recipe.title} ({recipe.servings} servings)")print()print("Ingredients:")foringinrecipe.ingredients:print(f" - {ing.quantity}{ing.unit}{ing.name}")print()print("Steps:")fori,stepinenumerate(recipe.steps,1):print(f" {i}. {step}")if__name__=="__main__":asyncio.run(main())