Skip to content

ZH Course 07 Tool Calling

lloydzhou edited this page Jun 1, 2026 · 2 revisions

工具调用

工具调用分三步:

  1. 解析模型发出的工具请求
  2. 分发到运行时实现
  3. 将工具结果写回 conversation

分发表保持直接:

tool_dispatch() {
    local name="$1"; shift
    case "$name" in
        Read)      tool_read "$@" ;;
        Write)     tool_write "$1" "$2" ;;
        Edit)      tool_edit "$@" ;;
        Bash)      tool_bash "$1" "$2" ;;
        Glob)      tool_glob "$1" "$2" ;;
        Grep)      tool_grep "$1" "$2" "$3" "$4" ;;
        TodoWrite) printf '%s' "$1" ;;
        PlanConfirm) tool_plan_confirm ;;
        PlanClear) tool_plan_clear ;;
        Skill)     tool_skill "$1" ;;
        WebSearch) tool_web_search "$1" ;;
        WebFetch)  tool_web_fetch "$1" ;;
        SubAgent)  tool_sub_agent "$1" "$2" "$3" ;;
    esac
}

参数提取

模型发送 JSON。运行时用按工具区分的参数列表把每个已知工具转成位置参数:

tool_param_keys() {
    case "$1" in
        Read) printf 'path offset limit' ;;
        Write) printf 'path content' ;;
        Edit) printf 'path old_string new_string' ;;
        Bash) printf 'command timeout' ;;
        Glob) printf 'pattern path' ;;
        Grep) printf 'pattern path glob context' ;;
    esac
}

这样每个工具实现都可以保持很小,不需要在内部重复理解 schema。

工具协议面

tools.json 不只是文档,它是所有运行时共享的提供方协议面。

util_load_tool_defs() {
    local tools_file script_dir
    script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    tools_file="$script_dir/tools.json"
    [[ -f "$tools_file" ]] || util_die "Cannot find tools.json: $tools_file"
    TOOL_DEF_JSON=$(<"$tools_file")
}

Claude 请求可以直接发送这份 schema。OpenAI 请求会在传输边界把同一份 tool definitions 转成 type=function tools。

agent loop 不应该知道底层提供方使用了哪种格式。它只接收统一后的 TOOL_CALL 消息,并按工具名分发。

结果格式化

工具输出可能很长。运行时在返回模型前会截断长结果:

tool_format_result() {
    local output="$1" size marker marker_len tail_lines=5 tail_text tail_len head_len
    if (( ${#output} <= TOOL_RESULT_MAX_BYTES )); then
        printf '%s' "$output"
        return 0
    fi
    # 保留开头、截断标记和末尾若干行
}

关键规则是:assistant 的 tool_use 和后续 user 的 tool_result 必须在 conversation 中保持配对。

下一章

Bash 工具权限模式 解释 shell 工具为什么需要单独的策略层。

Clone this wiki locally