| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- """
- 需求管理工具 - KnowHub Requirement API 封装
- 提供需求的向量检索和列表查询能力,
- 让 Agent 在提取新需求前可以先了解已有的需求库。
- """
- import os
- import json
- import logging
- import httpx
- from typing import Optional
- from agent.tools import tool, ToolResult, ToolContext
- logger = logging.getLogger(__name__)
- KNOWHUB_API = os.getenv("KNOWHUB_API", "http://localhost:8000").rstrip("/")
- @tool(
- hidden_params=["context"],
- display={
- "zh": {
- "name": "需求检索",
- "params": {
- "query": "搜索关键词",
- "top_k": "返回数量",
- }
- },
- "en": {
- "name": "Search Requirements",
- "params": {
- "query": "Search query",
- "top_k": "Number of results",
- }
- }
- }
- )
- async def requirement_search(
- query: str,
- top_k: int = 20,
- context: Optional[ToolContext] = None,
- ) -> ToolResult:
- """向量检索需求库,根据语义相似度返回最相关的需求。用于在提取新需求前了解已有需求,避免重复。"""
- try:
- params = {"q": query, "top_k": top_k}
- async with httpx.AsyncClient(timeout=30.0) as client:
- res = await client.get(f"{KNOWHUB_API}/api/requirement/search", params=params)
- res.raise_for_status()
- data = res.json()
- results = data.get("results", data) if isinstance(data, dict) else data
- items = results if isinstance(results, list) else []
- count = len(items)
- if count == 0:
- return ToolResult(
- title="需求检索完成",
- output="未找到相关需求。",
- long_term_memory=f"需求检索: 未找到与 '{query[:50]}' 相关的需求",
- )
- output = json.dumps(data, ensure_ascii=False, indent=2)
- return ToolResult(
- title=f"需求检索完成 -- 找到 {count} 条",
- output=output,
- long_term_memory=f"需求检索: 找到 {count} 条与 '{query[:50]}' 相关的需求",
- metadata={"count": count, "items": items},
- )
- except httpx.ConnectError:
- msg = f"无法连接到 KnowHub 服务 ({KNOWHUB_API}),请确认服务是否启动。"
- return ToolResult(title="需求检索失败", output=msg, error=msg)
- except Exception as e:
- return ToolResult(title="需求检索失败", output=str(e), error=str(e))
- @tool(
- hidden_params=["context"],
- display={
- "zh": {
- "name": "需求列表",
- "params": {
- "limit": "返回数量",
- "offset": "偏移量",
- }
- },
- "en": {
- "name": "List Requirements",
- "params": {
- "limit": "Number of results",
- "offset": "Offset",
- }
- }
- }
- )
- async def requirement_list(
- limit: int = 20,
- offset: int = 0,
- context: Optional[ToolContext] = None,
- ) -> ToolResult:
- """列出需求库中的已有需求,用于浏览和了解需求全貌。"""
- try:
- params = {"limit": limit, "offset": offset}
- async with httpx.AsyncClient(timeout=30.0) as client:
- res = await client.get(f"{KNOWHUB_API}/api/requirement/list", params=params)
- res.raise_for_status()
- data = res.json()
- results = data.get("results", data) if isinstance(data, dict) else data
- items = results if isinstance(results, list) else []
- count = len(items)
- if count == 0:
- return ToolResult(
- title="需求列表为空",
- output="需求库中暂无需求。",
- long_term_memory="需求列表: 需求库为空",
- )
- output = json.dumps(data, ensure_ascii=False, indent=2)
- return ToolResult(
- title=f"需求列表 -- 共 {count} 条",
- output=output,
- long_term_memory=f"需求列表: 获取了 {count} 条需求 (offset={offset})",
- metadata={"count": count, "items": items},
- )
- except httpx.ConnectError:
- msg = f"无法连接到 KnowHub 服务 ({KNOWHUB_API}),请确认服务是否启动。"
- return ToolResult(title="需求列表获取失败", output=msg, error=msg)
- except Exception as e:
- return ToolResult(title="需求列表获取失败", output=str(e), error=str(e))
|