Creating the future
Creating code with Google Vertex and Gemini

Creating the future

Even though it's still a heavy lift, generating some code types from specifications can yield good results. I've been helping retailers and other industry verticals access and adopt data models for years. Being a proponent of Model Driven Development, it's always fun working through adoption challenges with those customers as we all tend to model reality a little differently. Several domains have data models and practices that include highly optimized and even dynamic models. One of these models is schema.org which defines over 1400 entities and data types with highly customizable and adaptable relationships. As such, I put my AI hat on and along with some web scrapers and handlers to see what kind of code I could produce.

Challenge

Using the schema.org website, locate all of the defined types, datatypes, and their hierarchy and create a set of Pydantic transfer objects that can represent the domain and serialize properly to JSON. In addition, for every class created, ensure there's a test case, and lastly ensure the documentation is good enough without being overly obvious.

Components for success

  1. A complete representation of each type that can found in a vector store.
  2. A complete representation of the hierarchy of types.
  3. Sufficient rules from a system instruction perspective.
  4. Tools that give access to the AI for reading data and writing files.
  5. Dynamic prompts that can use out of band tools to achieve the desired outcomes successfully.

The Process

  1. Scrape all links to hierarchical types from the https://schema.org/docs/full.html page and ensure all of the appropriate actions are completed (expanding the trees) prior to extracting links.
  2. For each link, open the type definition page and expand all JSON examples; once complete save the content of the page into a PDF.
  3. For each PDF file in the downloaded PDFs directory generate and store vector data and chunks into a persistent vector store so the process doesn't need to be initialized each time.
  4. Initialize the VertexChat agent with the Gemini 2.0 Flash model.
  5. For each type, look up the definition from the vector store, determine the type content (fields, summary, etc), determine the type hierarchy, then create the class based on the information found from the tools.
  6. Write the python source code to the appropriate directory.

The outcome

Schema.org specifies a top level class called "Thing" that has common attributes inherited by all types. All class files below were generated using Google's Gemini. A total of 1864 classes were created, this included enumerations what will require either a better prompt or human intervention. Of those 1864 classes all second level hierarchy classes required at least one change, and less that 50 required additional changes to be valid. Of the test cases created the outcome is similar as the input data was the generated class.

class Thing(BaseModel):
    """
    The most general type of item.
    https://schema.org/Thing
    """
    context: Optional[str] = Field(default="https://schema.org", alias='@context', description='Defines the context for the schema.')
    type: Optional[str] = Field(default="Thing", alias='@type', description='Defines the schema type.')
    name: Optional[str] = Field(default=None, alias='name', description='The name of the item.')
    description: Optional[str] = Field(default=None, alias='description', description='A description of the item.')
    identifier: Optional[Union[str, float, AnyUrl]] = Field(default=None, alias='identifier', description='The identifier property represents any kind of identifier for any kind of Thing, such as ISBNs, GTIN codes, UUIDs etc. Schema.org provides dedicated properties for representing many of these, of course. In schema.org usage, generally only one identifier is allowed per Thing, but identifying code systems can be represented using multiple identifier properties. ')
    image: Optional[Union[AnyUrl, "ImageObject"]] = Field(default=None, alias='image', description='An image of the item. This can be a URL or a fully described ImageObject.')
    url: Optional[AnyUrl] = Field(default=None, alias='url', description='URL of the item.')
    sameAs: Optional[AnyUrl] = Field(default=None, alias='sameAs', description='URL of a reference Web page that unambiguously indicates the item\'s identity. E.g. the Wikipedia page, Wikidata entry, or official website.')
    subjectOf: Optional[Union["CreativeWork", "Event"]] = Field(default=None, alias='subjectOf', description='A subject of the item. Inverse property: subject')
    potentialAction: Optional["Action"] = Field(default=None, alias='potentialAction', description='Indicates a potential Action, which describes an idealized action in which this thing would play an \'object\' role.')
    mainEntityOfPage: Optional[Union["CreativeWork", AnyUrl]] = Field(default=None, alias='mainEntityOfPage', description='Indicates a page (or other CreativeWork) for which this thing is the main entity being described. See background notes for details. Inverse property: mainEntity')
    additionalType: Optional[AnyUrl] = Field(default=None, alias='additionalType', description='An additional type for the item, typically used for adding more specific types from external vocabularies in microdata syntax. This is a more general alternative to 'type' property, which requires full agreement on the type\'s definition. In a schema.org context, the type property always refers to the schema.org type, whereas additionalType allows for more general use.')
    alternateName: Optional[str] = Field(default=None, alias='alternateName', description='An alias for the item.')        

Here, you can see that based on the rules given it created the class and all of the forward references to the other schema.org types.

Next, we see Action, action is-a Thing and has additional attributes.

class Action(Thing):
    """
    An action performed by a direct agent and indirect participants upon a direct object. Optionally happens at a location with the help of an inanimate instrument.
    Agents and objects can be Organizations as well as people.
    The motivation behind the action is captured by the.
    https://schema.org/Action
    """
    actionStatus: Optional[Union[AnyUrl, "ActionStatusType"]] = Field(default=None, alias="actionStatus", description="Indicates the current disposition of the Action.")
    agent: Optional[Union["Person", "Organization"]] = Field(default=None, alias="agent", description="The agent causing the action.")
    endTime: Optional[str] = Field(default=None, alias="endTime", description="The endTime of something. For a reserved event or service (e.g. FoodEstablishmentReservation), the time that it is expected to end. For actions that span a period of time, when the action was performed. e.g. John moved to Seattle on 2015-03-01.")
    error: Optional["Thing"] = Field(default=None, alias="error", description="For failed actions, more information on the cause of the failure.")
    instrument: Optional["Thing"] = Field(default=None, alias="instrument", description="The object that helped the agent perform the action. e.g. John wrote a book with a pen.")
    location: Optional[Union["Place", "PostalAddress", str]] = Field(default=None, alias="location", description="The location of for example where an event is happening, an organization is located, or an action takes place.")
    object: Optional["Thing"] = Field(default=None, alias="object", description="The object upon which the action is carried out, whose state is changed or where it is being directed. The object is the thing the action acts upon, not necessarily when the action is performed on (multiple) other objects.")
    participant: Optional[Union["Organization", "Person"]] = Field(default=None, alias="participant", description="Other participants that may be involved in the action; e.g. when a supporting role was played in the action.")
    result: Optional["Thing"] = Field(default=None, alias="result", description="The result produced in the action. e.g. John wrote a book.")
    startTime: Optional[str] = Field(default=None, alias="startTime", description="The startTime of something. For a reserved event or service (e.g. FoodEstablishmentReservation), the time that it is expected to start. For actions that span a period of time, when the action was performed. e.g. John moved to Seattle on 2015-03-01.")
    target: Optional["EntryPoint"] = Field(default=None, alias="target", description="Indicates a target EntryPoint for an Action.")        

Observations

Even though the above output compiles and is a representation of good output, not all output is equal, nor consistent.

@Field(alias='@type', default="BioChemEntity")
    type: str        

Here for example even though several other classes describe the "type" field correctly, we still see errors like this where the LLM injects incorrect code.

Other such examples are forward refs instead of direct refs or vice versa. Overall the process become increasingly difficult as I realized what had to be done outside of the LLM due to logic limitations. As these continue to improve with thinking models and higher performance non-cached models I hope to see this complexity reduce. Until then I'm continuing to build out such examples to help developers adapt to the change in "what is a developer."

My last observation is that getting our models to perform takes an incredible amount of domain knowledge still. Building prompts and instruction sets defined well enough to create reproducible results isn't a small feet and can often be just as time consuming as writing the code by hand.

Conclusion

Models are continuing to improve but have several generations to go before we'll be creating fully functional apps or frameworks. These continue to get better but the complexity may not always make this the first choice of action. 2025 is going to continue rocking the world of companies and developers and as long as we continue to grow with, test and learn through these changes, the possibilities are granting more capabilities to those who learn the toolsets instead of those who deny them.

#Google #GoogleGemini #VertexAI #Python #GenAI #GenerativeAI #CodeGen

To view or add a comment, sign in

More articles by Ryan M.

  • Optimizing Enterprise Multi-Agent Systems via Stateless Routing

    Abstract Sequential agent logic is the primary scaling bottleneck in production Generative AI. Architectures relying on…

    8 Comments
  • Catalog Enrichment - Using Google's ADK

    With the fast advancement of AI here at #Google it's challenging to keep all of the demos and source up-to-date, but…

  • Choose Simplicity - AI Agent Deployments

    I've spoken with many engineers and architects who are excited about the potential of agent-to-agent communication. The…

  • Elevate your AI

    As we push our limits with amazing tools like Ollama, Langgraph, Gemma, and the myriad of models available today, I…

  • Generating Code from Specifications

    I've recently been posting about the process of using Generative AI to create code from specifications. Specifically…

    2 Comments
  • Agent of Agents

    I've written about the importance of various AI architectures of the near future, today I want to focus on agent of…

  • Digital Commerce - Catalog Enrichment

    In the incredible chaos of 40,000+ visitors from around the world at #NRF2025, if you missed our demo on digital…

  • Building the AI of tomorrow

    SETI @ Home God's Debris - Scott Adams "The Network is the Computer" - John Gage for Sun Microsystems in 1984 Numerous…

  • Make it a Linux 2025

    As we move faster into the world of Generative AI integration with our operating systems, and the total power drain and…

    4 Comments
  • Distraction Free Tech

    Today's distraction free tech recommendations Sticking with the theme posted yesterday about removing distractions…

Others also viewed

Explore content categories