【也是会写Agent了】使用DeepSeek的工具调用实现极简Agent

【也是会写Agent了】使用DeepSeek的工具调用实现极简Agent
【也是会写Agent了】使用DeepSeek的工具调用实现极简Agent

之前我对Agent挺不屑一顾的,觉得上限还是要看基座模型。但是前一段时间,我也是终于用上了Claude Code。刚开始用的时候,自然是刹不住车,额度一会儿就用完了。那没办法,用CC Switch换成DeepSeek的api试试,没想到性能居然差了那么多!完全是一个天上一个地下,怪不得DeepSeek也要开发自己的Agent。我也是萌生了自己开发Agent的想法。

说干就干。api上我选择了好评如潮的DeepSeek官方api(主要是便宜)。第一步的目标很简单,我从GitHub上下了一个仓库叫MisterQueen(一个国际象棋项目),我需要让Agent可以帮我总结这个项目。我用的是Windows,那就加一个PowerShell的tool_call吧!

代码如下:

import json
import subprocess

import requests

client = requests.Session()
client.headers.update({
    "Accept": "application/json",
    "Authorization": "Bearer YOUR_DEEPSEEK_API_KEY",
})


def run_powershell_cmd(cmd):
    full_cmd = (
        "[Console]::OutputEncoding=[Text.Encoding]::UTF8; "
        "$PSStyle.OutputRendering='PlainText'; "
        f"{cmd}"
    )
    result = subprocess.run(
        ["pwsh", "-Command", full_cmd],
        capture_output=True,
        text=True,
        encoding="utf-8",
    )
    return f"stdout:\n{result.stdout}\nstderr:\n{result.stderr}"


def post_deepseek(
    messages,
    model="deepseek-v4-pro",
    thinking=True,
    reasoning_effort="high",
    max_tokens=None,
    response_format_type="text",
    stop=None,
    stream=False,
    stream_options=None,
    temperature=1,
    top_p=1,
    tools=None,
    tool_choice=None,
    logprobs=False,
    top_logprobs=None,
):
    url = "https://api.deepseek.com/beta/chat/completions"
    json_data = {
        "messages": messages,
        "model": model,
        "thinking": {"type": "enabled" if thinking else "disabled"},
        "reasoning_effort": reasoning_effort if thinking else None,
        "response_format": {"type": response_format_type},
        "stream": stream,
        "temperature": temperature,
        "top_p": top_p,
        "logprobs": logprobs,
    }
    if max_tokens is not None:
        json_data["max_tokens"] = max_tokens
    if stop is not None:
        json_data["stop"] = stop
    if stream and stream_options is not None:
        json_data["stream_options"] = stream_options
    if tools is not None:
        json_data["tools"] = tools
    if tool_choice is not None:
        json_data["tool_choice"] = tool_choice
    if logprobs and top_logprobs is not None:
        json_data["top_logprobs"] = top_logprobs
    return client.post(url, json=json_data, stream=stream)


def post_deepseek_handle_tools(**kwargs):
    kwargs["messages"]
    while True:
        resp = post_deepseek(**kwargs)
        resp_json = resp.json()
        choice = resp_json["choices"][0]
        finish_reason = choice["finish_reason"]
        message = choice["message"]
        kwargs["messages"].append(message)
        if finish_reason == "stop":
            return kwargs["messages"]
        elif finish_reason == "tool_calls":
            tool_calls = message["tool_calls"]
            for tool_call in tool_calls:
                function = tool_call["function"]
                assert function["name"] == "run_powershell_cmd"
                arguments = json.loads(function["arguments"])
                cmd = arguments["cmd"]
                user_conformation = input(
                    f"AI wants to run powershell command:\n{cmd}\nDo you allow it? (y/n): "
                )
                if user_conformation.lower() != "y":
                    tool_result = f"Tool call rejected by user. Command was:\n{cmd}"
                else:
                    tool_result = run_powershell_cmd(cmd)
                kwargs["messages"].append({
                    "role": "tool",
                    "tool_call_id": tool_call["id"],
                    "content": tool_result,
                })
        else:
            raise ValueError(f"Unexpected finish_reason: {finish_reason}")


messages = post_deepseek_handle_tools(
    messages=[
        {
            "role": "system",
            "content": "你是一个人工智能助手",
        },
        {
            "role": "user",
            "content": "总结MisterQueen文件夹内的项目",
        },
    ],
    tools=[
        {
            "type": "function",
            "function": {
                "name": "run_powershell_cmd",
                "strict": True,
                "description": "运行powershell命令",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "cmd": {
                            "description": "要运行的powershell命令",
                            "type": "string",
                        }
                    },
                    "required": ["cmd"],
                    "additionalProperties": False,
                },
            },
        }
    ],
)

print(messages[-1]["content"])

运行结果:

AI wants to run powershell command:
Get-ChildItem -Path “MisterQueen” -Recurse -Depth 3 | Select-Object Mode, Name, Extension, FullName | Format-Table -AutoSize
Do you allow it? (y/n): y
AI wants to run powershell command:
Get-Content “MisterQueen\README.md”
Do you allow it? (y/n): y
AI wants to run powershell command:
Get-Content “MisterQueen\Makefile”
Do you allow it? (y/n): y
AI wants to run powershell command:
Get-Content “MisterQueen\LICENSE.md”
Do you allow it? (y/n): y
AI wants to run powershell command:
Get-Content “MisterQueen\src\main.c” -Head 30
Do you allow it? (y/n): y
AI wants to run powershell command:
Get-Content “MisterQueen\src\search.c” -Head 40
Do you allow it? (y/n): y
AI wants to run powershell command:
Get-Content “MisterQueen\src\uci.c” -Head 30
Do you allow it? (y/n): y
AI wants to run powershell command:
Get-Content “MisterQueen.gitignore”
Do you allow it? (y/n): y
AI wants to run powershell command:
Get-Content “MisterQueen\scripts\parser.py” -Head 30
Do you allow it? (y/n): y
AI wants to run powershell command:
Get-Content “MisterQueen\scripts\group.py” -Head 30
Do you allow it? (y/n): y

image

4 个帖子 - 2 位参与者

阅读完整话题

来源: LinuxDo 最新话题查看原文