import argparse import os import sys from pathlib import Path # 直接复用你在 test.py 里已经配置好的 client(里面含有 API Key 和 base_url) try: from test import client # type: ignore except Exception as import_error: # noqa: PIE786 raise SystemExit( "无法从 test.py 导入 client。请先确保 test.py 能正常运行,或在此脚本中自行创建 client。" ) from import_error def detect_language_by_suffix(file_path: Path) -> str: suffix = file_path.suffix.lower() mapping = { ".py": "python", ".js": "javascript", ".ts": "typescript", ".tsx": "tsx", ".jsx": "jsx", ".java": "java", ".go": "go", ".rs": "rust", ".rb": "ruby", ".php": "php", ".cs": "csharp", ".cpp": "cpp", ".cc": "cpp", ".cxx": "cpp", ".c": "c", ".h": "c", ".json": "json", ".yaml": "yaml", ".yml": "yaml", ".md": "markdown", ".sql": "sql", ".sh": "bash", ".ps1": "powershell", } return mapping.get(suffix, "") def read_text_file(file_path: Path) -> str: try: return file_path.read_text(encoding="utf-8") except UnicodeDecodeError: # 回退到系统默认编码 return file_path.read_text(errors="replace") def build_messages(code_path: Path, code_content: str, instruction: str): language = detect_language_by_suffix(code_path) system_prompt = ( "你是严谨的代码审查与重构助手,请用中文回答。" "输出请使用结构化 Markdown,包含:\n" "1) 概览\n2) 问题清单(按严重程度排序,标注位置/片段)\n" "3) 可执行的修复建议\n4) 示例修复代码(只给关键片段)\n" "5) 边界与测试要点\n" "除非必要,不要重复粘贴整份源码。" ) user_prompt = ( f"任务:{instruction.strip()}\n" f"文件:{code_path.name}\n" "代码如下:\n" f"```{language}\n{code_content}\n```" ) return [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}, ] def analyze_file(input_path: Path, output_path: Path, instruction: str, model: str = "deepseek-chat") -> None: code = read_text_file(input_path) messages = build_messages(input_path, code, instruction) resp = client.chat.completions.create( model=model, messages=messages, stream=False, temperature=0.2, ) content = resp.choices[0].message.content if resp.choices else "" output_path.write_text(content, encoding="utf-8") def main(argv: list[str]) -> int: parser = argparse.ArgumentParser( description="分析指定代码文件,输出结构化反馈到文件(复用 test.py 的 client)", ) parser.add_argument("input", help="要分析的源代码文件路径") parser.add_argument("output", help="把反馈写入到的目标文件路径,例如 review.md") parser.add_argument( "--instruction", default="请找出代码问题、潜在缺陷、可读性/性能/安全改进,并给出修复建议", help="自定义任务说明(可选)", ) parser.add_argument( "--model", default="deepseek-chat", help="模型名称(默认 deepseek-chat)", ) args = parser.parse_args(argv) input_path = Path(args.input).expanduser().resolve() output_path = Path(args.output).expanduser().resolve() if not input_path.exists(): raise SystemExit(f"输入文件不存在: {input_path}") output_path.parent.mkdir(parents=True, exist_ok=True) analyze_file(input_path, output_path, args.instruction, model=args.model) print(f"分析完成,结果已写入: {output_path}") return 0 if __name__ == "__main__": raise SystemExit(main(sys.argv[1:]))