Skip to main content

调试工具

correlationId

每个请求的唯一标识符

validateOnly

验证配置而不执行请求

响应头

查看剪裁、工具使用等信息

日志记录

记录完整的请求响应

使用 correlationId

每个 API 响应都包含 correlationId,用于追踪问题:
const response = await fetch(url, options);
const data = await response.json();

console.log("Correlation ID:", data.correlationId);
// 或从响应头获取
console.log("Correlation ID:", response.headers.get("X-Correlation-Id"));
用途
  • 向技术支持报告问题时提供
  • 在日志系统中关联请求
  • 追踪问题发生的时间点

使用 validateOnly

在正式调用前验证参数配置:
{
  "model": "anthropic/claude-3-7-sonnet-20250219",
  "messages": [...],
  "allowedTools": ["zhipin_reply_generator"],
  "context": {...},
  "validateOnly": true
}
返回验证报告:
{
  "valid": false,
  "model": { "valid": true },
  "tools": [
    {
      "name": "zhipin_reply_generator",
      "valid": false,
      "missingContext": ["configData", "replyPrompts"]
    }
  ]
}

检查响应头

响应头包含有用的调试信息:
const response = await fetch(url, options);

console.log({
  correlationId: response.headers.get("X-Correlation-Id"),
  pruned: response.headers.get("X-Message-Pruned"),
  skippedTools: response.headers.get("X-Tools-Skipped"),
});
响应头说明
X-Correlation-Id请求唯一标识
X-Message-Pruned是否进行了消息剪裁
X-Tools-Skipped被跳过的工具列表

日志记录

完整记录请求和响应:
async function debugChat(message, options = {}) {
  const timestamp = new Date().toISOString();
  const requestId = crypto.randomUUID();

  console.log(`[${timestamp}] Request ${requestId}:`, {
    message,
    options,
  });

  try {
    const response = await chat(message, options);

    console.log(`[${timestamp}] Response ${requestId}:`, {
      correlationId: response.correlationId,
      usage: response.data.usage,
      messageLength: response.data.messages[0].parts[0].text.length,
    });

    return response;
  } catch (error) {
    console.error(`[${timestamp}] Error ${requestId}:`, {
      message: error.message,
      stack: error.stack,
    });

    throw error;
  }
}

常见问题排查

问题:401 认证错误

检查清单
# 1. 验证 API Key 格式
echo $HUAJUNE_API_KEY

# 2. 测试 API Key 是否有效
curl -X GET https://huajune.duliday.com/api/v1/models \
  -H "Authorization: Bearer $HUAJUNE_API_KEY"

# 3. 检查环境变量是否正确加载
node -e "console.log(process.env.HUAJUNE_API_KEY)"

问题:工具无法使用

调试步骤
// 1. 查看可用工具
const tools = await fetch('https://huajune.duliday.com/api/v1/tools', {
  headers: { 'Authorization': `Bearer ${apiKey}` }
}).then(r => r.json());

console.log('Available tools:', tools.data.tools);

// 2. 使用 validateOnly 检查配置
const validation = await fetch('https://huajune.duliday.com/api/v1/chat', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    model: 'anthropic/claude-3-7-sonnet-20250219',
    messages: [{ role: 'user', content: 'test' }],
    allowedTools: ['zhipin_reply_generator'],
    context: { ... },
    validateOnly: true
  })
}).then(r => r.json());

console.log('Validation result:', validation);

问题:响应慢或超时

排查步骤
// 1. 测量响应时间
const start = Date.now();
const response = await chat(message);
const duration = Date.now() - start;

console.log(`Response time: ${duration}ms`);

// 2. 检查消息长度
const totalTokens = messages.reduce((sum, msg) => {
  return sum + estimateTokens(msg.content);
}, 0);

console.log(`Estimated input tokens: ${totalTokens}`);

// 3. 启用消息剪裁
if (totalTokens > 10000) {
  options.prune = true;
  options.pruneOptions = { targetTokens: 8000 };
}

问题:意外的响应内容

调试方法
// 1. 检查系统提示词
console.log("System prompt:", systemPrompt);

// 2. 记录完整的消息历史
console.log("Messages:", JSON.stringify(messages, null, 2));

// 3. 查看实际使用的工具
const response = await chat(message, { allowedTools: ["bash"] });
console.log("Tools used:", response.data.tools.used);
console.log("Tools skipped:", response.data.tools.skipped);

测试工具脚本

创建一个测试脚本帮助调试:
// test-api.js
require("dotenv").config();

async function testAPI() {
  const tests = [
    {
      name: "基础认证测试",
      fn: async () => {
        const response = await fetch(
          "https://huajune.duliday.com/api/v1/models",
          {
            headers: { Authorization: `Bearer ${process.env.HUAJUNE_API_KEY}` },
          }
        );
        return response.ok;
      },
    },
    {
      name: "简单对话测试",
      fn: async () => {
        const response = await chat("你好");
        return response.data.messages.length > 0;
      },
    },
    {
      name: "工具验证测试",
      fn: async () => {
        const response = await chat("test", {
          allowedTools: ["bash"],
          validateOnly: true,
        });
        return response.valid !== undefined;
      },
    },
  ];

  for (const test of tests) {
    try {
      const result = await test.fn();
      console.log(`✅ ${test.name}: ${result ? "PASSED" : "FAILED"}`);
    } catch (error) {
      console.log(`❌ ${test.name}: ERROR`);
      console.error(error.message);
    }
  }
}

testAPI();

性能分析

监控关键指标:
class PerformanceMonitor {
  constructor() {
    this.metrics = [];
  }

  async track(name, fn) {
    const start = Date.now();
    const startMemory = process.memoryUsage().heapUsed;

    try {
      const result = await fn();
      const duration = Date.now() - start;
      const memoryDelta = process.memoryUsage().heapUsed - startMemory;

      this.metrics.push({
        name,
        duration,
        memoryDelta: memoryDelta / 1024 / 1024, // MB
        timestamp: new Date().toISOString(),
      });

      return result;
    } catch (error) {
      this.metrics.push({
        name,
        error: error.message,
        timestamp: new Date().toISOString(),
      });

      throw error;
    }
  }

  report() {
    console.table(this.metrics);

    const avgDuration =
      this.metrics.reduce((sum, m) => sum + (m.duration || 0), 0) /
      this.metrics.length;
    console.log(`Average duration: ${avgDuration.toFixed(2)}ms`);
  }
}

// 使用
const monitor = new PerformanceMonitor();

await monitor.track("Simple chat", () => chat("Hello"));
await monitor.track("With tools", () =>
  chat("List files", { allowedTools: ["bash"] })
);

monitor.report();

下一步