Programmatic Tool Calling

故障排除

常见问题及解决方案

故障排除

常见错误

aiohttp 依赖缺失

错误信息:

Error: aiohttp is required. Install it with: pip install aiohttp

原因: Python 环境缺少 aiohttp

解决方案:

pip install aiohttp

验证安装:

python3 -c "import aiohttp; print(aiohttp.__version__)"

桥接服务器未启动

错误信息:

Connection error: Cannot connect to host localhost:8080

原因: HTTP 桥接服务器未启动

诊断步骤:

  1. 检查服务器是否运行
curl http://localhost:8080/health
  1. 检查端口占用
lsof -i :8080
  1. 查看进程日志
// 在 Go 代码中添加日志
if err := server.StartAsync(); err != nil {
    log.Printf("服务器启动失败: %v", err)
}

解决方案:

// 使用不同端口
codeExec.SetBridgeURL("http://localhost:9000")
server := bridge.NewHTTPBridgeServer(toolBridge, "localhost:9000")

Python 执行超时

错误信息:

execution timeout

原因: 代码执行时间超过配置的超时限制

解决方案:

// 增加超时时间
config := &bridge.RuntimeConfig{
    Timeout: 60 * time.Second,  // 从 30s 增加到 60s
}

runtime := bridge.NewPythonRuntime(config)

优化建议:

  • 使用并发减少执行时间
  • 避免阻塞操作
  • 检查是否有死循环

工具调用失败

错误信息:

Tool Read failed: file not found

原因: 工具执行失败(业务逻辑错误)

调试步骤:

  1. 直接测试工具
# 测试 HTTP 接口
curl -X POST http://localhost:8080/tools/call \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "Read",
    "input": {"path": "test.txt"}
  }'
  1. 检查输入参数
# 在 Python 代码中打印参数
import sys
print(f"调用 Read, path={path}", file=sys.stderr)
result = await Read(path=path)
  1. 捕获异常
try:
    result = await Read(path="nonexistent.txt")
except Exception as e:
    print(f"详细错误: {type(e).__name__}: {e}")
    # 使用默认值
    result = ""

AllowedCallers 配置错误

错误信息:

Tool XXX is not allowed in code_execution context

原因: 工具的 AllowedCallers 未包含 code_execution_20250825

解决方案:

// 修改工具配置
toolSchema := provider.ToolSchema{
    Name: "Read",
    Description: "...",
    InputSchema: {...},
    // 添加 code_execution 权限
    AllowedCallers: []string{"direct", "code_execution_20250825"},
}

检查清单:

  • ✅ 工具在 ToolSchema 中定义
  • ✅ AllowedCallers 包含正确值
  • ✅ 工具已注册到 Registry
  • ✅ CodeExecute 工具能访问 Registry

性能问题

调用延迟过高

症状: 每次工具调用需要 100ms+

诊断:

// 添加性能日志
start := time.Now()
result, _ := tool.Execute(ctx, input, tc)
latency := time.Since(start)
log.Printf("Tool %s latency: %v", name, latency)

可能原因和解决方案:

// 使用本地桥接服务器
codeExec.SetBridgeURL("http://localhost:8080")  // ✅
// 而不是
codeExec.SetBridgeURL("http://remote-server:8080")  // ❌

内存占用过高

症状: Go 进程内存持续增长

诊断:

import "runtime"

// 打印内存统计
var m runtime.MemStats
runtime.ReadMemStats(&m)
log.Printf("Alloc = %v MB, TotalAlloc = %v MB, Sys = %v MB",
    m.Alloc/1024/1024, m.TotalAlloc/1024/1024, m.Sys/1024/1024)

可能原因:

  1. Schema 缓存未清理
    • 缓存有 TTL,会自动过期
    • 检查缓存大小是否合理
  2. HTTP 连接泄漏
    • 确保 Python 会话正确关闭
    • SDK 已在 __aexit__ 中实现清理
  3. 临时文件未删除
    • Runtime 会自动删除
    • 检查 /tmp/aster_*.py 文件

调试技巧

启用详细日志

import "log"

func main() {
    // 设置日志格式
    log.SetFlags(log.LstdFlags | log.Lshortfile)

    // 会输出:
    // 2025/01/30 10:30:45 http_server.go:179: HTTP Bridge Server listening on localhost:8080
    // 2025/01/30 10:30:46 tool_bridge.go:45: Calling tool Read with input map[path:test.txt]
}

Python 代码调试

import sys

# 输出到 stderr 避免干扰结果
print("=== 调试信息 ===", file=sys.stderr)

# 打印可用的全局变量
import pprint
pprint.pprint({k: v for k, v in globals().items() if not k.startswith('_')},
              stream=sys.stderr)

# 执行并捕获详细错误
try:
    result = await Read(path="test.txt")
    print(f"✅ 成功: {len(result)} 字节", file=sys.stderr)
except Exception as e:
    import traceback
    print("❌ 错误:", file=sys.stderr)
    traceback.print_exc(file=sys.stderr)
    raise

查看生成的 Python 代码

// 在 runtime.go 中临时修改
func (r *PythonRuntime) Execute(ctx context.Context, code string, input map[string]any) (*ExecutionResult, error) {
    wrappedCode := r.wrapCode(code, input)

    // 打印生成的代码
    log.Printf("=== Generated Python Code ===\n%s\n", wrappedCode)

    // ... 继续执行
}

测试 HTTP 端点

# 1. 健康检查
curl http://localhost:8080/health

# 2. 列出工具
curl http://localhost:8080/tools/list | jq

# 3. 获取 Schema
curl "http://localhost:8080/tools/schema?name=Read" | jq

# 4. 调用工具
curl -X POST http://localhost:8080/tools/call \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "Read",
    "input": {"path": "README.md"}
  }' | jq

# 5. 测试错误处理
curl -X POST http://localhost:8080/tools/call \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "Read",
    "input": {"path": "/nonexistent/file.txt"}
  }' | jq

性能分析

import _ "net/http/pprof"

func main() {
    // 启动 pprof 服务器
    go func() {
        log.Println(http.ListenAndServe("localhost:6060", nil))
    }()

    // ... 正常逻辑
}
# CPU 分析
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30

# 内存分析
go tool pprof http://localhost:6060/debug/pprof/heap

# Goroutine 分析
go tool pprof http://localhost:6060/debug/pprof/goroutine

环境问题

Python 版本不兼容

要求: Python 3.7+

检查版本:

python3 --version

解决方案:

# macOS
brew install python@3.11

# Ubuntu
sudo apt install python3.11

# 使用 pyenv
pyenv install 3.11.0
pyenv global 3.11.0

依赖冲突

症状: aiohttp 安装失败或版本冲突

解决方案:

python3 -m venv venv
source venv/bin/activate
pip install aiohttp

生产环境建议

监控配置

// 添加健康检查端点监控
go func() {
    ticker := time.NewTicker(30 * time.Second)
    for range ticker.C {
        resp, err := http.Get("http://localhost:8080/health")
        if err != nil || resp.StatusCode != 200 {
            log.Printf("⚠️  Bridge server unhealthy")
            // 发送告警
        }
    }
}()

错误处理

// 生产环境应该捕获所有错误
result, err := tool.Execute(ctx, input, tc)
if err != nil {
    // 记录详细错误
    log.Printf("Tool execution failed: %v, input: %+v", err, input)

    // 返回友好错误
    return map[string]any{
        "success": false,
        "error":   "Internal server error",
    }, nil
}

资源限制

// 限制并发执行数
var sem = make(chan struct{}, 10)  // 最多10个并发

func executeWithLimit(ctx context.Context, code string) error {
    select {
    case sem <- struct{}{}:
        defer func() { <-sem }()
        // 执行代码
    case <-ctx.Done():
        return ctx.Err()
    }
}

获取帮助

如果以上方案都无法解决问题:


title: GitHub Issues icon: i-lucide-github to: https://github.com/astercloud/aster/issues


报告 Bug 或提交功能请求

::card

title: 讨论区 icon: i-lucide-message-circle to: https://github.com/astercloud/aster/discussions


提问和讨论

::card

title: 文档 icon: i-lucide-book to: /tools/ptc


查阅完整文档 :: ::

报告问题时请提供:

  1. ✅ 错误信息和堆栈跟踪
  2. ✅ Go 版本和 Python 版本
  3. ✅ 最小可复现示例
  4. ✅ 相关配置文件
  5. ✅ 日志输出