test_knowhub_query.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. """测试 KnowHub 工具表查询功能"""
  2. import httpx
  3. import os
  4. from typing import Any
  5. # KnowHub API 地址
  6. KNOWHUB_API = os.getenv("KNOWHUB_API", "http://43.106.118.91:9999")
  7. def test_list_all_resources():
  8. """测试:列出所有资源"""
  9. print("\n=== 测试:列出所有资源 ===")
  10. try:
  11. resp = httpx.get(f"{KNOWHUB_API}/api/resource", params={"limit": 1000}, timeout=60.0)
  12. resp.raise_for_status()
  13. data = resp.json()
  14. print(f"状态码: {resp.status_code}")
  15. print(f"返回数据类型: {type(data)}")
  16. # 检查返回格式
  17. if isinstance(data, dict):
  18. print(f"返回字典的键: {data.keys()}")
  19. # API 返回格式: {"results": [...], "count": N}
  20. if "results" in data:
  21. data = data["results"]
  22. elif "data" in data:
  23. data = data["data"]
  24. if not isinstance(data, list):
  25. print(f"⚠️ 返回数据不是列表")
  26. return []
  27. print(f"总资源数: {len(data)}")
  28. # 过滤出工具
  29. tools = [r for r in data if isinstance(r, dict) and r.get("id", "").startswith("tools/")]
  30. print(f"工具数量: {len(tools)}")
  31. if tools:
  32. print("\n前 3 个工具:")
  33. for tool in tools[:3]:
  34. print(f" - {tool['id']}: {tool.get('title', 'N/A')}")
  35. return tools
  36. except Exception as e:
  37. print(f"❌ 错误: {e}")
  38. import traceback
  39. traceback.print_exc()
  40. return []
  41. def test_get_tool_detail(tool_id: str):
  42. """测试:获取工具详情"""
  43. print(f"\n=== 测试:获取工具详情 ({tool_id}) ===")
  44. try:
  45. resp = httpx.get(f"{KNOWHUB_API}/api/resource/{tool_id}", timeout=10.0)
  46. resp.raise_for_status()
  47. tool = resp.json()
  48. print(f"状态码: {resp.status_code}")
  49. print(f"ID: {tool['id']}")
  50. print(f"标题: {tool.get('title', 'N/A')}")
  51. metadata = tool.get("metadata", {})
  52. print(f"\nMetadata:")
  53. for key, value in metadata.items():
  54. # 长列表截断显示
  55. if isinstance(value, list) and len(value) > 3:
  56. print(f" - {key}: [{len(value)} items] {value[:3]}...")
  57. else:
  58. print(f" - {key}: {value}")
  59. return tool
  60. except Exception as e:
  61. print(f"❌ 错误: {e}")
  62. return None
  63. def test_search_tools_by_category(category: str):
  64. """测试:按分类搜索工具"""
  65. print(f"\n=== 测试:按分类搜索工具 (category={category}) ===")
  66. try:
  67. resp = httpx.get(f"{KNOWHUB_API}/api/resource", params={"limit": 1000}, timeout=60.0)
  68. resp.raise_for_status()
  69. data = resp.json()
  70. # 检查返回格式
  71. if isinstance(data, dict):
  72. # API 返回格式: {"results": [...], "count": N}
  73. if "results" in data:
  74. data = data["results"]
  75. elif "data" in data:
  76. data = data["data"]
  77. if not isinstance(data, list):
  78. print(f"⚠️ 返回数据不是列表")
  79. return []
  80. # 客户端过滤
  81. tools = [
  82. r for r in data
  83. if isinstance(r, dict) and r.get("id", "").startswith("tools/")
  84. and r.get("metadata", {}).get("category") == category
  85. ]
  86. print(f"找到 {len(tools)} 个 {category} 类工具:")
  87. for tool in tools[:5]:
  88. print(f" - {tool['id']}: {tool.get('title', 'N/A')}")
  89. return tools
  90. except Exception as e:
  91. print(f"❌ 错误: {e}")
  92. import traceback
  93. traceback.print_exc()
  94. return []
  95. def test_search_knowledge_by_tool(query: str, top_k: int = 5):
  96. """测试:搜索工具相关知识"""
  97. print(f"\n=== 测试:搜索工具相关知识 (query={query}) ===")
  98. try:
  99. resp = httpx.get(
  100. f"{KNOWHUB_API}/api/knowledge/search",
  101. params={"q": query, "top_k": top_k, "min_score": 3},
  102. timeout=60.0
  103. )
  104. resp.raise_for_status()
  105. results = resp.json()
  106. print(f"状态码: {resp.status_code}")
  107. print(f"返回数据类型: {type(results)}")
  108. # 检查返回格式
  109. if isinstance(results, dict):
  110. print(f"返回字典的键: {results.keys()}")
  111. if "results" in results:
  112. results = results["results"]
  113. elif "data" in results:
  114. results = results["data"]
  115. if not isinstance(results, list):
  116. print(f"⚠️ 返回数据不是列表")
  117. return []
  118. print(f"找到 {len(results)} 条知识:")
  119. for i, item in enumerate(results[:3], 1):
  120. if isinstance(item, dict):
  121. print(f"\n {i}. {item.get('id', 'N/A')}")
  122. title = item.get('title', 'N/A')
  123. print(f" 标题: {title[:50] if isinstance(title, str) else title}")
  124. print(f" 分数: {item.get('score', 0):.2f}")
  125. print(f" 关联工具: {item.get('resource_ids', [])}")
  126. return results
  127. except Exception as e:
  128. print(f"❌ 错误: {e}")
  129. import traceback
  130. traceback.print_exc()
  131. return []
  132. def test_list_tool_knowledge(tags: str = "tool"):
  133. """测试:列出所有工具相关知识"""
  134. print(f"\n=== 测试:列出所有工具相关知识 (tags={tags}) ===")
  135. try:
  136. resp = httpx.get(
  137. f"{KNOWHUB_API}/api/knowledge",
  138. params={"tags": tags, "status": "approved,checked", "page_size": 200},
  139. timeout=60.0
  140. )
  141. resp.raise_for_status()
  142. results = resp.json()
  143. print(f"状态码: {resp.status_code}")
  144. print(f"返回数据类型: {type(results)}")
  145. # 检查返回格式
  146. if isinstance(results, dict):
  147. print(f"返回字典的键: {results.keys()}")
  148. if "results" in results:
  149. results = results["results"]
  150. elif "data" in results:
  151. results = results["data"]
  152. elif "items" in results:
  153. results = results["items"]
  154. if not isinstance(results, list):
  155. print(f"⚠️ 返回数据不是列表")
  156. return []
  157. print(f"找到 {len(results)} 条工具知识")
  158. if results:
  159. print("\n前 3 条:")
  160. for item in results[:3]:
  161. if isinstance(item, dict):
  162. title = item.get('title', 'N/A')
  163. print(f" - {item.get('id', 'N/A')}: {title[:40] if isinstance(title, str) else title}")
  164. print(f" 关联工具: {item.get('resource_ids', [])}")
  165. return results
  166. except Exception as e:
  167. print(f"❌ 错误: {e}")
  168. import traceback
  169. traceback.print_exc()
  170. return []
  171. def main():
  172. """运行所有测试"""
  173. print(f"KnowHub API: {KNOWHUB_API}")
  174. print("=" * 60)
  175. # 1. 列出所有资源
  176. tools = test_list_all_resources()
  177. # 2. 获取 ComfyUI 工具详情(验证 toolhub_items)
  178. test_get_tool_detail("tools/image_gen/comfyui")
  179. # 3. 获取第一个工具的详情
  180. if tools:
  181. first_tool_id = tools[0]["id"]
  182. if first_tool_id != "tools/image_gen/comfyui":
  183. test_get_tool_detail(first_tool_id)
  184. # 3. 按分类搜索
  185. test_search_tools_by_category("plugin")
  186. # 4. 搜索工具相关知识
  187. test_search_knowledge_by_tool("IP-Adapter")
  188. # 5. 列出所有工具知识
  189. test_list_tool_knowledge()
  190. print("\n" + "=" * 60)
  191. print("测试完成!")
  192. if __name__ == "__main__":
  193. main()