教程演示用Oxlo.ai API构建Python性能监控脚本,自动测量函数执行时间、提取静态复杂度指标并生成优化建议报告,适合接入CI流程做自动化初筛。
最近我上线了一个内部工具,可以对 Python 函数进行性能分析,并通过 LLM 诊断性能瓶颈。在本教程中,我们将构建一个轻量级 Agent,它可以测量执行时间、提取静态复杂度指标,并通过 Oxlo.ai 生成优化报告。对于希望在昂贵的人工审查之前获得自动化初轮代码审查的团队来说,这非常有用。
需要准备一个来自 https://portal.oxlo.ai 的 Oxlo.ai API Key
以及 OpenAI SDK:pip install openai
我每个项目都从一个单文件和一个具体目标开始。创建 perf_monitor.py,并添加一个故意低效的函数,这样我们就有了一个真实的瓶颈可以检测。同时添加一个简单的计时器,用已知输入运行该函数。
import time
import ast
import json
from openai import OpenAI
TARGET_CODE = '''
def find_duplicates(data):
result = []
for i in range(len(data)):
for j in range(i + 1, len(data)):
if data[i] == data[j] and data[i] not in result:
result.append(data[i])
return result
'''
def benchmark():
namespace = {}
exec(TARGET_CODE, namespace)
fn = namespace["find_duplicates"]
test_data = list(range(500)) + [250]
start = time.perf_counter()
result = fn(test_data)
elapsed = time.perf_counter() - start
return elapsed, result
仅有原始的计时数据是不够的。我遍历 AST 来计算循环和分支数量,这样模型就能得到硬数字,而不是从原始文本中猜测结构。
def extract_metrics(source: str):
tree = ast.parse(source)
loops = sum(
1 for node in ast.walk(tree)
if isinstance(node, (ast.For, ast.While))
)
conditionals = sum(
1 for node in ast.walk(tree)
if isinstance(node, (ast.If, ast.IfExp))
)
return {
"loops": loops,
"conditionals": conditionals,
"lines": len([l for l in source.splitlines() if l.strip()]),
}
Agent 的个性体现在系统提示词中。我保持它的严格和结构化,这样输出是可预测的,便于下游解析。
SYSTEM_PROMPT = """You are a senior performance engineer.
Analyze the provided Python function using its source code, static metrics, and execution time.
Identify algorithmic complexity bottlenecks, redundant work, and memory inefficiencies.
Respond with valid JSON containing exactly these keys:
- summary: one sentence describing the core issue
- complexity_analysis: explanation of time and space complexity
- recommendations: list of specific, actionable fixes
- refactored_code: a corrected Python implementation
Be concise. Do not include markdown fencing around the JSON."""
我使用 Oxlo.ai,因为它的按请求计费模式即使将大型模块或长堆栈跟踪传入提示词也不会像按 token 计费的提供商那样推高成本。对于代码分析,我选择 deepseek-v3.2,它在免费层可用,且处理推理任务表现良好。客户端是 OpenAI SDK 的直接替代品。
user_message = (
f"Function source:\n{TARGET_CODE}\n\n"
f"Static metrics: {json.dumps(metrics)}\n"
f"Execution time (seconds): {elapsed:.6f}\n"
f"Test output length: {len(output)}"
)
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
response = client.chat.completions.create(
model="deepseek-v3.2",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
)
report = response.choices[0].message.content
最后,我将各个部分粘合在一个 main 块中,这样脚本可以直接运行。
if __name__ == "__main__":
elapsed, output = benchmark()
metrics = extract_metrics(TARGET_CODE)
print(f"Elapsed: {elapsed:.6f}s | Metrics: {metrics}")
user_message = (
f"Function source:\n{TARGET_CODE}\n\n"
f"Static metrics: {json.dumps(metrics)}\n"
f"Execution time (seconds): {elapsed:.6f}\n"
f"Test output length: {len(output)}"
)
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
response = client.chat.completions.create(
model="deepseek-v3.2",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
)
print("\n--- Performance Report ---\n")
print(response.choices[0].message.content)
安装依赖,设置你的 Key,然后执行监控器。
pip install openai
export OXLO_API_KEY="sk-..."
python perf_monitor.py
在我的机器上输出如下:
Elapsed: 0.024531s | Metrics: {'loops': 2, 'conditionals': 2, 'lines': 7}
--- Performance Report ---
{
"summary": "The function uses nested loops with an O(n^2) scan and a linear membership test inside the inner loop, creating O(n^3) behavior in the worst case.",
"complexity_analysis": "The two nested for loops generate n*(n-1)/2 comparisons. The guard `data[i] not in result` scans the result list on every match, adding an extra O(n) factor and heavy constant-time overhead.",
"recommendations": [
"Replace nested iteration with a single pass using a set for O(1) lookups.",
"Use two sets, `seen` and `duplicates`, to eliminate the linear `not in` check."
],
"refactored_code": "def find_duplicates(data):\n seen = set()\n dups = set()\n for item in data:\n if item in seen:\n dups.add(item)\n else:\n seen.add(item)\n return list(dups)"
}
这个 Agent 让你对算法瓶颈有了自动化的初轮审查。由于 Oxlo.ai 按请求收费而非按 token 收费,将整个模块或长堆栈跟踪传入上下文窗口不会像按 token 计费的提供商那样推高账单。你可以在 https://oxlo.ai/pricing 查看详细定价。
两个具体的后续步骤:将其集成到 pre-commit hook 中,让开发者在推送前获得即时反馈;或者扩展 AST visitor 来使用 radon 计算圈复杂度,并添加延迟回归检查,当重构后变慢超过百分之十时让 CI 失败。