AI resources setup
The setupAiResources function sets up the following resources:
- A Team
- Agents
- Equip Agents with Tools
- An in-depth SchemaDefinition that describes the properties of the project's collections and their related items in the Item Service. An agent with RelatedQueryTool uses this when constructing a query. For more information, see [].
Creating agents#
To meet the requirements of this feature, the following agents are required:
- An Agent that constructs a
$findWithRelatedquery based on your prompt. This Agent requires the RelatedQueryTool in order to construct such a query. - An Agent that runs the query and returns the results. This Agent requires the SearchRelatedItemsTool.
- An Agent that takes the response items and presents them as it sees fit with a summary, making sure to include the ids.
Define the agents in an array, making sure to add a _background property, which becomes the system propt, and any required tools and your LLM config:
const createDefaultAgents = async (PlatformApi, ctx) => { const { IafAISvc } = PlatformApi; const agentDefs = [ { _name: "FindWithQueryConstructor", _background: ` //For more information, see the following section `, _userType: "FindWithQueryConstructor", _type: "user_agent", _namespaces: ctx._namespaces, _config: { _provider: "openai", _model: "gpt-4o" }, _tools: [ "RelatedQueryTool" ] }, { _name: "FindWithQueryRunner", _background: "Use the SearchRelatedItemsTool to run the input findWithRelated query and return results", _userType: "FindWithQueryRunner", _type: "user_agent", _namespaces: ctx._namespaces, _config: { _provider: "openai", _model: "gpt-4o" }, _tools: [ "SearchRelatedItemsTool" ] }, { _name: "QueryPostProcessor", _background: ` Take the FindWithQueryRunner results and - Format them for user display - Include all possible element ids - Add insights about the returned elements `, _userType: "QueryPostProcessor", _type: "user_agent", _namespaces: ctx._namespaces, _config: { _provider: "openai", _model: "gpt-4o" }, _tools: [ "SearchRelatedItemsTool" ] } ]; //hidden code};
Next, post the agents to the database using IafAISvc.createAgents:
try { const agents = await IafAISvc.createAgents(agentDefs, ctx); console.log("Created agents:", agents); } catch (error) { console.error("Error creating agents:", error); throw error; }Crafting background for RelatedQueryTool for element selection#
While the RelatedQueryTool is designed to construct related queries, you can narrow its focus to your exact use case to deliver exact results each time and more quickly. This background information can be helpful context, knowledge you have gained that you want to pass on to the agent, or required instruction based on your experience when testing the agent's results.
The following sections are useful for prompt engineering:
- Objectives
- Warning
- Important
- Use cases
- Guidelines
The following background is an in-depth example used to reliably contruct findWithRelated queries for the explicit purpose of finding revit elements based on a user's prompt, which could involve finding elements by category, type, or any type of property query.
Important: Give the agent pagination instructions. This drastically reduces reaching your LLM's token limit. In your guidelines section, describe how your agent should paginate based on the user's question. For more information, see the 'Guidelines' section of the following system prompt.
Warning: - Do not use a findInCollections query. Use findWithRelated only.
Objective: - Construct a findWithRelated query with a 'parent' and 'related' query to fulfill the element search. - In the parent query, find items in one collection that match, then in the related query, get relevant items related to those matches. - The three collections are 'rvt_elements', 'rvt_element_props', and 'rvt_type_elements'
Important!: - You must include the _userItemId of the parent collection in the parent collectionDesc - Always use '_id', not 'id' - Do not use _relatedUserItemId or _relatedTypeName in the relatedDesc, use _relatedUserType
Use Cases: - Find model elements by a given property/ies (material, props above or below a given value, etc.) (find matching properties in rvt_element_props collection, then get related model elements from rvt_elements collection) - Find model elements by type or category provided by the user: - Target the types collection in the parent query using 'ElementType' or 'ElementCategory' equal to the type the user suggests, for example "query": { "$or": [ { "ElementType": { "$regex": "^Table$", "$options": "i" } }, { "ElementCategory": { "$regex": "^Table$", "$options": "i" } } ] }, Note: type elements do not have properties so do not use properties.prop.val in the query, use 'ElementType' or 'ElementCategory' directly in the query against the types collection. Then get related model elements from rvt_elements collection., - Do not separate the words in the regex because the results are useless, for example, '.*(Fire|Alarm|Panel).*' does not find a 'Fire Alarm Panel', it finds everything else that has one of those words. You can regex for lower/uppercase or word order. - Find the properties of a model element/s (find model elements in rvt_elements that match element id/s, then get related properties from rvt_element_props collection) - Find the superlative or diminutive model element by a certain property - use sort
Guidelines:- Never hallucinate or fabricate data.- Make sure to return the id of any element discussed. These ids are scraped from the response by the app to highlight them in the 3D model viewer.- For follow up questions, either adjust the existing query or use the ids from the last response to create a new and different type of query. - Follow up example: You returned elements that matched a query, then the user asks which element is the largest. Use the ids from the last response to create a new query that gets the height properties of those elements. A later agent will then compute the largest from those.- Don't return just a single element unless the user specifically asks for one or that is simply all that matches.- Limit the page size to 10 results unless the prompt indicates otherwise. - If the the user prompt asks: "show me more": increase the offset to show the next 10 and so on. "show me all": increase the page size and tell the user the current page size and whether to increase it further. - The larger the page size, the more limiting the projection should be. For example, return only the element type, category, and id. For even larger, only return the ids. - Always mention the total number of results found for the query.Creating a Team#
Create a Team with reference to the created Agents and their flow order:
const team = await IafAISvc.createTeam({ _name: "Model Query Team", _namespaces: ctx._namespaces, _agents: [ { _userType: "FindWithQueryConstructor" }, { _userType: "FindWithQueryRunner" }, { _userType: "QueryPostProcessor" } ], _flow: [ { from: "__start__", to: "FindWithQueryConstructor" }, { from: "FindWithQueryConstructor", to: "FindWithQueryRunner" },
{ from: "FindWithQueryRunner", to: "QueryPostProcessor" }, { from: "QueryPostProcessor", to: "__end__" } ] });