test_tool_description_boundaries.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import unittest
  2. from tools.export_out_of_province_port_data import (
  3. ExportOutOfProvincePortDataTool,
  4. )
  5. from tools.export_pending_outbound_orders import ExportPendingOutboundOrdersTool
  6. from tools.list_order_filter_options import ListOrderFilterOptionsTool
  7. from tools.list_pending_outbound_export_filter_options import (
  8. ListPendingOutboundExportFilterOptionsTool,
  9. )
  10. from tools.query_customs_declaration_files import QueryCustomsDeclarationFilesTool
  11. from tools.query_order import QueryOrderTool
  12. from tools.query_order_detail import QueryOrderDetailTool
  13. from tools.query_order_exact import QueryOrderExactTool
  14. from tools.query_outbound_detail import QueryOutboundDetailTool
  15. from tools.query_outbound_list import QueryOutboundListTool
  16. from tools.query_track import QueryTrackTool
  17. class ToolDescriptionBoundaryTest(unittest.TestCase):
  18. def test_every_existing_tool_states_use_and_prohibition_boundaries(self):
  19. tools = (
  20. QueryOrderTool(),
  21. QueryOrderExactTool(),
  22. QueryTrackTool(),
  23. QueryCustomsDeclarationFilesTool(),
  24. QueryOutboundListTool(),
  25. QueryOutboundDetailTool(),
  26. ListOrderFilterOptionsTool(),
  27. ListPendingOutboundExportFilterOptionsTool(),
  28. ExportPendingOutboundOrdersTool(),
  29. ExportOutOfProvincePortDataTool(),
  30. )
  31. for tool in tools:
  32. with self.subTest(tool=tool.name):
  33. description = tool.metadata()['description']
  34. self.assertIn('使用场景:', description)
  35. self.assertIn('禁止使用:', description)
  36. def test_number_tools_require_clarification_and_forbid_trial_queries(self):
  37. tools = (
  38. QueryOrderTool(),
  39. QueryOrderExactTool(),
  40. QueryTrackTool(),
  41. QueryCustomsDeclarationFilesTool(),
  42. QueryOutboundListTool(),
  43. QueryOutboundDetailTool(),
  44. ExportOutOfProvincePortDataTool(),
  45. )
  46. for tool in tools:
  47. with self.subTest(tool=tool.name):
  48. description = tool.metadata()['description']
  49. self.assertIn('号码类型不明确时必须先询问用户', description)
  50. self.assertIn('不得根据号码格式猜测', description)
  51. self.assertIn('不得跨字段或跨工具试查', description)
  52. def test_result_intent_distinguishes_adjacent_tools(self):
  53. expected = {
  54. QueryOrderTool(): ('旧版跨字段通用搜索', 'query_order_exact', '订单列表'),
  55. QueryOrderExactTool(): ('订单列表', 'query_order_detail', '排舱列表'),
  56. QueryOrderDetailTool(): ('单个订单的详情', '逐个调用', 'query_order_exact', '订单列表'),
  57. QueryTrackTool(): ('物流轨迹', '订单资料', '报关资料文件'),
  58. QueryCustomsDeclarationFilesTool(): ('报关资料文件', '完整排舱详情', '文件链接'),
  59. QueryOutboundListTool(): ('排舱列表', '19个字段', '排舱详情'),
  60. QueryOutboundDetailTool(): ('排舱详情', '11项汇总', '34项订单明细'),
  61. ListOrderFilterOptionsTool(): ('query_order_exact', '授权筛选值', '业务数据'),
  62. ListPendingOutboundExportFilterOptionsTool(): (
  63. 'export_pending_outbound_orders', '授权筛选值', 'query_outbound_list',
  64. ),
  65. ExportPendingOutboundOrdersTool(): ('明确要求导出', '未排舱订单', '查看或查询'),
  66. ExportOutOfProvincePortDataTool(): ('明确要求导出', '省外进港资料', '普通排舱查询'),
  67. }
  68. for tool, phrases in expected.items():
  69. with self.subTest(tool=tool.name):
  70. description = tool.metadata()['description']
  71. for phrase in phrases:
  72. self.assertIn(phrase, description)
  73. def test_outbound_number_fields_require_explicit_business_types(self):
  74. properties = QueryOutboundListTool().metadata()['input_schema']['properties']
  75. for field, label in (
  76. ('outbound_numbers', '排舱单号'),
  77. ('order_numbers', '订单号'),
  78. ('container_codes', '柜号'),
  79. ('so_numbers', 'SO号'),
  80. ('bl_numbers', '提单号'),
  81. ):
  82. with self.subTest(field=field):
  83. description = properties[field]['description']
  84. self.assertIn(label, description)
  85. self.assertIn('仅当用户明确', description)
  86. self.assertIn('不得放入其他类型号码', description)
  87. if __name__ == '__main__':
  88. unittest.main()