当前位置: 首页 > article >正文

基于Claude API的AI应用开发:claude-toolshed框架实战指南

1. 项目概述与核心价值最近在折腾AI应用开发特别是围绕Claude API构建一些自动化工具时发现了一个挺有意思的开源项目——aksh-3141/claude-toolshed。这名字直译过来是“Claude的工具棚”听起来就挺接地气的。简单来说它不是一个独立的AI应用而是一个专门为Claude API设计的“工具集”或“工具箱”框架。如果你用过Claude的API特别是它的“工具调用”Tool Calling功能就会知道这玩意儿功能强大但用起来有点繁琐。你需要自己定义工具、处理JSON、管理会话状态代码写起来容易变得又长又乱。claude-toolshed的出现就是为了把这些脏活累活都包了让你能像搭积木一样快速、优雅地把各种功能“挂载”到Claude对话中。它的核心价值在于“提效”和“降本”。对于个人开发者或小团队它能让你在几小时内就搭建出一个功能相对完善的AI助手原型而不用花几天时间去处理底层的通信协议和状态管理。对于有经验的开发者它提供了一套清晰、可扩展的架构让你能把精力集中在业务逻辑和工具功能的实现上而不是重复造轮子。这个项目特别适合那些想基于Claude API构建复杂对话应用、智能客服、数据分析助手或者自动化工作流的人。即使你对Python和异步编程不是特别熟跟着它的文档和例子也能很快上手。2. 核心架构与设计哲学拆解2.1 什么是“工具调用”与为什么需要框架要理解claude-toolshed得先搞懂Claude API的“工具调用”机制。这其实是当前大模型应用的一个主流模式大模型本身不直接执行具体操作比如查数据库、发邮件、调用第三方API它只负责“思考”和“决策”。当用户提出一个需要具体操作才能回答的问题时比如“帮我查一下上个月的销售额”模型会“决定”需要调用哪个工具并生成一个结构化的调用请求一个JSON对象。然后你的应用程序负责接收这个请求找到对应的函数去执行拿到结果后再把结果塞回给模型由模型组织成自然语言回复给用户。这个过程听起来简单但实现起来坑不少。首先你需要严格按照Anthropic的格式定义每个工具名称、描述、参数schema。其次你要维护一个“工具注册表”把定义好的工具函数映射上去。然后在每次对话循环中你都要检查模型的返回里是否包含了工具调用请求如果有就得解析、分发、执行再把执行结果拼装好连同历史对话一起作为下一次请求的上下文发回去。状态管理、错误处理、异步执行……这些细节堆在一起代码很快就变得难以维护。claude-toolshed的设计哲学就是“约定大于配置”和“关注点分离”。它帮你把工具定义、注册、调用分发、会话管理这些通用逻辑全部封装好了。作为开发者你只需要做两件事1. 用Python函数和简单的装饰器来定义你的工具2. 告诉框架怎么连接Claude API。剩下的框架全包了。这种设计让代码结构非常清晰工具就是纯粹的业务逻辑函数而框架负责所有与AI模型交互的胶水代码。2.2 项目核心组件与工作流拆开来看claude-toolshed主要由以下几个核心组件构成它们共同协作完成一次完整的工具调用对话Tool工具这是最基本的单元。每一个工具对应一个Python函数。你需要用tool装饰器来标记它并在装饰器里提供工具的名称和描述。函数的参数和返回值类型会被框架自动用来生成符合Claude API要求的JSON Schema。比如一个查询天气的工具函数签名可能是def get_weather(city: str) - str:框架就知道这个工具需要一个字符串类型的city参数并返回一个字符串。ToolRegistry工具注册表这是一个中心化的仓库负责收集和管理所有用tool装饰过的函数。你不需要手动注册框架会在启动时自动发现并加载它们。这保证了工具定义的声明式和去中心化你可以在项目的任何地方定义工具只要它们能被导入框架就能找到。Agent/Toolset代理/工具集这是与Claude模型对话的核心执行器。你创建一个Agent实例并把你需要的工具注册表传递给它。Agent内部封装了与Claude API的通信逻辑。它的run方法是主要的入口你传入用户消息它就会自动处理整个“模型思考-调用工具-返回结果-模型回复”的循环直到模型认为不需要再调用工具给出最终答案为止。Conversation会话Agent内部维护着一个会话对象它保存了完整的对话历史包括用户消息、模型回复、工具调用和工具执行结果。这个状态是自动管理的确保了多轮对话中上下文的连贯性。整个工作流可以概括为用户输入 -Agent.run()- 框架将对话历史和可用工具列表发送给Claude - Claude返回消息或工具调用请求 - 框架解析工具调用执行对应的Python函数 - 将函数结果作为新的上下文消息发送给Claude - Claude生成最终回复 - 框架输出回复给用户。这个过程对开发者是完全透明的。3. 从零开始环境搭建与基础工具创建3.1 安装与初始配置上手的第一步是安装。claude-toolshed是一个Python库所以前提是你得有Python环境建议3.8以上。安装非常简单用pip一键搞定pip install claude-toolshed安装完成后最关键的一步是配置Claude API密钥。框架需要这个密钥来与Anthropic的服务器通信。绝对不要把密钥硬编码在代码里更不要上传到GitHub等公开平台。最安全、最规范的做法是使用环境变量。在终端里设置环境变量Linux/macOSexport ANTHROPIC_API_KEY你的实际API密钥或者在代码中通过os.environ设置仅用于临时测试生产环境不推荐import os os.environ[ANTHROPIC_API_KEY] 你的实际API密钥对于Windows用户可以在PowerShell中使用$env:ANTHROPIC_API_KEY你的实际API密钥实操心得我强烈建议使用.env文件配合python-dotenv库来管理环境变量。在项目根目录创建一个.env文件里面写上ANTHROPIC_API_KEYsk-xxx然后在代码开头加两行from dotenv import load_dotenv; load_dotenv()。这样既安全.env文件通常被.gitignore忽略又方便在不同环境开发、测试、生产切换时只需替换.env文件即可。3.2 创建你的第一个工具让我们从一个最简单的“Hello World”式工具开始感受一下框架的便捷。假设我们想创建一个工具让Claude能给我们讲个笑话。首先创建一个Python文件比如my_first_agent.py。import asyncio from claude_toolshed import tool from claude_toolshed.agent import Agent # 1. 使用装饰器定义一个工具 tool(nametell_joke, descriptionTell a random joke.) def get_random_joke() - str: 这个函数被tool装饰后就成为了一个Claude可调用的工具。 函数名本身不重要装饰器里的name才是工具在Claude眼中的标识。 description至关重要Claude根据它来决定什么时候调用这个工具。 # 这里只是一个硬编码的例子实际可以连接笑话API jokes [ 为什么程序员分不清万圣节和圣诞节因为 Oct 31 Dec 25。, 我写代码的速度取决于咖啡因的浓度和死线的距离。, 调试代码就像在雷区里找一只变色的猫而那只猫可能根本不存在。 ] import random return random.choice(jokes) # 2. 创建Agent并运行 async def main(): # 初始化Agent。默认使用最新的Claude模型。 agent Agent(tools[get_random_joke]) # 将工具函数传入 # 开始对话 response await agent.run(给我讲个笑话吧要程序员相关的。) print(Claude:, response) if __name__ __main__: asyncio.run(main())运行这个脚本你会看到Claude调用了tell_joke工具并把工具返回的笑话组织成一段友好的话术回复给你。整个过程你只需要定义函数和一句话启动对话框架自动完成了工具描述生成、API调用、结果注入的所有中间步骤。注意事项tool装饰器中的description字段是灵魂。Claude模型完全依赖这个描述来理解工具的功能。描述要清晰、具体最好说明工具的用途、输入和输出。模糊的描述会导致模型错误调用或根本不调用。例如“处理数据”就太模糊“根据城市名称查询该城市当前的天气情况和温度”就明确得多。3.3 处理带参数的复杂工具现实中的工具很少像讲笑话这么简单。大部分工具都需要输入参数。claude-toolshed利用Python的类型注解来自动生成参数schema非常智能。让我们创建一个稍微复杂点的工具一个简易的计算器能进行加减乘除。from claude_toolshed import tool from typing import Literal tool( namecalculator, descriptionPerform a basic arithmetic operation. Choose from addition (), subtraction (-), multiplication (*), or division (/). ) def calculate(a: float, b: float, operation: Literal[, -, *, /]) - float: 执行基础算术运算。 Args: a: 第一个运算数 b: 第二个运算数 operation: 运算符支持 , -, *, / Returns: 运算结果 if operation : return a b elif operation -: return a - b elif operation *: return a * b elif operation /: if b 0: return float(inf) # 简单处理除零错误实际项目应更严谨 return a / b else: raise ValueError(fUnsupported operation: {operation}) # 在Agent中使用 async def main(): agent Agent(tools[calculate]) # 你可以问“计算一下3.14乘以2.5等于多少” response await agent.run(请帮我计算 (15 7) * 3 的值。) print(response)这里有几个关键点类型注解即Schema函数参数a: float, b: float明确告诉框架这两个参数是数字类型。Claude API会据此生成{type: number}的schema。复杂类型支持operation: Literal[, -, *, /]使用了typing.Literal。这会被框架翻译成枚举类型{enum: [, -, *, /]}强制Claude必须从这几个选项里选一个避免了模型胡编乱造一个不支持的运算符。错误处理在工具函数内部进行基本的错误检查如除零并返回一个合理的值或抛出异常。框架能捕获异常并将其信息传递给Claude让模型可以向用户解释错误。运行这段代码Claude会理解你的问题自动调用calculator工具并传入正确的参数a15, b7, operation‘‘得到结果22后再调用一次a22, b3, operation‘*‘最终计算出66并组织语言回复你。这一切都是自动的、链式的。4. 构建实战一个多功能个人助理Agent理解了基础工具后我们来组装一个更有用的东西一个能查天气、记笔记、管理待办事项的个人文字助理。这个例子将涵盖更接近真实世界的场景。4.1 工具一智能天气查询我们使用一个免费的公开天气API例如Open-Meteo来获取真实数据。这涉及到网络请求所以工具函数必须是异步的async def。import aiohttp from claude_toolshed import tool from datetime import date tool(nameget_weather, descriptionGet the current weather and forecast for a given city.) async def fetch_weather(city_name: str, country_code: str CN) - str: 根据城市名和国家代码查询天气。 使用Open-Meteo API无需密钥。 # 1. 地理编码将城市名转换为经纬度 geo_url fhttps://geocoding-api.open-meteo.com/v1/search?name{city_name}country{country_code}count1 async with aiohttp.ClientSession() as session: async with session.get(geo_url) as resp: if resp.status ! 200: return f无法找到城市 {city_name} 的地理信息。 geo_data await resp.json() if not geo_data.get(results): return f未找到城市 {city_name}。请检查拼写。 location geo_data[results][0] lat, lon location[latitude], location[longitude] city_full_name location.get(name, city_name) # 2. 获取天气数据 weather_url ( fhttps://api.open-meteo.com/v1/forecast? flatitude{lat}longitude{lon} fcurrenttemperature_2m,weathercodedailyweathercode,temperature_2m_max,temperature_2m_min ftimezoneauto ) async with session.get(weather_url) as resp: if resp.status ! 200: return f获取{city_full_name}的天气数据失败。 weather_data await resp.json() # 3. 解析并格式化结果 current weather_data[current] daily weather_data[daily] # 简单映射天气代码到文字实际应用可用更全的映射表 wmo_code_map {0: 晴, 1: 少云, 2: 多云, 3: 阴天, 45: 雾, 61: 小雨, 80: 阵雨} current_weather wmo_code_map.get(current[weathercode], 未知) today daily[time][0] today_weather wmo_code_map.get(daily[weathercode][0], 未知) result f {city_full_name} 当前天气 - 温度{current[temperature_2m]}°C - 状况{current_weather} 今日({today})预报 - 最高温{daily[temperature_2m_max][0]}°C - 最低温{daily[temperature_2m_min][0]}°C - 天气{today_weather} return result实操心得对于涉及网络I/O的工具务必使用异步函数async def和像aiohttp这样的异步HTTP客户端。这能保证你的Agent在等待一个工具如网络请求返回时不会阻塞整个事件循环从而保持高响应性。同步的requests库在异步环境里会出问题。4.2 工具二简易笔记与待办管理为了简化我们用内存中的字典来模拟数据存储。在实际项目中你会连接到数据库如SQLite、PostgreSQL或云服务。from claude_toolshed import tool from typing import Optional, List # 模拟内存存储 notes_store {} todos_store [] tool(namecreate_note, descriptionCreate a new note with a title and content.) def add_note(title: str, content: str) - str: 创建一条新笔记。 if title in notes_store: return f笔记 {title} 已存在请使用更新功能或换一个标题。 notes_store[title] content return f笔记 {title} 创建成功。 tool(nameget_note, descriptionRetrieve the content of a note by its title.) def retrieve_note(title: str) - str: 根据标题获取笔记内容。 content notes_store.get(title) if content is None: return f未找到标题为 {title} 的笔记。 return f笔记 {title} 的内容\n{content} tool(nameadd_todo, descriptionAdd a new todo item.) def add_todo_item(task: str, priority: Literal[low, medium, high] medium) - str: 添加一条待办事项。 import uuid todo_id str(uuid.uuid4())[:8] new_item {id: todo_id, task: task, priority: priority, done: False} todos_store.append(new_item) return f待办事项已添加 (ID: {todo_id})。任务{task}优先级{priority}。 tool(namelist_todos, descriptionList all pending todo items, optionally filtered by priority.) def list_pending_todos(priority_filter: Optional[str] None) - str: 列出所有未完成的待办事项。 filtered [t for t in todos_store if not t[done]] if priority_filter and priority_filter in [low, medium, high]: filtered [t for t in filtered if t[priority] priority_filter] if not filtered: return 当前没有待办的事项。 if not priority_filter else f没有优先级为 {priority_filter} 的待办事项。 result 待办事项列表\n for item in filtered: result f- [{item[id]}] {item[task]} (优先级: {item[priority]})\n return result这个工具集展示了几个重要模式工具分组将相关的操作笔记的增查、待办的增列定义在同一个模块里逻辑清晰。可选参数priority_filter: Optional[str] None表示这个参数可以省略。Claude在调用时如果用户没提优先级就不会传这个参数。状态持久化目前数据存在内存里程序重启就没了。这是为了演示的简化。生产环境必须使用外部持久化存储并在工具函数中实现读写。4.3 组装并运行多功能Agent现在我们把所有工具组装起来创建一个真正的个人助理。import asyncio from claude_toolshed.agent import Agent # 假设上面的工具定义都在同一个文件或已被导入 from my_weather_tool import fetch_weather from my_note_tools import add_note, retrieve_note, add_todo_item, list_pending_todos async def main(): # 创建Agent传入所有工具 agent Agent( tools[fetch_weather, add_note, retrieve_note, add_todo_item, list_pending_todos], modelclaude-3-5-sonnet-20241022, # 可以指定模型版本 max_tokens1024, ) # 模拟一个多轮对话场景 conversation [ 今天北京天气怎么样, 把‘项目会议要点’记下来内容是‘讨论claude-toolshed集成方案负责人张三下周交付原型’。, 我还有哪些高优先级的待办事项, 帮我计算一下(1200 - 450) / 30 等于多少, # 我们没加计算器工具看Claude如何处理 ] print( 个人助理对话开始 ) for user_msg in conversation: print(f\n[用户]: {user_msg}) response await agent.run(user_msg) print(f[助理]: {response}) print( 对话结束 ) if __name__ __main__: asyncio.run(main())运行这个脚本你会看到一个连贯的对话。Claude会根据你的问题智能地选择调用get_weather、create_note或list_todos工具。当你问到一个它没有对应工具的问题如计算时它会老实地回答“我无法执行计算”或者尝试用推理给出一个近似答案取决于模型。这展示了Agent的能力边界。5. 高级特性与生产级考量当你想把基于claude-toolshed的原型变成真正可用的服务时有几个高级特性和工程化问题必须考虑。5.1 会话记忆与上下文管理默认情况下Agent对象会维护一个会话记住之前的所有对话和工具调用结果。这对于多轮对话至关重要。但有时你需要更精细的控制新建会话每次调用agent.run()默认是延续上次会话。如果想开始一个全新话题可以创建新的Agent实例或者使用agent.new_session()方法如果框架提供。上下文长度与总结Claude模型有上下文窗口限制如200K tokens。超长的对话历史会被截断可能导致遗忘早期信息。对于超长对话一个高级策略是定期让模型自己总结之前的对话要点然后将总结作为新的“系统提示”或压缩后的历史再继续后续对话。claude-toolshed本身可能不直接提供此功能但你可以通过拦截或包装agent.run的输入输出来实现。会话持久化如果你想实现“用户下次登录还能看到上次对话”的功能就需要把agent.conversation或其中的消息列表序列化如转成JSON保存到数据库。下次初始化Agent时再反序列化加载进去。5.2 错误处理与工具鲁棒性工具函数在执行时可能出错网络超时、API限流、无效输入等。框架通常能捕获异常并将其传递给Claude模型模型会尝试向用户解释错误。但我们可以做得更好from claude_toolshed import tool import aiohttp from aiohttp import ClientError, ClientTimeout tool(namerobust_weather, descriptionA more robust weather query tool.) async def get_weather_safe(city: str) - str: try: # ... 之前的天气查询逻辑 ... async with aiohttp.ClientSession(timeoutClientTimeout(total10)) as session: # ... 发起请求 ... pass except ClientError as e: # 网络相关错误 return f查询天气时网络出现错误{str(e)}。请稍后重试。 except TimeoutError: return 天气查询请求超时请检查网络或稍后再试。 except KeyError as e: # API返回数据格式不符合预期 return f处理天气数据时遇到意外格式错误信息{str(e)}。 except Exception as e: # 捕获所有其他未预见的错误 # 生产环境应记录日志如logging.error(e)而不是直接返回给用户 return 系统内部处理天气请求时发生未知错误。核心原则工具函数应该尽可能内部消化错误并返回一个对用户友好的字符串信息。避免让未处理的异常直接抛出导致整个Agent会话崩溃。同时一定要记录详细的错误日志使用logging模块方便后台排查。5.3 性能优化与超时控制工具执行超时如果一个工具执行时间过长比如一个复杂的数据库查询或慢速的第三方API会拖累整个对话响应。可以为工具函数设置超时机制。Python的asyncio.wait_for可以派上用场。import asyncio from functools import wraps def tool_with_timeout(timeout_seconds30): def decorator(func): wraps(func) async def wrapper(*args, **kwargs): try: return await asyncio.wait_for(func(*args, **kwargs), timeouttimeout_seconds) except asyncio.TimeoutError: return f工具 {func.__name__} 执行超时{timeout_seconds}秒请重试或简化请求。 return wrapper return decorator tool(nameslow_query) tool_with_timeout(10) # 自定义超时装饰器要放在tool里面 async def potentially_slow_operation(): await asyncio.sleep(15) # 模拟慢操作 return Done异步并发如果多个工具之间没有依赖关系且框架支持可以考虑让它们并发执行。不过标准的Claude工具调用模式是顺序的模型思考-调用一个工具-得到结果-再思考所以通常不需要。5.4 安全性与权限控制这是企业级应用无法回避的问题。你不能让用户通过Claude调用任何工具。工具级权限最简单的办法是根据用户身份动态构建不同的工具列表。例如普通用户只能使用查询天气和创建笔记而管理员则多一个系统管理工具。在创建Agent时根据当前登录用户传入不同的tools列表即可。参数校验与净化工具函数必须对输入参数进行严格的校验。即使Claude模型已经根据schema生成了参数也要防范潜在的注入攻击或非法值。例如一个删除文件工具必须校验文件路径是否在允许的目录内。tool(nameread_file) def read_allowed_file(filepath: str) - str: import os # 限制只能读取特定安全目录下的文件 SAFE_BASE_DIR /var/www/safe_data/ full_path os.path.abspath(os.path.join(SAFE_BASE_DIR, filepath)) # 防止目录遍历攻击 if not full_path.startswith(os.path.abspath(SAFE_BASE_DIR)): return 错误无权访问该路径。 if not os.path.exists(full_path): return 文件不存在。 # ... 读取文件 ...访问令牌Token管理如果你的工具需要调用需要认证的外部API如公司内部系统千万不要把API密钥硬编码在工具函数里。应该从安全的配置服务或当前用户的会话信息中获取。6. 常见问题、调试技巧与避坑指南在实际开发和集成claude-toolshed的过程中你肯定会遇到各种问题。下面是我踩过的一些坑和总结的排查思路。6.1 工具不被调用检查描述和对话历史问题你明明定义了一个工具但Claude在对话中从来不调用它。排查步骤检查工具描述这是最常见的原因。描述必须清晰、无歧义准确反映工具的功能和适用场景。对比一下差描述“处理数据”好描述“根据给定的股票代码查询该股票最近一天的收盘价和涨跌幅。”用后者当用户问“苹果股价怎么样”时模型更容易匹配到。检查工具参数Schema在Agent初始化后可以打印出工具列表的schema看看。agent Agent(tools[my_tool]) for t in agent.tools: print(t.name, t.schema) # 查看生成的JSON Schema是否符合预期确保参数类型string, number, boolean等定义正确。 3.检查对话历史/系统提示有时之前的对话历史会把模型“带偏”。或者如果你设置了很强的系统提示如“你是一个只负责翻译的助手”模型可能会自我限制不去调用其他功能的工具。尝试开启一个新的会话新建Agent测试。 4.模型能力确认你使用的Claude模型版本支持工具调用。目前claude-3-opus、claude-3-sonnet和claude-3-haiku都支持但不同版本在工具调用的准确性和主动性上可能有细微差别。6.2 工具调用参数错误强化类型提示和描述问题Claude调用了工具但传入的参数值类型不对或格式错误导致工具函数执行失败。解决方案使用更精确的类型除了基本的str,int,float,bool多用typing模块。List[str],Dict[str, int],Literal[“yes“, “no“]都能生成更精确的schema约束模型的输出。在描述中明确格式如果参数有特定格式如日期“YYYY-MM-DD”邮箱地址一定要在工具描述或参数描述中写明。例如tool(description“查询日历。date参数格式必须为YYYY-MM-DD。”)工具函数内部做防御性校验这是最后一道防线。即使参数不对也要优雅处理。tool(namesend_email) def send_email(to: str, subject: str, body: str) - str: import re # 简单的邮箱格式校验 if not re.match(r[^][^]\.[^], to): return f错误邮箱地址‘{to}’格式无效。 # ... 发送逻辑 ...6.3 异步工具函数卡住或报错确保正确的异步上下文问题在运行异步工具时程序卡住、报错Event loop is closed或Task was destroyed but it is pending。根本原因异步事件循环管理不当。claude-toolshed内部是异步的你的异步工具函数也必须在正确的事件循环中运行。解决与避坑入口点使用asyncio.run()这是最安全的方式如我们所有例子所示。避免在同步函数中调用异步Agent如果你在Flask、Django非异步视图这样的同步Web框架中集成不能直接await agent.run()。你需要使用asyncio.run()在一个新的事件循环中运行或者使用asyncio.create_task并在一个已运行的事件循环中管理。更推荐使用支持异步的Web框架如FastAPI、Sanic、Quart。管理好HTTP会话对于aiohttp不要在每次工具调用时都创建新的ClientSession这很耗资源且可能导致端口耗尽。最好在工具函数外部创建并复用session或者使用框架提供的上下文管理。6.4 如何调试复杂的工具调用逻辑当对话逻辑复杂工具调用链很长时看清内部发生了什么很有必要。开启详细日志claude-toolshed可能内置了日志功能。查看其文档看如何设置日志级别如logging.basicConfig(levellogging.DEBUG)来打印模型请求、响应和工具调用的详细信息。手动打印中间状态你可以在工具函数内部和agent.run前后打印信息。async def main(): agent Agent(tools[...]) user_input “复杂问题...” print(f“用户输入: {user_input}”) # 你可以先看看Agent准备发送给Claude的消息和工具列表 # 这需要查看Agent内部属性具体取决于框架暴露的接口 response await agent.run(user_input) print(f“模型最终回复: {response}”) # 查看完整的对话历史 for msg in agent.conversation.messages: # 假设属性名是这个 print(f“{msg[‘role’]}: {msg[‘content’]}”)使用Claude API Playground或Console有时直接把Agent构建的请求包括系统提示、历史消息、工具定义复制到Anthropic的官方控制台里手动发送能更直观地看到模型的“思考过程”和原始响应有助于调试工具选择或参数生成的问题。6.5 成本控制与Token使用优化Claude API是按Token收费的。复杂的工具调用和长对话历史会快速消耗Token。监控Token用量API的响应头或响应体里通常会包含本次请求消耗的输入/输出Token数。定期统计做到心中有数。精简工具描述在保证清晰的前提下工具描述不要太啰嗦。每个Token都要花钱。定期清理对话历史对于长时间运行的会话定期让模型总结一下然后重置历史只保留总结作为新的系统消息。这能有效控制上下文长度。设置max_tokens参数在创建Agent时合理设置max_tokens防止模型生成过于冗长的回复。最后再分享一个我个人的小技巧在项目初期可以先用一个简单的、硬编码返回值的工具来测试整个流程是否跑通然后再去实现复杂的、依赖外部服务的真实逻辑。这能帮你快速隔离问题确定是工具定义的问题、模型调用的问题还是外部API集成的问题。claude-toolshed这个框架把复杂的AI交互抽象得非常干净让你能专注于创造有价值的工具本身而不是陷在协议和状态管理的泥潭里。

相关文章:

基于Claude API的AI应用开发:claude-toolshed框架实战指南

1. 项目概述与核心价值最近在折腾AI应用开发,特别是围绕Claude API构建一些自动化工具时,发现了一个挺有意思的开源项目——aksh-3141/claude-toolshed。这名字直译过来是“Claude的工具棚”,听起来就挺接地气的。简单来说,它不是…...

087、Python并发编程:队列Queue与线程安全

087、Python并发编程:队列Queue与线程安全 上周排查一个线上问题,服务端处理传感器上报数据时偶尔会丢失几条。日志里没报错,但计数器就是对不上。最后定位到是多个工作线程共用一个列表,其中一个线程在遍历时,另一个线程正好删除了元素——经典的多线程数据竞争问题。这…...

用手机遥控电脑演讲:开源项目Presentation-Control部署与实战指南

1. 项目概述与核心价值最近在准备一个重要的线上技术分享,过程中遇到了一个几乎所有演讲者都会头疼的问题:如何优雅地控制幻灯片播放,同时又能自如地操作电脑上的其他演示工具,比如代码编辑器、终端或者在线Demo?传统的…...

086、Python数据压缩与归档:zipfile与tarfile实战笔记

086、Python数据压缩与归档:zipfile与tarfile实战笔记 一、从线上故障说起 上周排查一个生产环境问题:某服务每天生成的日志文件把磁盘撑满了。 查看代码发现,开发同事用 open().write() 直接写文本,一年下来积累了上千个文件。 其实这类场景最适合用压缩归档——既节省空…...

别再花冤枉钱!手把手教你用Arduino+ESP32自制车机CAN模拟器(附开源代码)

用ArduinoESP32打造高性价比CAN总线模拟器:从硬件搭建到报文解析全指南 在汽车电子和工业控制领域,CAN总线作为可靠的通信标准已经存在三十余年。面对市面上动辄上千元的商业CAN模拟器,许多开发者、学生和DIY爱好者常常望而却步。实际上&…...

085、命令行工具开发:argparse模块实战笔记

085、命令行工具开发:argparse模块实战笔记 昨天帮同事调试一个数据清洗脚本,问题出在参数解析上。脚本接收三个输入路径,结果他少传了一个参数,程序直接崩溃报“IndexError”。这种体验太糟糕了——用户不知道哪里错了,也不知道该怎么用。这就是为什么我们需要专业的命令…...

Perplexity如何秒级定位IEEE顶会论文?:2024最新实测验证的7步精准检索法

更多请点击: https://intelliparadigm.com 第一章:Perplexity如何秒级定位IEEE顶会论文? Perplexity 是一款基于大语言模型的实时搜索增强工具,其核心优势在于将语义理解与权威学术数据库(如 IEEE Xplore、ACM DL、ar…...

【NotebookLM播客化实战指南】:3步将静态文档转化为高转化率AI播客,92%用户留存提升实测数据曝光

更多请点击: https://intelliparadigm.com 第一章:NotebookLM文档播客化功能详解 NotebookLM 是 Google 推出的基于用户上传文档进行 AI 增强理解与交互的实验性工具,其“文档播客化”(Document Podcasting)功能允许用…...

从单片机寄存器到多线程标志:volatile关键字的5个硬核使用场景详解

从单片机寄存器到多线程标志:volatile关键字的5个硬核使用场景详解 在嵌入式系统和并发编程的世界里,volatile关键字就像一位沉默的守护者,确保编译器不会自作聪明地优化掉那些看似冗余但实际上至关重要的代码。对于习惯了高层抽象语言的开发…...

Angular+Claude协同开发全栈实践(企业级项目落地手册)

更多请点击: https://intelliparadigm.com 第一章:AngularClaude协同开发全栈实践(企业级项目落地手册) 在现代企业级应用开发中,前端框架与AI辅助编程的深度集成正成为提效关键。Angular 提供结构化、可扩展的单页应…...

【限时公开】ElevenLabs企业级有声书工作台搭建指南:Webhook自动触发+Notion项目看板+音频质量AI评分模型(含开源评估脚本)

更多请点击: https://intelliparadigm.com 第一章:ElevenLabs企业级有声书工作台全景概览 ElevenLabs 企业级有声书工作台(Enterprise Audiobook Studio)是一套面向出版机构、教育平台与内容工厂的端到端语音生成协同平台&#x…...

无人机+点云+Civil3D:无控制点场景下的高精度土方算量实战

1. 无人机航测在复杂地形土方算量中的优势 石头山这类复杂地形一直是工程测绘的难点。传统全站仪测量需要测绘人员翻山越岭布设控制点,不仅效率低下,还存在安全隐患。而无人机航测就像给工程装上了"天眼",特别适合解决这类难题。 去…...

Altium Designer 系统偏好设置全解析:从新手到高手的效率跃迁

1. Altium Designer系统偏好设置的重要性 刚接触Altium Designer时,我和大多数新手一样,只关注画原理图、布局布线这些核心功能。直到有次看到同事操作,同样的操作他只用我三分之一的时间完成,我才意识到系统偏好设置的重要性。这…...

im2col算法实现:从原理到代码的逐行剖析

1. im2col算法原理揭秘 想象你正在整理一副扑克牌,需要把相邻的几张牌快速组合起来。im2col算法的核心思想与此类似——它将图像中相邻的像素区域重新排列成矩阵的列,从而将卷积运算转化为高效的矩阵乘法。这个"image to column"的转换过程&am…...

动态未知环境下无人机轨迹规划技术SANDO解析

1. 动态未知环境中的轨迹规划挑战在机器人自主导航领域,动态未知环境下的轨迹规划一直是个棘手问题。想象一下无人机在密集城市环境中穿行,既要避开突然出现的行人车辆,又要应对GPS信号丢失和传感器视野受限的情况。传统规划方法通常需要精确…...

taotoken api key管理与访问控制保障企业开发安全

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Taotoken API Key 管理与访问控制:保障企业开发安全 在团队协作开发中,安全、可控地使用大模型能力是技术负…...

基于MCP协议构建AI工具服务器:从原理到企业级实践

1. 项目概述:一个连接上下文与工具的智能服务器最近在折腾AI应用开发,特别是想让大语言模型(LLM)能更“聪明”地使用外部工具和数据。我发现,很多项目要么是把工具调用逻辑硬编码在提示词里,要么就是搞一套…...

Box64终极指南:5分钟学会在ARM设备上运行x86_64程序

Box64终极指南:5分钟学会在ARM设备上运行x86_64程序 【免费下载链接】box64 Box64 - Linux Userspace x86_64 Emulator with a twist, targeted at ARM64, RV64 and LoongArch Linux devices 项目地址: https://gitcode.com/gh_mirrors/bo/box64 你是否曾经梦…...

物联网设备安全:硅基硬件防护方案解析

1. 物联网设备安全现状与挑战在智能家居、工业自动化、医疗监测等领域,物联网设备正以惊人的速度普及。根据IDC的调研数据,超过27%的企业在选择物联网供应商时将安全能力作为首要考量标准。然而现实情况是,大多数物联网设备仍在使用软件层面的…...

通过MCP协议集成ChatGPT桌面应用,实现AI助手无缝协作

1. 项目概述与核心价值最近在折腾AI工作流,发现一个痛点:我经常在Claude Desktop或者Cursor这类支持MCP协议的AI助手里面写代码、分析问题,但有时候需要调用ChatGPT的能力,比如让它帮我润色一段英文,或者用它的代码解释…...

Awesome-AITools:AI开发者必备的开源工具聚合地图

1. 项目概述:一份AI工具的“藏宝图”如果你是一名AI开发者、研究者,或者只是一个对AI工具充满好奇的探索者,那么你肯定经历过这样的时刻:面对网络上浩如烟海的AI工具,从聊天机器人、代码助手到图像生成、模型训练平台&…...

在Windows上运行iOS应用:ipasim模拟器完整指南与最佳实践

在Windows上运行iOS应用:ipasim模拟器完整指南与最佳实践 【免费下载链接】ipasim iOS emulator for Windows 项目地址: https://gitcode.com/gh_mirrors/ip/ipasim 想在Windows电脑上体验iPhone应用吗?厌倦了为iOS开发而购买昂贵的苹果设备&…...

别再为Canvas跨域头疼了!手把手教你用UniApp H5搞定网络图片转Base64并生成海报(附完整代码)

UniApp H5开发实战:Canvas跨域图片处理与海报生成全攻略 在移动端H5开发中,Canvas绘制网络图片并生成分享海报是个常见需求,但跨域问题往往让开发者头疼不已。本文将带你深入理解Canvas的CORS限制本质,对比两种主流解决方案的技术…...

智慧校园平台建设要多少钱?这份预算规划指南帮你理清思路

✅作者简介:合肥自友科技 📌核心产品:智慧校园平台(包括教工管理、学工管理、教务管理、考务管理、后勤管理、德育管理、资产管理、公寓管理、实习管理、就业管理、离校管理、科研平台、档案管理、学生平台等26个子平台) 。公司所有人员均有多…...

网络安全协议验证不求人:手把手教你用VirtualBox导入SPAN虚拟机跑AVISPA

网络安全协议验证实战:VirtualBoxSPAN虚拟机快速搭建AVISPA实验环境 在网络安全研究领域,协议验证是确保通信安全性的关键环节。AVISPA(Automated Validation of Internet Security Protocols and Applications)作为自动化验证工…...

【2024最新版】ElevenLabs有声书生产流水线:1个API Key+3个Python脚本+2个FFmpeg指令=日更10小时高质量音频

更多请点击: https://intelliparadigm.com 第一章:ElevenLabs有声书生产流水线全景概览 ElevenLabs 的有声书生产流水线是一套融合文本预处理、语音合成、音频后处理与元数据封装的端到端自动化系统,专为高质量、多语种、情感一致的有声内容…...

从零到一:手把手教你用LabelImg高效构建VOC与YOLO数据集

1. 为什么你需要掌握LabelImg标注工具 刚接触计算机视觉时,我最头疼的就是数据准备环节。记得第一次尝试训练目标检测模型,花了两周时间收集了上千张图片,却在标注环节卡住了——手动画框太慢,格式转换出错,反复返工差…...

别再死记SGD公式了!用PyTorch手把手带你复现一个‘会滚下山’的优化器(附完整代码)

从零构建PyTorch SGD优化器:可视化梯度下降的物理直觉 想象你站在一座云雾缭绕的山顶,手中握着一颗钢珠。当你松开手指,钢珠会沿着最陡峭的路径滚向谷底——这正是梯度下降算法的核心隐喻。本文将带你用PyTorch重建这个直观过程,不…...

别再手动敲表格了!用Python+PaddleOCR,5分钟搞定图片转Excel(附完整代码)

智能表格提取革命:用PaddleOCR实现图片转Excel的工业级解决方案 在数据驱动的商业环境中,每天有数百万份纸质表格、扫描文档和截图等待被数字化处理。传统的手动录入不仅效率低下,错误率高达18%-22%(国际数据公司2023年办公自动化…...

PostgreSQL游标实战:大数据处理、分页优化与性能避坑指南

1. 项目概述:为什么我们需要关注PostgreSQL游标?在数据库应用开发中,尤其是处理海量数据时,我们常常会遇到一个经典难题:如何高效、安全地遍历一个包含数百万甚至上亿条记录的结果集?直接使用SELECT * FROM…...