关于 contracts-query-enhancer
面向 ServiceNow 合同管理的技能,将业务语言转为合同及义务查询条件,帮助非技术用户和合同团队进行发现、续约、审计及报告筛选。
主要功能
- 01映射搜索词与合同字段
- 02解析供应商、类型和状态
- 03将日期表达转换为查询条件
- 04组合筛选条件并建议后续查询
- 05查询合同义务并构建保存搜索
适用场景
- 01查找即将到期或自动续约的合同
- 02按供应商和金额筛选合同
- 03审计合同义务与合规事项
- 04为合同报告构建筛选条件
MCP 相关
通过 SN-Query-Table 查询合同、义务、供应商和选项值,也可使用 SN-Discover-Table-Schema 检查字段,并以 SN-Create-Record 保存搜索。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ happy-technologies-llc/ happy-platform-skills --skill contracts-query-enhancer安装后在 Claude Code 中输入/contracts-query-enhancer确认已加载。
详细介绍
合同查询增强器
概述
此技能可将自然语言合同搜索查询转换为精准的 ServiceNow 查询,让用户无需了解表结构或编码查询语法即可查找合同。它涵盖:
- 将对话式搜索词映射到合同表字段和编码查询运算符
- 将供应商名称、合同类型和状态值解析为对应的 ServiceNow 值
- 将日期表达式(“下季度到期”“去年签署”)转换为编码日期查询
- 理解义务相关术语,并映射到 CLM 义务类型
- 组合多个搜索条件,生成优化的复合查询
- 建议后续查询,以便缩小宽泛的结果范围
适用场景:
- 用户使用业务术语而非字段名称搜索合同时
- 为审计、续约或尽职调查项目查找合同时
- 构建需要特定筛选条件的合同报告时
- 非技术相关人员需要在不具备 ServiceNow 专业知识的情况下查找合同时
- 需要根据自然语言条件触发的自动化合同监控
前置条件
- 角色:
contract_reader、contract_manager、sn_clm.user或admin - 插件:
com.snc.contract_management(Contract Management)或com.sn_clm(Contract Lifecycle Management) - 访问权限: 对 ast_contract、clm_obligation、core_company、sys_choice 表具有读取权限
- 知识: 基本了解合同术语及所在组织的合同分类体系
查询映射参考
自然语言到字段的映射
| 自然语言术语 | ServiceNow 字段 | 表 | 编码查询示例 |
|---|---|---|---|
| “供应商”“供货商”“服务提供商” | vendor | ast_contract | vendor.nameLIKE[term] |
| “到期”“即将到期”“结束日期” | ends | ast_contract | ends<javascript:gs.daysAgoEnd(-90) |
| “价值”“成本”“金额”“价格” | total_cost | ast_contract | total_cost>100000 |
| “自动续约”“自动续期” | auto_renew | ast_contract | auto_renew=true |
| “通知期”“退出窗口期” | notice_period | ast_contract | notice_period<=60 |
| “管辖法律”“司法管辖权” | governing_law | ast_contract | governing_lawLIKE[state] |
| “义务”“承诺” | short_description | clm_obligation | short_descriptionLIKE[term] |
| “类型”“类别” | contract_type | ast_contract | contract_type=[value] |
| “有效”“当前”“生效中” | state | ast_contract | state=active |
| “部门”“业务部门” | department | ast_contract | department=[sys_id] |
日期表达式转换
| 自然语言 | 编码查询 |
|---|---|
| “本月到期” | endsBETWEENjavascript:gs.beginningOfThisMonth()@javascript:gs.endOfThisMonth() |
| “下季度到期” | endsBETWEENjavascript:gs.beginningOfNextQuarter()@javascript:gs.endOfNextQuarter() |
| “90 天内到期” | ends<=javascript:gs.daysAgoEnd(-90)^ends>=javascript:gs.daysAgoEnd(0) |
| “去年签署” | startsBETWEENjavascript:gs.beginningOfLastYear()@javascript:gs.endOfLastYear() |
| “2025 年续约” | renewal_dateBETWEEN2025-01-01@2025-12-31 |
| “逾期义务” | due_date<javascript:gs.now()^state!=complete |
操作步骤
第 1 步:解析自然语言查询
分析用户的搜索意图并识别各项要素:
- 实体类型: 合同、义务、条款或供应商
- 筛选条件: 日期范围、金额、状态、相关方
- 排序偏好: 按日期、金额、相关性或风险排序
- 范围: 单份合同、供应商合同组合或完整合同组合
第 2 步:解析字段值
将用户术语映射到 ServiceNow 选项值和引用字段。
解析合同类型值:
Tool: SN-Query-Table
Parameters:
table_name: sys_choice
query: name=ast_contract^element=contract_type
fields: value,label
limit: 50
使用 REST API:
GET /api/now/table/sys_choice?sysparm_query=name=ast_contract^element=contract_type&sysparm_fields=value,label&sysparm_limit=50
按名称解析供应商:
Tool: SN-Query-Table
Parameters:
table_name: core_company
query: nameLIKE[search_term]^vendor=true
fields: sys_id,name,vendor_type
limit: 10
步骤 3:构建增强查询
将解析出的值组合成经过优化的编码查询。
示例:“显示所有与 Acme 签订、价值超过 $100K 且将在未来 6 个月内到期的 SaaS 合同”
逐步转换:
- “SaaS 合同” ->
contract_type=saas(从 sys_choice 解析) - “与 Acme 签订” ->
vendor=[acme_sys_id](从 core_company 解析) - “将在未来 6 个月内到期” ->
ends<=javascript:gs.daysAgoEnd(-180)^ends>=javascript:gs.daysAgoEnd(0) - “价值超过 $100K” ->
total_cost>100000
组合后的查询:
Tool: SN-Query-Table
Parameters:
table_name: ast_contract
query: contract_type=saas^vendor=[acme_sys_id]^ends<=javascript:gs.daysAgoEnd(-180)^ends>=javascript:gs.daysAgoEnd(0)^total_cost>100000^active=true
fields: sys_id,number,short_description,vendor,contract_type,starts,ends,total_cost,auto_renew,notice_period,state
limit: 50
order_by: ends
步骤 4:执行并验证结果
运行查询并验证结果是否符合用户意图。
使用 REST API:
GET /api/now/table/ast_contract?sysparm_query=contract_type=saas^vendor=[acme_sys_id]^ends<=javascript:gs.daysAgoEnd(-180)^ends>=javascript:gs.daysAgoEnd(0)^total_cost>100000^active=true&sysparm_fields=sys_id,number,short_description,vendor,contract_type,starts,ends,total_cost,auto_renew,notice_period&sysparm_limit=50&sysparm_display_value=true
或者,使用自然语言搜索进行模糊匹配:
Tool: SN-Query-Table
Parameters:
table_name: ast_contract
query: contract_type=saas^vendor=[acme_sys_id]^ends<=javascript:gs.daysAgoEnd(-180)^ends>=javascript:gs.daysAgoEnd(0)^total_cost>100000^active=true
limit: 25
步骤 5:根据上下文搜索义务
将与义务相关的查询转换为 CLM 表搜索。
示例:“查找本季度到期的所有供应商数据保护义务”
Tool: SN-Query-Table
Parameters:
table_name: clm_obligation
query: obligation_type=vendor_obligation^short_descriptionLIKEdata protection^due_dateBETWEENjavascript:gs.beginningOfThisQuarter()@javascript:gs.endOfThisQuarter()^active=true
fields: sys_id,short_description,contract,obligation_type,responsible_party,due_date,state,compliance_status,clause_reference
limit: 50
步骤 6:生成查询建议
提供后续查询以细化结果:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var suggestions = {
original_query: 'SaaS contracts with Acme expiring next 6 months over $100K',
results_found: 0,
refinement_suggestions: [],
broadening_suggestions: []
};
// Count results
var ga = new GlideAggregate('ast_contract');
ga.addQuery('contract_type', 'saas');
ga.addQuery('active', true);
ga.addQuery('ends', '<=', gs.daysAgoEnd(-180));
ga.addQuery('ends', '>=', gs.daysAgoEnd(0));
ga.addQuery('total_cost', '>', 100000);
ga.addAggregate('COUNT');
ga.query();
if (ga.next()) suggestions.results_found = parseInt(ga.getAggregate('COUNT'));
if (suggestions.results_found > 20) {
suggestions.refinement_suggestions = [
'Add department filter: "...in the Engineering department"',
'Narrow timeline: "...expiring in the next 30 days"',
'Add renewal filter: "...with auto-renewal enabled"'
];
} else if (suggestions.results_found == 0) {
suggestions.broadening_suggestions = [
'Remove value filter: "SaaS contracts with Acme expiring in 6 months"',
'Expand vendor: "SaaS contracts expiring in 6 months over $100K"',
'Expand type: "All contracts with Acme expiring in 6 months"'
];
}
gs.info('QUERY SUGGESTIONS:\n' + JSON.stringify(suggestions, null, 2));
description: "CLM: Generate query refinement suggestions based on result count"
步骤 7:构建已保存的搜索查询
保存常用查询模式以供重复使用:
Tool: SN-Create-Record
Parameters:
table_name: sys_filter
fields:
title: "Contracts Expiring Next 90 Days - Auto Renew"
table: ast_contract
filter: active=true^auto_renew=true^ends<=javascript:gs.daysAgoEnd(-90)^ends>=javascript:gs.daysAgoEnd(0)
工具用法
| 操作 | MCP 工具 | REST 端点 |
|---|---|---|
| 查询合同 | SN-Query-Table | GET /api/now/table/ast_contract |
| 模糊搜索 | SN-Natural-Language-Search | N/A |
| 解析选项值 | SN-Query-Table | GET /api/now/table/sys_choice |
| 解析供应商 | SN-Query-Table | GET /api/now/table/core_company |
| 查询义务 | SN-Query-Table | GET /api/now/table/clm_obligation |
| 汇总计数 | SN-Execute-Background-Script | POST /api/now/table/sys_trigger |
| 发现字段 | SN-Discover-Table-Schema | GET /api/now/table/sys_dictionary |
最佳实践
- 始终解析引用: 不要将原始文本传入引用字段;先将供应商名称和部门名称解析为 sys_id
- 日期安全性: 使用 JavaScript 日期函数,而非硬编码日期,确保查询长期有效
- 渐进式细化: 从范围更广的查询开始,并提供细化选项,而不是返回零条结果
- 字段验证: 查询非标准字段前,先检查 sys_dictionary,以避免出现“invalid field”错误
- 显示值: 面向用户的结果始终请求
sysparm_display_value=true,以便引用字段显示名称 - 复合查询: 对于 OR 条件,使用
^OR或^NQ(新查询)运算符;仔细测试复杂的布尔逻辑 - 性能: 为所有查询添加
sysparm_limit;使用索引字段(number、sys_id、state)作为主要筛选条件 - 编码: 对 REST 查询参数中的特殊字符进行 URL 编码,尤其是
^、=和日期表达式
故障排除
有合同但查询未返回结果
症状: 自然语言查询转换正确,但返回零条结果
原因: 选项值不匹配(例如,“saas”与“SaaS”或“software_as_a_service”)
解决方案: 始终先从 sys_choice 解析选项值:
Tool: SN-Query-Table
Parameters:
table_name: sys_choice
query: name=ast_contract^element=contract_type^labelLIKESaaS
fields: value,label
limit: 5
日期查询返回意外结果
症状: “下个季度到期”返回了错误时间段内的合同
原因: JavaScript 日期函数使用服务器时区;gs.daysAgoEnd() 从今天开始计算
解决方案: 使用 gs.getProperty('glide.sys.date.format') 验证服务器时区。为确保精确性,使用包含明确季度边界的 BETWEEN。
无法解析供应商名称
症状: 对已知供应商进行查找时未返回结果
原因: core_company 中的供应商名称可能与常用名称不同(例如,“International Business Machines”与“IBM”)
解决方案: 使用 nameLIKE 进行部分匹配,或搜索 name、stock_symbol 和 u_dba_name 字段。
示例
示例 1:续约仪表板查询
用户查询:“显示所有自动续约且需在 60 天内发出通知的合同”
增强查询:
Tool: SN-Query-Table
Parameters:
table_name: ast_contract
query: active=true^auto_renew=true^endsRELATIVELE@dayAgo@-60^endsRELATIVEGE@dayAgo@0
fields: number,short_description,vendor,ends,notice_period,total_cost,contract_administrator
limit: 50
order_by: ends
示例 2:合规审计查询
用户查询:“查找与欧洲供应商签订且未提及 GDPR 的合同”
增强后的查询(两步):
Tool: SN-Query-Table
Parameters:
table_name: ast_contract
query: active=true^vendor.country=Germany^ORvendor.country=France^ORvendor.country=Netherlands^terms_and_conditionsNOT LIKEGDPR
fields: number,short_description,vendor,governing_law,total_cost,ends
limit: 50
示例 3:财务风险敞口查询
用户查询:“今年到期的技术供应商合同总支出是多少?”
增强后的查询:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var ga = new GlideAggregate('ast_contract');
ga.addQuery('active', true);
ga.addQuery('vendor.vendor_type', 'technology');
ga.addQuery('ends', 'BETWEEN', gs.beginningOfThisYear() + '@' + gs.endOfThisYear());
ga.addAggregate('SUM', 'total_cost');
ga.addAggregate('COUNT');
ga.query();
if (ga.next()) {
gs.info('Total contracts: ' + ga.getAggregate('COUNT'));
gs.info('Total spend: $' + ga.getAggregate('SUM', 'total_cost'));
}
description: "CLM: Calculate total spend for technology vendors with contracts expiring this year"
相关技能
legal/contract-metadata-extraction- 从合同记录中提取元数据legal/contract-analysis- 全面的合同风险分析legal/contract-obligation-extraction- 发现并跟踪义务legal/legal-request-triage- 对合同审查请求进行分类itsm/natural-language-queries- 通用自然语言查询技巧