""" 豆包 LLM 接口参数变更审核模块。 仅审核 Controller 层接口参数的增删改,不对 Java 源码做通用代码审查。 """ import json from typing import Any, Dict, List, Optional import requests from comparator import EndpointChangeReport def is_llm_enabled(config: Dict[str, Any]) -> bool: """ 判断大模型总开关是否开启。 :param config: 完整配置字典 :return: True=启用 LLM 审核 """ return config.get("llm", {}).get("enabled", True) def call_doubao_api( api_key: str, prompt: str, config: Dict[str, Any], ) -> Optional[str]: """ 调用火山引擎豆包 Chat Completions API。 :param api_key: API Key :param prompt: 用户提示词 :param config: 完整配置 :return: LLM 回复文本;失败返回 None """ if not api_key or api_key == "YOUR_DOUBAO_API_KEY": print("[警告] 未配置豆包 API Key,跳过 LLM 审核。") return None llm_cfg = config.get("llm", {}) model = llm_cfg.get("model") or llm_cfg.get("endpoint_id", "") if not model: print("[警告] 未配置 llm.model 或 llm.endpoint_id,跳过 LLM 审核。") return None api_url = llm_cfg.get( "api_url", "https://ark.cn-beijing.volces.com/api/v3/chat/completions" ) timeout = llm_cfg.get("timeout") headers = { "Content-Type": "application/json", "Authorization": f"Bearer {api_key}", } payload = { "model": model, "messages": [ { "role": "system", "content": ( "你是 Java Spring Boot Controller 接口参数变更分析专家。" "你的职责是识别并整理 Controller 层接口参数的增、删、改、重命名," "确认 AST 解析结果是否准确,并指出对调用方的兼容性影响。" ), }, {"role": "user", "content": prompt}, ], "temperature": 0.1, } try: kwargs = {"headers": headers, "json": payload} if timeout is not None: kwargs["timeout"] = timeout resp = requests.post(api_url, **kwargs) resp.raise_for_status() data = resp.json() if "choices" in data and data["choices"]: return data["choices"][0]["message"]["content"] print("[错误] AI 返回格式异常") return None except requests.RequestException as exc: print(f"[错误] 豆包 API 调用失败: {exc}") return None def build_parameter_change_prompt( reports: List[EndpointChangeReport], changed_files: List[str], git_diff: str = "", ) -> str: """ 构造接口参数变更审核提示词(对齐第一版需求:识别 Controller 参数增删改)。 :param reports: AST 解析对比结果 :param changed_files: 本次变更的 Controller 文件列表 :param git_diff: 相关文件的 Git diff 内容 :return: 完整 prompt """ ast_report = [] for r in reports: ast_report.append( { "uri": f"{r.http_method} {r.uri}", "controller": r.controller_class, "method": r.method_name, "is_new_endpoint": r.is_new_endpoint, "is_removed_endpoint": r.is_removed_endpoint, "parameter_changes": [ { "type": c.change_type.value, "name": c.param_name, "java_type": c.param_type, "old_name": c.old_name, "old_type": c.old_type, "required": c.required, "detail": c.detail, } for c in r.parameter_changes ], } ) diff_block = git_diff.strip() if git_diff.strip() else "(无 diff 内容)" if len(diff_block) > 8000: diff_block = diff_block[:8000] + "\n... [diff 过长,已截断]" return f"""请审核以下 Controller 层接口参数变更,整理并确认变更结果。 ## 变更的 Controller 文件 {json.dumps(changed_files, ensure_ascii=False)} ## AST 自动解析的参数变更报告 {json.dumps(ast_report, ensure_ascii=False, indent=2)} ## Git Diff(Controller 相关) ```diff {diff_block} ``` ## 审核要求 1. 逐条确认 AST 报告的参数变更是否准确(增/删/改/重命名) 2. 若 AST 有遗漏,补充遗漏的接口参数变更 3. 若 AST 有误报,指出并修正 4. 按以下格式整理每个接口的变更(与通知模板一致): URI: GET /api/xxx 参数变更: - 删除: Boolean userType - 新增: Boolean includeDisabled (是否必填:false) - 重命名: String userName -> String accountName 5. 简要说明是否存在破坏性变更(影响前端/调用方) 6. 用中文回复,简洁清晰 """ def review_parameter_changes( reports: List[EndpointChangeReport], config: Dict[str, Any], changed_files: List[str], git_diff: str = "", ) -> Optional[str]: """ 使用 LLM 审核 Controller 接口参数变更(AST 结果的二次确认与整理)。 :param reports: AST 对比报告 :param config: 完整配置 :param changed_files: 变更的 Controller 文件 :param git_diff: Git diff 文本 :return: LLM 整理后的审核结论;未启用或无报告时返回 None """ if not is_llm_enabled(config): print("[LLM] 大模型开关已关闭,跳过接口参数变更审核。") return None if not reports: return None llm_cfg = config.get("llm", {}) prompt = build_parameter_change_prompt(reports, changed_files, git_diff) return call_doubao_api(llm_cfg.get("api_key", ""), prompt, config)