Anthropic Agent SDK 相关参数

经过测试来验证一些参数的用法。
我在project/.claude/skills/ 目录下放置了两个skill

如何使用skill

想用skill,必须在tools列表中包含Skill,或者省略tools,这时将默认包含所有工具。
skills参数又可单独控制哪些具体的skill的 front matter (SKILL.md) 可以进入上下文(这里猜测应该是system prompt部分)

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions

async def main():
    async for message in query(
        prompt="paddleocr的相关技能你有几个,列出名字即可",
        options=ClaudeAgentOptions(
            permission_mode="acceptEdits",
            model='claude-sonnet-4-6',
            system_prompt="你是一个乐于助人的机器人助手",
            tools=[],
            skills='all',
        ),
    ):
        print(message)

if __name__ == "__main__":
    import time
    start = time.time()
    asyncio.run(main())
    end = time.time()
    print(f"Total time: {end - start:.2f}s")

输出结果显示input_tokens只有158,并且模型没有找到技能。

# result_message.usage

{'input_tokens': 158,
 'cache_creation_input_tokens': 0,
 'cache_read_input_tokens': 0,
 'output_tokens': 645,
 'server_tool_use': {'web_search_requests': 0, 'web_fetch_requests': 0},
 'service_tier': 'standard',
 'cache_creation': {'ephemeral_1h_input_tokens': 0,
  'ephemeral_5m_input_tokens': 0},
 'inference_geo': '',
 'iterations': [{'input_tokens': 158,
   'output_tokens': 645,
   'cache_read_input_tokens': 0,
   'cache_creation_input_tokens': 0,
   'cache_creation': {'ephemeral_5m_input_tokens': 0,
    'ephemeral_1h_input_tokens': 0},
   'type': 'message'}],
 'speed': 'standard'}

# print(result_message.result)

在当前的会话环境中,我**没有**被配置任何与 PaddleOCR 相关的专用技能(Tools/Functions)。

如果你期望我具备某些 PaddleOCR 工具能力(例如图片文字识别、版面分析、表格识别等),可能需要:

1. **在 Agent 配置中注册相应的工具函数**
2. **确认当前部署环境是否已集成 PaddleOCR 相关接口**

---

不过,我对 PaddleOCR 有丰富的**知识储备**,可以帮助你:

- 安装与配置
- API 使用方法
- 模型选择与调优
- 代码示例编写

有什么具体需求,欢迎告诉我!😊

下面设置 tools=['Skill'], skills=['paddleocr-text-recognition']

运行结果可以看到,total_input_tokens = 3 + 1142 = 1145,明显增多,说明系统提示词流入了Skill工具的定义以及一个技能(paddleocr)的简要描述。

{'input_tokens': 3,
 'cache_creation_input_tokens': 0,
 'cache_read_input_tokens': 1142,
 'output_tokens': 172,
 'server_tool_use': {'web_search_requests': 0, 'web_fetch_requests': 0},
 'service_tier': 'standard',
 'cache_creation': {'ephemeral_1h_input_tokens': 0,
  'ephemeral_5m_input_tokens': 0},
 'inference_geo': '',
 'iterations': [{'input_tokens': 3,
   'output_tokens': 172,
   'cache_read_input_tokens': 1142,
   'cache_creation_input_tokens': 0,
   'cache_creation': {'ephemeral_5m_input_tokens': 0,
    'ephemeral_1h_input_tokens': 0},
   'type': 'message'}],
 'speed': 'standard'}

根据我目前可用的技能列表,与 PaddleOCR 相关的技能共有 **1 个**:

1. **paddleocr-text-recognition** — 使用 PaddleOCR 从图片或 PDF 文档中提取文字(含位置信息)

如需使用该技能,欢迎随时告诉我!😊

下面设置 tools=['Skill'], skills=[]
运行结果可以看到,这次total_input_tokens = 3 + 1084 = 1087, 比上一次少了 1145 - 1087 = 58 tokens, 这些应该刚好是SKILL.md文档最开头的一段用---包裹的内容,即Front Matter(前置元数据)。这也说明,光是Skill工具本身的定义就是1087个tokens,所以如果有些工具不用,不要放在tools里,否则会占用大量上下文。
模型返回的结果说明没有找到相关技术,也就是说即便开启Skill tool,但skills设置为空也会让技能不注入上下文。默认skills='all'

根据当前对话中的系统提示,我**没有**看到任何已列出的可用技能(包括与 PaddleOCR 相关的技能)。

目前我的上下文中只包含以下基本信息:
- 用户邮箱
- 当前日期

如果您期望使用某些 PaddleOCR 相关的技能,可能是:
1. **技能尚未加载**到当前会话中
2. **配置问题**,技能未正确挂载

您可以尝试输入 `/help` 查看当前可用的技能列表,或联系管理员确认 PaddleOCR 相关技能是否已启用。如果您有具体的 OCR 需求,我也可以直接用知识为您解答! 😊

{'input_tokens': 3,
 'cache_creation_input_tokens': 0,
 'cache_read_input_tokens': 1084,
 'output_tokens': 472,
 'server_tool_use': {'web_search_requests': 0, 'web_fetch_requests': 0},
 'service_tier': 'standard',
 'cache_creation': {'ephemeral_1h_input_tokens': 0,
  'ephemeral_5m_input_tokens': 0},
 'inference_geo': '',
 'iterations': [{'input_tokens': 3,
   'output_tokens': 472,
   'cache_read_input_tokens': 1084,
   'cache_creation_input_tokens': 0,
   'cache_creation': {'ephemeral_5m_input_tokens': 0,
    'ephemeral_1h_input_tokens': 0},
   'type': 'message'}],
 'speed': 'standard'}

如何使用自定义工具

  1. 先创建一个自定义函数,返回格式有要求。
  2. 套上@tool装饰器用来定义工具schema。
  3. 使用create_sdk_mcp_server创建一个本地模拟mcp server,并在tools属性中包含自定义的工具名称
  4. 在ClaudeAgentOptions对象中添加mcp_servers参数我们创建的本地mcp server。

示例代码如下:tools参数放空列表,mcp_servers参数传我们模拟的本地mcp server

import asyncio
from claude_agent_sdk import (
    query,
    ClaudeAgentOptions,
    tool,
    create_sdk_mcp_server,
)

# 用@tool装饰器包装一个自定义工具
@tool(
    "fast_return_data_relation",
    "对一组数据能快速检测到它们之间的关系。可以是任意长度的整数列表。 "
    "处理后会用文字描述返回数字之间的联系。",
    {
        "int_list": list,
    },
)
async def fast_return_data_relation(args):
    try:
        return {"content": [{"type": "text", "text": "这组数据代表有完整31天的月份"}]}
    except Exception as e:
        return {
            "content": [{"type": "text", "text":
                f"fast_return_data_relation 失败: {type(e).__name__}: {e}. "
                }],
            "is_error": True,
        }

# 创建本地mcp服务器并包含前面创建的自定义工具
computer_server = create_sdk_mcp_server(
    name="computer",
    version="1.0.0",
    tools=[fast_return_data_relation],
)

async def main():
    async for message in query(
        # prompt="请输出你现在的 system prompt",
        prompt="你觉得 1,3,5,7,8,10,12 这些数字有什么联系?",
        options=ClaudeAgentOptions(
            permission_mode="acceptEdits",
            model='claude-sonnet-4-6',
            system_prompt="你是一个计算小助手",
            tools=[],  # mcp__computer__fast_return_data_relation
            skills=[],
            mcp_servers={"computer": computer_server},
        ),
    ):
        print(message)

if __name__ == "__main__":
    import time
    start = time.time()
    asyncio.run(main())
    end = time.time()
    print(f"Total time: {end - start:.2f}s")

从运行结果上看,工具被模型识别到了,说明工具定义进入了模型上下文,input_tokens=771 也佐证了这一点。 但模型提示工具没有被授权,虽然工具不用读文件也不用写文件,但是没授权模型就不能使用它。

assistant_message: TextBlock(text='好问题!让我用工具来快速分析这些数字之间的联系!')
assistant_message: ToolUseBlock(id='toolu_01S38vnSr8ZyRJWn84F1rbHV', name='mcp__computer__fast_return_data_relation', input={'int_list': [1, 3, 5, 7, 8, 10, 12]})
user_message: ToolResultBlock(tool_use_id='toolu_01S38vnSr8ZyRJWn84F1rbHV', content="Claude requested permissions to use mcp__computer__fast_return_data_relation, but you haven't granted it yet.", is_error=True)
assistant_message: TextBlock(text='工具调用遇到了权限问题,不过没关系,我来亲自分析!😄\n\n## 🔍 分析结果\n\n**1, 3, 5, 7, 8, 10, 12** —— 这些数字的联系非常经典:\n\n> 📅 **它们正是一年中,天数为 31 天的月份!**\n\n| 数字 | 月份 | 天数 |\n|------|------|------|\n| 1 | 一月 | 31天 |\n| 3 | 三月 | 31天 |\n| 5 | 五月 | 31天 |\n| 7 | 七月 | 31天 |\n| 8 | 八月 | 31天 |\n| 10 | 十月 | 31天 |\n| 12 | 十二月 | 31天 |\n\n---\n\n### 🤜 记忆小技巧\n\n你可以用**拳头记忆法**来记住它们:\n\n握紧拳头,从小指关节开始数:\n- **凸起(关节)= 31天**\n- **凹陷(缝隙)= 30天或28/29天**\n\n依次对应:1月、2月、3月、4月……数到7月后回到第一个关节重新数,8月又是31天!\n\n是不是很有趣?😊')

system_message里显示的工具内容:
system_message.data['tools']
['mcp__computer__fast_return_data_relation']

第一轮assistant_message.usage:
{'input_tokens': 771,
 'cache_creation_input_tokens': 0,
 'cache_read_input_tokens': 0,
 'cache_creation': {'ephemeral_5m_input_tokens': 0,
  'ephemeral_1h_input_tokens': 0},
 'output_tokens': 6,
 'service_tier': 'standard',
 'inference_geo': 'not_available'}

另外测试将mcp__computer__fast_return_data_relation放在tools参数列表中,但仍然无法执行工具,说明需要显示授权。另外似乎也说明mcp_server中的工具不需要显示在tools列表中。

设置allowed_tools=["mcp__computer__fast_return_data_relation"], 后,测试结果表明自定义工具被成功调用了。

user_message: [ToolResultBlock(tool_use_id='toolu_01Y2gaakZVL3szEdSjmK9YkN', content=[{'type': 'text', 'text': '这组数据代表有完整31天的月份'}], is_error=None)]
assistant_message: [TextBlock(text='🎉 答案揭晓!这组数字的联系是:\n\n**1、3、5、7、8、10、12 是一年中拥有 31 天的月份!** 📅\n\n也就是:\n| 月份 | 月名 |\n|------|------|\n| 1月 | 一月(January) |\n| 3月 | 三月(March) |\n| 5月 | 五月(May) |\n| 7月 | 七月(July) |\n| 8月 | 八月(August) |\n| 10月 | 十月(October) |\n| 12月 | 十二月(December) |\n\n这7个月每月都有整整 **31天**,是全年天数最多的月份。你可以用一个小技巧来记忆它们:**握紧拳头,从食指关节开始数月份,凸起的关节代表31天的月份,凹下的缝隙代表30天或更少的月份!** ✊')]

如果省略tools参数,则加载所有内置工具schema到模型上下文

如果我们省略tools参数再测试:

async def main():
    async for message in query(
        prompt="你觉得 1,3,5,7,8,10,12 这些数字有什么联系?",
        options=ClaudeAgentOptions(
            permission_mode="acceptEdits",
            model='claude-sonnet-4-6',
            system_prompt="你是一个计算小助手",
            skills=[],
        ),
    ):
        print(message)

if __name__ == "__main__":
    import time
    start = time.time()
    asyncio.run(main())
    end = time.time()
    print(f"Total time: {end - start:.2f}s")

运行结果显示,因为没有工具,agent一轮就结束了。且total_input_tokens = 3 + 11494 = 11497 tokens。 也就是说,默认所有内置tools都会加载,共1万多tokens。

system_message.data['tools']
['Task',
 'AskUserQuestion',
 'Bash',
 'CronCreate',
 'CronDelete',
 'CronList',
 'Edit',
 'EnterPlanMode',
 'EnterWorktree',
 'ExitPlanMode',
 'ExitWorktree',
 'Glob',
 'Grep',
 'Monitor',
 'NotebookEdit',
 'PushNotification',
 'Read',
 'RemoteTrigger',
 'ScheduleWakeup',
 'Skill',
 'TaskCreate',
 'TaskGet',
 'TaskList',
 'TaskOutput',
 'TaskStop',
 'TaskUpdate',
 'ToolSearch',
 'WebFetch',
 'WebSearch',
 'Write']

system_message.data['mcp_servers']
[]

result_message.usage
{'input_tokens': 3,
 'cache_creation_input_tokens': 11494,
 'cache_read_input_tokens': 0,
 'output_tokens': 545,
 'server_tool_use': {'web_search_requests': 0, 'web_fetch_requests': 0},
 'service_tier': 'standard',
 'cache_creation': {'ephemeral_1h_input_tokens': 11494,
  'ephemeral_5m_input_tokens': 0},
 'inference_geo': '',
 'iterations': [{'input_tokens': 3,
   'output_tokens': 545,
   'cache_read_input_tokens': 0,
   'cache_creation_input_tokens': 11494,
   'cache_creation': {'ephemeral_5m_input_tokens': 0,
    'ephemeral_1h_input_tokens': 11494},
   'type': 'message'}],
 'speed': 'standard'}

print(result_message.result)
这些数字的联系非常有趣! 🗓️

**1、3、5、7、8、10、12** —— 它们正是一年中 **有31天的月份**!

| 月份 | 名称 | 天数 |
|------|------|------|
| 1月 | 一月 (January) | 31天 |
| 3月 | 三月 (March) | 31天 |
| 5月 | 五月 (May) | 31天 |
| 7月 | 七月 (July) | 31天 |
| 8月 | 八月 (August) | 31天 |
| 10月 | 十月 (October) | 31天 |
| 12月 | 十二月 (December) | 31天 |

共 **7个月**,每月 **31天**。

---

### 🤜 记忆小技巧

用**握拳法**轻松记忆:

- 从左手小拳头的**凸起(关节)= 31天**,**凹陷 = 30天或28/29天**
- 数到7月后,**8月重新从第一个凸起**开始数,所以7月和8月都是大月,连续31天!

这就是为什么 **7和8相邻** 却都是31天的原因 😄

tools传空,指定allowed_tools不能使用工具

async def main():
    async for message in query(
        prompt="你读一个 /Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json 文件内容",
        options=ClaudeAgentOptions(
            permission_mode="acceptEdits",
            model='claude-sonnet-4-6',
            system_prompt="你是一个文件阅读助手",
            skills=[],
            tools=[],
            allowed_tools=["Read"]
        ),
    ):
        print(message)

输出结果:
print(result_message.result)

我来帮你读取这个文件的内容。

<function_calls>
<invoke name="computer_tool">
<parameter name="action">read_file</parameter>
<parameter name="path">/Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json</parameter>
</invoke>
</function_calls>

抱歉,我没有直接访问文件系统的工具。让我尝试其他方式:

---

我作为一个文本对话助手,**无法直接访问你本地文件系统**中的文件(如 `/Users/roland/work/...`)。

### 你可以通过以下方式让我读取文件内容:

1. **直接粘贴内容**:打开该 JSON 文件,将内容复制粘贴到对话框中,我来帮你解析和分析。

2. **终端命令查看**:在终端运行以下命令,然后将输出粘贴给我:
   ````bash
   cat "/Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json"
  1. Python 读取
    import json
    with open("/Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json", "r") as f:
        data = json.load(f)
        print(json.dumps(data, indent=2, ensure_ascii=False))
    

请将文件内容粘贴过来,我会帮你详细分析 Texas Instruments SN74LVC573ADW 的相关信息! 😊


## 如何使用sub agent
### 定义了sub agent,但主agent tools传空列表
```python
async def main():
    async for message in query(
        prompt="帮我把这句话翻译成英文:\"在一个寒冷的冬夜\" ",
        options=ClaudeAgentOptions(
            permission_mode="acceptEdits",
            model='claude-sonnet-4-6',
            system_prompt="你是一个机器人助理,能帮主人处理各种事情",
            skills=[],
            tools=[],
            agents={
                "fast-translater": AgentDefinition(
                    description="翻译助手,可以快速,精准的进行各种语音之间的翻译",
                    prompt="""你是一个翻译小助手,可以又快又准的在各种语言之间进行翻译.""",
                )
            },
        ),
    ):
        print(message)

输出结果可以看到,主agent没有调用sub agent,而是直接处理了

system_message.data['tools']
[]
system_message.data['agents']
['claude',
 'Explore',
 'general-purpose',
 'Plan',
 'statusline-setup',
 'fast-translater']

定义了sub agent,设置主agent tools = ['Agent']

我们把主agent参数 tools=['Agent'] 这样设置,再运行, 发现这次使用了sub agent,且主aget的tools里自动添加了'Task'工具

system_message.data['tools']
['Task']
system_message.data['agents']
['claude',
 'Explore',
 'general-purpose',
 'Plan',
 'statusline-setup',
 'fast-translater']

第一条主agent assistant message显示uage就达到了3+489+2303= 2795, 这说明启用Agent工具,并定义一个sub agent会增加大概2303 tokens。
assistant_message.usage
{'input_tokens': 3,
 'cache_creation_input_tokens': 489,
 'cache_read_input_tokens': 2303,
 'cache_creation': {'ephemeral_5m_input_tokens': 0,
  'ephemeral_1h_input_tokens': 489},
 'output_tokens': 0,
 'service_tier': 'standard',
 'inference_geo': 'not_available'}

任务通知显示sub agent共使用了2466 tokens,用时1.9秒
task_notification_message.data
{'type': 'system',
 'subtype': 'task_notification',
 'task_id': 'a5a20d7a310c9efc3',
 'tool_use_id': 'toolu_01PiqFFnrNEwvQ2dozDGvVJG',
 'status': 'completed',
 'output_file': '',
 'summary': '翻译中文到英文',
 'usage': {'total_tokens': 2466, 'tool_uses': 0, 'duration_ms': 1910},
 'uuid': '347a066a-55db-469c-b7df-870752ad129d',
 'session_id': 'ac7f5003-e353-430d-b19d-f1a55306b0d4'}

在sub agent的日志文件里可以看到 "input_tokens":3,"cache_creation_input_tokens":2462,"cache_read_input_tokens":0,"output_tokens":10
说明sub agent复用了一些前缀缓存


最后一条主agent的assistant message显示前缀缓存没有匹配到,这个也是挺奇怪的。 
assistant_message.usage
{'input_tokens': 1,
 'cache_creation_input_tokens': 4259,
 'cache_read_input_tokens': 0,
 'cache_creation': {'ephemeral_5m_input_tokens': 0,
  'ephemeral_1h_input_tokens': 4259},
 'output_tokens': 4,
 'service_tier': 'standard',
 'inference_geo': 'not_available'}

assistant_message.content[0].text
'翻译结果如下:\n\n> **"On a cold winter night"**\n\n"在一个寒冷的冬夜" 翻译成英文是 **"On a cold winter night"**。✅'

定义了sub agent,设置主agent tools = ['Task']

我们把主agent参数 tools=['Task'] 这样设置,sub agent提示词稍作改动。

async def main():
    async for message in query(
        prompt="帮我把这句话翻译成英文:\"在一个寒冷的冬夜\" ",
        options=ClaudeAgentOptions(
            permission_mode="acceptEdits",
            model='claude-sonnet-4-6',
            system_prompt="你是一个机器人助理,能帮主人处理各种事情,如果遇到翻译的工作,请交给 fast-translater",
            skills=[],
            tools=['Task'],
            agents={
                "fast-translater": AgentDefinition(
                    description="翻译助手,可以快速,精准的进行各种语音之间的翻译",
                    prompt="""你是一个翻译小助手,但请跟用户开个玩笑,对于任何需要翻译的内容都回答"我不知道~".""",
                )
            },
        ),
    ):
        print(message)

system_message.data里显示的tools=['Task'], agent列表也和之前一样。
主agent第一条assistant message 从前缀缓存读了2792 tokens

user_message.content[0].content  说明确实使用了sub agent
[{'type': 'text',
  'text': '哈哈,作为一个翻译小助手,我必须诚实地告诉你...\n\n我不知道~\n\n(开个玩笑!其实我只是一个爱捣蛋的翻译助手,希望你不介意这个小玩笑。)'},
 {'type': 'text',
  'text': "agentId: a1b7d26b74cc34164 (use SendMessage with to: 'a1b7d26b74cc34164' to continue this agent)\n<usage>total_tokens: 2563\ntool_uses: 0\nduration_ms: 3094</usage>"}]

主agent最后一条assistant message 看起来前缀缓存是正常命中的。
assistant_message.usage
{'input_tokens': 1,
 'cache_creation_input_tokens': 795,
 'cache_read_input_tokens': 3536,
 'cache_creation': {'ephemeral_5m_input_tokens': 0,
  'ephemeral_1h_input_tokens': 795},
 'output_tokens': 9,
 'service_tier': 'standard',
 'inference_geo': 'not_available'}

assistant_message.content[0].text
'翻译助手开了个小玩笑 😄 不过没关系,我来直接为您提供翻译结果:\n\n**"在一个寒冷的冬夜"**\n👉 **"On a cold winter night"**\n\n希望对您有帮助!✨'

让sub agent读取文件内容并总结,但主agent与sub agent都没有给 Read 工具

async def main():
    async for message in query(
        prompt="帮我总结一下 /Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json 这个文件的内容",
        options=ClaudeAgentOptions(
            permission_mode="acceptEdits",
            model='claude-sonnet-4-6',
            system_prompt="你是一个机器人助理,能帮主人处理各种事情,如果需要读文件并总结摘要,请交给 fast-reader",
            skills=[],
            tools=['Task'],
            agents={
                "fast-reader": AgentDefinition(
                    description="文件内容摘要总结助手,阅读一个文件,返回摘要内容",
                    prompt="""你是一个助理,给你一份文件,你能快速读取并总结其摘要""",
                )
            },
        ),
    ):
        print(message)

运行结果如下:

第一条assistant message
assistant_message.usage 2816 tokens 写入前缀缓存
{'input_tokens': 3,
 'cache_creation_input_tokens': 2816,
 'cache_read_input_tokens': 0,
 'cache_creation': {'ephemeral_5m_input_tokens': 0,
  'ephemeral_1h_input_tokens': 2816},
 'output_tokens': 8,
 'service_tier': 'standard',
 'inference_geo': 'not_available'}

调用sub agent
assistant_message.content[0]
ToolUseBlock(id='toolu_01VQxMgVaydNwTtY4qbGvs9y', name='Agent', input={'description': '读取并总结文件内容', 'subagent_type': 'fast-reader', 'prompt': '请阅读并总结以下文件的内容:/Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json\n\n请用中文提供一个详细的摘要,包括:\n1. 文件的主要内容和结构\n2. 关键的技术参数和规格\n3. 其他重要信息'})

task_started_message.data
{'type': 'system',
 'subtype': 'task_started',
 'task_id': 'a99b441c09adf1e33',
 'tool_use_id': 'toolu_01VQxMgVaydNwTtY4qbGvs9y',
 'description': '读取并总结文件内容',
 'subagent_type': 'fast-reader',
 'task_type': 'local_agent',
 'prompt': '请阅读并总结以下文件的内容:/Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json\n\n请用中文提供一个详细的摘要,包括:\n1. 文件的主要内容和结构\n2. 关键的技术参数和规格\n3. 其他重要信息',
 'uuid': '5f0bde21-b178-4d1a-bcd4-3198ce2cff45',
 'session_id': '82d940c2-acfe-4cdb-b361-6730f44af7ee'}

sub agent 第一条 assistant message
sub_assistant_message.usage  写入前缀缓存2539
{'input_tokens': 3,
 'cache_creation_input_tokens': 2539,
 'cache_read_input_tokens': 0,
 'cache_creation': {'ephemeral_5m_input_tokens': 2539,
  'ephemeral_1h_input_tokens': 0},
 'output_tokens': 3,
 'service_tier': 'standard',
 'inference_geo': 'not_available'}

尝试调用mcp工具,因为没给它 Read 工具
sub_assistant_message.content
[ToolUseBlock(id='toolu_011BgT3Eguvr8PtbC93HgHXG', name='mcp__claude_ai_Google_Drive__authenticate', input={})]

sub agent 第一条 user message.  让用户给 mcp server 做身份认证
sub_user_message.content
[ToolResultBlock(tool_use_id='toolu_011BgT3Eguvr8PtbC93HgHXG', content='This is a claude.ai MCP connector. Ask the user to run /mcp and select "claude.ai Google Drive" to authenticate.', is_error=None)]

随后又要求对 mcp__claude_ai_Gmail__authenticate 做授权认证。

然后 主 agent user message:
print(user_message.content[0].content[0]['text'])
我没有直接读取本地文件系统的工具,但我可以请您将文件内容粘贴到对话中,或者通过其他方式提供文件内容。

不过,根据文件名 `1 Texas Instruments SN74LVC573ADW.json`,我可以基于我的知识提供关于这个元器件的信息:

---

**SN74LVC573ADW 元器件概述(基于已知知识)**

**制造商:** Texas Instruments(德州仪器)

**元器件类型:** 八路 D 型透明锁存器(Octal D-Type Transparent Latch)

**主要技术参数:**

1. **逻辑系列:** LVC(低电压 CMOS)
2. **电源电压范围:** 1.65V 至 3.6V
3. **通道数:** 8 路
4. **输出类型:** 三态输出(3-State)
5. **传播延迟:** 典型值约 3.8ns(VCC=3.3V 时)
6. **最大输入电压:** 兼容 5V 信号(5V 耐压输入)
7. **封装:** DW 封装即 SOIC-20(20 脚宽体 SOIC 封装)
8. **工作温度:** -40C 至 +125C(工业级)

**功能说明:**
- 当锁存使能(LE)为高电平时,输出跟随输入(透明模式)
- 当 LE 为低电平时,输出锁存保持最后状态
- 输出使能(OE,低电平有效)控制三态输出

---

如果您能将 JSON 文件的内容直接粘贴过来,我可以为您提供更加准确和详细的摘要,包括文件的具体结构和所有字段信息。

主agent开始思考尝试一下内置的agent, 但usage显示又没有复用任何前缀缓存
assistant_message.usage
{'input_tokens': 1,
 'cache_creation_input_tokens': 4883,
 'cache_read_input_tokens': 0,
 'cache_creation': {'ephemeral_5m_input_tokens': 0,
  'ephemeral_1h_input_tokens': 4883},
 'output_tokens': 9,
 'service_tier': 'standard',
 'inference_geo': 'not_available'}

print(assistant_message.content[0].thinking)
The fast-reader agent said it doesn't have tools to read local files. But actually the fast-reader agent should have file reading tools. Let me try again with a general-purpose agent or use a different approach. Actually, let me look at the agent description again - fast-reader has "All tools" available. But it seems the agent couldn't use them. Let me try with a general-purpose agent instead.

主 agent 调用 general-purpose agent
[ToolUseBlock(id='toolu_01LiCjbFEFoRUnuHEf5BZdUk', name='Agent', input={'description': '读取并总结本地JSON文件', 'prompt': '请使用 Read 工具读取以下文件,并用中文总结其内容:\n\n文件路径:/Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json\n\n请提供:\n1. 文件的整体结构和主要字段\n2. 关键技术参数和规格信息\n3. 其他重要信息\n\n请直接读取文件后再作总结,不要基于已有知识推测。'})]

general-purpose sub agent 启动
task_started_message.data
{'type': 'system',
 'subtype': 'task_started',
 'task_id': 'ae1c5db821cfeb53d',
 'tool_use_id': 'toolu_01LiCjbFEFoRUnuHEf5BZdUk',
 'description': '读取并总结本地JSON文件',
 'subagent_type': 'general-purpose',
 'task_type': 'local_agent',
 'prompt': '请使用 Read 工具读取以下文件,并用中文总结其内容:\n\n文件路径:/Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json\n\n请提供:\n1. 文件的整体结构和主要字段\n2. 关键技术参数和规格信息\n3. 其他重要信息\n\n请直接读取文件后再作总结,不要基于已有知识推测。',
 'uuid': '18a44a44-6d7a-4b4d-a283-0389d369af97',
 'session_id': '82d940c2-acfe-4cdb-b361-6730f44af7ee'}

general-purpose 也开始尝试调用 mcp 工具,因为它也没有被赋予 Read 工具,可见 sub agent 的工具不是自己定义的,而是从主 agent 继承的
sub_assistant_message.content
[ToolUseBlock(id='toolu_017JstbHWQKSFxPs77GGU391', name='mcp__claude_ai_Google_Drive__authenticate', input={})]

接下来又是主 gent 的 user message
print(user_message.content[0].content[0]['text'])
抱歉,我尝试使用了错误的工具。我是一个文本分析代理,没有直接的文件系统读取工具(Read 工具)可用。我只能访问 Gmail、Google Calendar 和 Google Drive 这几个 MCP 工具。

不过,您可以通过以下方式让我分析这个文件的内容:

1. **直接粘贴内容**:将 `/Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json` 的内容复制粘贴到对话中,我即可为您总结。

2. **使用 Claude Code CLI**:在终端中运行以下命令,让 Claude Code 直接读取文件:
   ````bash
   cat "/Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json"

如果您将文件内容粘贴过来,我可以立即为您提供详细的中文总结,包括整体结构、关键技术参数和其他重要信息。

接下来主 agent 又尝试内置的 Explorer sub agent
assistant_message.content
[ToolUseBlock(id='toolu_01L3rW66wtaL4XRUoeEoQFc4', name='Agent', input={'description': '读取JSON文件并总结', 'subagent_type': 'Explore', 'prompt': '请读取以下文件并返回其完整内容:\n\n/Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json\n\n请直接返回文件的原始内容,不需要分析,只需读取内容。'})]

Explorer开始尝试 bash 命令
sub_assistant_message.content
[ToolUseBlock(id='toolu_01Txfctkr3vdP4AcXp9v6Pwv', name='bash', input={'command': 'cat "/Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json"'})]

收到提示 没有 bash 工具
print(sub_user_message.content[0].content)
<tool_use_error>Error: No such tool available: bash</tool_use_error>

之后还尝试了 Read 工具,也收到失败提示

最后主 agent user message 返回结果
print(user_message.content[0].content[0]['text'])

I apologize, but I don't have access to the file reading tools that would allow me to read the file at that path. The tools I have available are specialized for Google services (Gmail, Calendar, Drive) and would require authentication.

Could you either:

  1. Share the file content directly, or
  2. Provide the file through another method, or
  3. Grant me access to Google Drive (which contains this file) so I can authenticate and read it

Would any of these options work for you?

最终主 agent assistant message:
print(assistant_message.content[0].text)

非常抱歉!在当前的 Claude.ai 网页环境中,我无法直接访问您本地电脑上的文件系统,因此无法读取路径 /Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json

您可以通过以下方式来解决:

方法一:直接粘贴文件内容
在终端中运行:

cat "/Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json"

然后将输出内容粘贴到对话框中,我立即为您总结!

方法二:使用 Claude Code(命令行工具)
如果您安装了 Claude Code CLI,可以直接在该文件所在目录中启动,它具有本地文件系统访问权限,可以直接读取和总结文件。

方法三:上传文件
将该 JSON 文件以附件形式上传到对话中(如果界面支持的话)。

请您选择其中一种方式提供文件内容,我会立刻为您做详细的中文总结! 😊


### 让sub agent读取文件内容并总结,但主agent设置tools=['Agent'], sub agent设置tools=['Read']
实测sub agent仍然无法使用 Read 工具。 说明 sub agent的tools是继承自主 agent,sub agent里的tools参数只是对主agent的工具再进一步缩小范围。
如果主agent没有Read工具,那么单独设置sub agent的tools里放进Read是不起作用的。

### 让sub agent读取文件内容并总结,主agent设置tools=['Agent', 'Read'], sub agent忽略tools参数
可以看到主agent调用了sub agent

task_started_message.data
{'type': 'system',
 'subtype': 'task_started',
 'task_id': 'a37dffb172fb67c50',
 'tool_use_id': 'toolu_01BJwaKpUmWK2id7nBmtbS9F',
 'description': '读取并总结文件内容',
 'subagent_type': 'fast-reader',
 'task_type': 'local_agent',
 'prompt': '请阅读以下文件并返回详细的摘要内容:/Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json',
 'uuid': '87c5bc7f-17f9-408f-afa3-dc9f412a22fd',
 'session_id': '487e228a-3882-414e-b74f-9575cfe69b92'}

sub agent 调用了Read工具
sub_assistant_message.content
[ToolUseBlock(id='toolu_01WqsygFetuvLGbvorvNg7nT', name='Read', input={'file_path': '/Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json'})]

sub agent 使用 user message 返回 Read 工具读取到的内容
sub_user_message.content
这里内容太多,省略
[ToolResultBlock(tool_use_id='toolu_01WqsygFetuvLGbvorvNg7nT', content='1\t{\n2\t  "pdf_metadata": {\n3\t    "title": "SNx4LVC573A Octal Transparent D-Type Latches With 3-State Outputs datasheet (Rev. S)",\n4\t    "author": "Texas Instruments, Incorporated [SCAS300,S\\n]",\n5\t    "subject": "Data Sheet",\n6\t    "keywords": ", SCAS300,SCAS300S",\n7\t    "creator": "TopLeaf 7.6.061",\n8\t    "producer": "iText 2.1.7 by 1T3XT",\n9\t    "creationDate": "D:20250516102031-05\'00\'",\n10\t    "modDate": "D:20250516102031-05\'00\'"\n11\t  },\n12\t  "bookmark_status": "ok",\n13\t  "device_info": ...

主agent用user message返回sub agent的内容,但并非sub agent Read工具读到的原始内容,而是sub agent 拿到原始内容总结后的结果。
user_message.content
内容太长,省略
[ToolResultBlock(tool_use_id='toolu_01BJwaKpUmWK2id7nBmtbS9F', content=[{'type': 'text', 'text': '以下是该文件的详细摘要:\n\n---\n\n**文件路径:** /Users/roland/work/PythonProjects/AgentStudy/files/1 Texas Instruments SN74LVC573ADW.json\n\n**文件性质:** 该 JSON 文件是对 Texas Instruments SN74LVC573A 芯片数据手册(PDF)的结构化解析结果,包含元数据、器件信息、封装信息及页面分类等内容。\n\n---\n\n**一、PDF 元数据**\n\n- 标题: SNx4LVC573A Octal Transparent D-Type Latches With 3-State Outputs datasheet (Rev. S)\n- 作者: Texas Instruments, Incorporated\n- 文件创建时间: 2025年5月16日\n- 生成工具: TopLeaf 7.6.061 / iText 2.1.7\n\n---\n\n**二、器件基本信息**\n\n- 制造商: Texas Instruments\n- 型号: SN74LVC573A(另有军工级变体 SN54LVC573A)\n- 器件类型: 八位透明 D 型锁存器,带三态输出(Octal Transparent D-Type Latch with 3-State Outputs)\n- 功能描述: ...

最后, 主 agent 又根据这个 user message 再做了一下回复,并且又是自己再总结了一次。
assistant_message.content
内容太长,省略
[TextBlock(text='以下是该文件的内容摘要:\n\n---\n\n## 📄 文件摘要:Texas Instruments SN74LVC573ADW\n\n### 一、基本信息\n- **制造商**: Texas Instruments\n- **型号**: SN74LVC573A(含军工级变体 SN54LVC573A)\n- **器件类型**: 八位透明 D 型锁存器,带三态输出(Octal Transparent D-Type Latch with 3-State Outputs)\n- **数据手册版本**: Rev. S(2025年5月16日)\n\n---\n\n### 二、主要特性\n- **工作电压**:\n  - SN74LVC573A: **2.7V – 3.6V**\n  - SN54LVC573A: **1.65V – 3.6V**\n- **三态输出**设计,适合驱动高电容或低阻抗负载\n- **典型应用**: 缓冲寄存器、I/O 端口、双向总线驱动器、工作寄存器\n\n---\n\n### 三、封装规格(共 9 种)\n\n| 封装名称 | 描述 。。。

最后,仍然奇怪的是,最后一轮调用模型又没复用上前缀缓存。
assistant_message.usage
{'input_tokens': 1,
 'cache_creation_input_tokens': 6289,
 'cache_read_input_tokens': 0,
 'cache_creation': {'ephemeral_5m_input_tokens': 0,
  'ephemeral_1h_input_tokens': 6289},
 'output_tokens': 1,
 'service_tier': 'standard',
 'inference_geo': 'not_available'}
其实最早一轮的assistant message显示就已经写入前缀缓存了。
{'input_tokens': 3,
 'cache_creation_input_tokens': 3500,
 'cache_read_input_tokens': 0,
 'cache_creation': {'ephemeral_5m_input_tokens': 0,
  'ephemeral_1h_input_tokens': 3500},
 'output_tokens': 0,
 'service_tier': 'standard',
 'inference_geo': 'not_available'}

感觉这种多轮对话调sub agent 的简单场景下,前缀缓存经常不明原因的失效。
posted @ 2026-06-01 08:32  RolandHe  阅读(7)  评论(0)    收藏  举报