期待的结果
查询具体的属性,或者分类,直接给出ECSQL,及查找结果
![]()
1 elastic search存储用于搜索和语义匹配的元数据索引
步骤
- 打开 checkpoint(SnapshotDb)
- 读取 schema / class / property / label / codevalue
- 过滤掉明显不适合检索的内容
- 只保留有用的元数据和少量示例值
- 生成 property / userlabel / codevalue 三类文档
- 再写入 Elasticsearch
过滤的规则是考虑
- 抽象类不收
- 空类不收
- 无效/不适合查找的属性不收
- 只保留少量示例值,不会把无穷多实例值全存进去
- 重点保留的是“属性定义”和“语义标签”,不是整张模型数据表
结果
npm run index:es -- "bim路径" 去写入
npm run query:es 去验证结果
2 Agent
通过用户的输入,LLM拆解需要的属性,从ES中对应的表,调用最后的ECSQl的生成器,这里比较有意思,我按照自己的想法去写agent,后面Copilot给我建议,说我写的是固定流程,而不是真正意义的agent,那么我问一个好的agent是怎么样的,他给的答案是这样的:
理解目标
→ 选择工具
→ 观察结果
→ 判断下一步
→ 发现错误
→ 分析原因
→ 修正计划
→ 再次执行
→ 判断是否完成
后面我就让Copilot来写~
1 定义决策step
这里给了10,也就是表示 Agent 最多运行10 轮决策。
第 1 步:搜索属性
第 2 步:读取关系
第 3 步:生成 ECSQL
第 4 步:执行 ECSQL
第 5 步:总结结果
防止agent无线循环
2 Agent Tools
search_metadata搜索 iModel 中相关的类和属性inspect_relationships 读取 iModel 中的类继承关系和 Relationship 关系generate_ecsql 根据类、属性和条件生成 ECSQLexecute_ecsql 执行已经生成的 ECSQL
const AGENT_TOOLS = [ { type: "function", function: { name: "search_metadata", description: "Search grounded iModel classes and properties for the user's request.", parameters: { type: "object", properties: { query: { type: "string", description: "Terms to search for." } }, required: ["query"], additionalProperties: false, }, }, }, { type: "function", function: { name: "inspect_relationships", description: "Load the iModel class inheritance and relationship graph.", parameters: { type: "object", properties: {}, additionalProperties: false }, }, }, { type: "function", function: { name: "generate_ecsql", description: "Validate a grounded query plan and generate ECSQL. Search metadata first.", parameters: { type: "object", properties: { targetClasses: { type: "array", items: { type: "object" } }, selectProperties: { type: "array", items: { type: "object" } }, predicates: { type: "array", items: { type: "object" } }, logicTree: { type: ["object", "string", "null"] }, queryIntent: { type: "object" }, reasoning: { type: "string" }, }, required: ["targetClasses", "selectProperties", "predicates", "logicTree"], additionalProperties: false, }, }, }, { type: "function", function: { name: "execute_ecsql", description: "Execute the ECSQL generated by generate_ecsql and return sample rows.", parameters: { type: "object", properties: {}, additionalProperties: false }, }, }, ];3 state
它用来记录已经完成的步骤和中间结果,保证后面的工具可以使用前面工具产生的数据
4 回滚
try { const args = JSON.parse(toolCall.function?.arguments || "{}"); result = { ok: true, result: await runner.run(name, args) }; } catch (error) { result = { ok: false, error: error.message }; }这里如果失败,是会把错误信息继续返回给Agent,让模型自己决定下一步
比如,生成 ECSQL失败,只要没有超过最大的步数,就还可以继续
→ AI 看到错误
→ AI 换一个属性名
→ 再次调用 generate_ecsql
5 结果
我单查询一个唯一属性的时候,返回正确
查询某个category下的所有属性,会发现属性少了,并且有个属性值会被修改a0
另外还测试的一些别的情况,还有不少问题,等后面再慢慢摸索
3 Agent还缺少的部分
- 状态快照
- 状态恢复
- 每个工具独立重试次数
- 错误分类恢复策略
- 查询计划版本管理
- 真正的 rollback/checkpoint 机制