ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Agent-Reach 实战:AI Agent 如何通过 CLI 工具链触达外部世界

Agent-Reach 实战:AI Agent 如何通过 CLI 工具链触达外部世界 1. 从 Agent-Reach 看 AI Agent 工具链的落地逻辑1.1 这个项目到底在解决什么问题Agent-Reach 这个名字本身就透露了很多信息。Agent 指的是 AI AgentReach 可以理解为触达、连接、延伸。把这两个词放在一起它要解决的核心问题就是让 AI Agent 真正能够触达外部世界而不只是停留在对话框里跟你聊天。我接触过不少做 AI Agent 的团队大家普遍卡在同一个地方——模型本身很聪明推理能力也够用但你让它去操作一个 CLI 工具、去调一个 Python 脚本、去访问一个 GitHub 仓库它就抓瞎了。Agent-Reach 这类项目的价值就在于它在模型和真实工具之间搭了一层桥。具体来说它做的事情包括几个层面。第一层是工具注册与发现让 Agent 知道自己有哪些能力可以调用。第二层是调用协议的统一不管底层是 Python 函数、CLI 命令还是 HTTP 接口对上层 Agent 来说都是统一的调用方式。第三层是结果的结构化返回把各种乱七八糟的输出格式统一成 Agent 能理解的格式。这个项目适合谁来参考如果你正在搭建 AI Agent 系统或者想把现有的 CLI 工具接入到 Agent 工作流里又或者你只是想搞清楚 Agent 到底怎么跟外部工具交互那这个项目的思路都值得仔细看看。哪怕你不直接用它的代码理解它的设计逻辑也能帮你少走很多弯路。1.2 为什么 CLI 是 Agent 触达外部世界的首选通道热词里出现了大量 CLI 相关的内容——zcode cli、codex cli、boos cli、openspec cli、minimax cli。这不是偶然的。CLI 之所以成为 AI Agent 连接外部能力的首选通道有几个非常实际的原因。CLI 工具天然就是为自动化设计的。你想想一个命令行工具从诞生那天起它的输入就是文本参数输出就是标准输出流这跟 AI Agent 的工作方式几乎完美匹配。Agent 生成一段命令执行拿到文本结果继续推理。整个链路非常干净。相比之下GUI 操作就麻烦得多。你得处理屏幕截图、坐标定位、窗口焦点这些跟核心任务无关的事情。HTTP API 虽然也适合程序调用但很多内部工具根本没有 API只有 CLI。所以 CLI 就成了覆盖面最广、改造成本最低的选择。还有一个容易被忽略的点CLI 工具的错误处理机制非常成熟。退出码、标准错误输出、参数校验这些东西已经存在了几十年Agent 可以直接利用。你不需要重新发明一套错误处理协议直接用现成的就行。我在实际项目里做过对比同样一个文件处理任务通过 CLI 封装给 Agent 调用从开发到调试完成大概只需要半天。如果走 GUI 自动化那条路光是处理不同分辨率下的界面适配就得折腾好几天。这个效率差距是数量级的。1.3 Agent-Reach 的架构选型背后有哪些考量从热词里能看到 Python 和 Rust 都出现了。Python 是 AI Agent 领域的主流语言生态丰富上手快。Rust 则在性能和安全性上有明显优势适合做底层的基础设施。Agent-Reach 这类项目通常采用混合架构。核心的调度和协议层用 Rust 或者 Go 来写保证并发处理和长时间运行的稳定性。工具的具体实现和 Agent 的逻辑层用 Python方便快速迭代和接入各种 AI 库。这种分层设计的好处是底层不需要频繁变动上层可以快速试错。你换一个模型、改一个提示词策略不需要动底层的通信机制。反过来底层优化了性能上层的业务逻辑完全不受影响。另一个关键选型是通信方式。Agent 和工具之间用什么协议通信常见的选择有 stdio、HTTP、WebSocket、gRPC。Agent-Reach 这类项目一般会优先支持 stdio因为最简单、最通用。任何能读写标准输入输出的程序都能接入不需要额外开端口、配网络。注意选 stdio 做主要通信方式时一定要处理好超时和缓冲区的问题。有些 CLI 工具输出大量数据时会阻塞如果 Agent 端没有做流式读取整个调用就会卡死。2. 核心细节解析与实操要点2.1 工具注册机制的设计与实现Agent-Reach 要让 Agent 知道有哪些工具可用这就需要一个注册机制。最直接的做法是维护一个工具描述文件里面列出每个工具的名称、功能说明、参数定义和返回值格式。这个描述文件通常用 JSON 或 YAML 来写。为什么不用代码直接定义因为描述文件可以被 Agent 直接读取和理解不需要执行代码就能获取工具信息。这对于动态加载和热更新非常重要。一个典型的工具描述大概长这样{ name: file_search, description: 在指定目录下搜索匹配的文件, parameters: { directory: { type: string, description: 搜索的起始目录, required: true }, pattern: { type: string, description: 文件名匹配模式支持通配符, required: true } }, command: find {directory} -name {pattern}, timeout: 30 }这里有几个设计细节值得注意。command 字段用的是模板字符串Agent 只需要填充参数就行不需要自己拼接命令。这样做的好处是安全——参数会被正确转义避免命令注入。timeout 字段给每个工具设置了独立的超时时间防止某个工具卡死拖垮整个 Agent。参数的类型定义也很关键。Agent 需要知道每个参数是字符串、数字还是布尔值才能生成正确的调用。如果类型定义不清晰Agent 可能会把数字当成字符串传进去导致工具执行失败。我在实际使用中发现工具描述里的 description 字段写得越详细Agent 的调用准确率越高。不要只写搜索文件要写清楚搜索的范围、匹配规则、返回结果的格式。这些信息会直接影响 Agent 的判断。2.2 参数传递与安全边界Agent 生成的参数不能直接拼接到命令里执行这是安全底线。必须经过转义和校验两个环节。转义解决的是特殊字符的问题。比如文件名里包含空格或引号如果不转义命令就会被截断或产生意外行为。Python 的 shlex.quote() 就是干这个的它会把参数包装成 shell 安全的形式。校验解决的是参数合法性的问题。Agent 可能会生成超出预期的参数值比如一个路径参数传入了系统目录或者一个数字参数传入了负数。这些都需要在工具层做校验不能指望 Agent 每次都生成正确的参数。import shlex import os def validate_path(path, allowed_base): 确保路径在允许的范围内 real_path os.path.realpath(path) real_base os.path.realpath(allowed_base) if not real_path.startswith(real_base): raise ValueError(f路径超出允许范围: {path}) return real_path def build_command(template, params): 安全地构建命令 safe_params {} for key, value in params.items(): if isinstance(value, str): safe_params[key] shlex.quote(value) else: safe_params[key] str(value) return template.format(**safe_params)这段代码展示了两个核心防护措施。validate_path 确保 Agent 不能访问指定目录之外的文件。build_command 对所有字符串参数做 shell 转义。两层防护叠加基本能挡住常见的注入攻击。提示不要依赖 Agent 自己来做参数校验。模型可能会被诱导生成恶意参数也可能只是单纯犯错。安全边界必须放在工具执行层这是最后一道防线。2.3 输出解析与结果结构化CLI 工具的输出格式五花八门有的返回 JSON有的返回纯文本有的返回表格。Agent-Reach 需要把这些输出统一成 Agent 能理解的结构。最理想的情况是工具本身支持 JSON 输出。很多现代 CLI 工具都有 --json 或 --format json 这样的选项。如果有优先用这个解析成本最低。如果没有 JSON 输出就需要写解析器。解析器要处理几种常见情况固定格式的文本输出、带分隔符的表格、键值对形式的结果。每种情况的解析策略不同。固定格式的文本输出最麻烦因为格式可能会随版本变化。我的做法是尽量用正则表达式提取关键信息而不是按位置截取。位置截取太脆弱了工具输出多一行少一行就全乱了。import re import json def parse_output(raw_output, output_format): 将工具输出解析为结构化数据 if output_format json: return json.loads(raw_output) if output_format lines: return [line.strip() for line in raw_output.splitlines() if line.strip()] if output_format key_value: result {} for line in raw_output.splitlines(): match re.match(r^(\w):\s*(.)$, line) if match: result[match.group(1)] match.group(2).strip() return result return {raw: raw_output}这个解析函数覆盖了三种最常见的输出格式。实际项目中可能还需要处理更多格式但思路是一样的先判断格式类型再用对应的解析策略。解析失败时的处理也很重要。不要让解析异常直接抛给 Agent而是返回一个包含原始输出的错误对象。这样 Agent 至少能看到原始信息有机会自己判断问题出在哪里。2.4 超时控制与资源限制Agent 调用工具时最怕的就是工具卡住不返回。一个卡死的工具会阻塞整个 Agent 的执行流程严重时会导致整个系统无响应。超时控制要在多个层面做。进程层面设置最大执行时间超过就强制终止。通信层面设置读写超时防止在等待输出时无限阻塞。Agent 层面设置整体任务超时确保单个工具的异常不会拖垮整个任务。import subprocess import signal def execute_with_timeout(command, timeout_seconds): 带超时控制的命令执行 process subprocess.Popen( command, shellTrue, stdoutsubprocess.PIPE, stderrsubprocess.PIPE, preexec_fnos.setsid ) try: stdout, stderr process.communicate(timeouttimeout_seconds) return { success: process.returncode 0, stdout: stdout.decode(utf-8, errorsreplace), stderr: stderr.decode(utf-8, errorsreplace), returncode: process.returncode } except subprocess.TimeoutExpired: os.killpg(os.getpgid(process.pid), signal.SIGTERM) return { success: False, error: f命令执行超时{timeout_seconds}秒, stdout: , stderr: }这里用 os.setsid 创建了新的进程组超时时用 killpg 终止整个进程组。为什么要杀进程组而不是单个进程因为很多 CLI 工具会启动子进程只杀父进程的话子进程会变成孤儿进程继续运行占用系统资源。资源限制还包括内存和文件描述符。有些工具处理大文件时会吃掉大量内存如果不加限制可能会影响其他任务的执行。可以用 resource 模块来设置这些限制不过大多数场景下超时控制已经能解决绝大部分问题。3. 实操过程与核心环节实现3.1 环境准备与依赖安装先把基础环境搭起来。Python 是必须的建议用 3.10 以上的版本因为很多 AI 相关的库对新版本支持更好。安装 Python 本身不复杂官网下载安装包一路下一步就行关键是装完之后要把 pip 和虚拟环境配好。# 创建虚拟环境 python -m venv agent-reach-env # 激活虚拟环境 # Windows agent-reach-env\Scripts\activate # macOS/Linux source agent-reach-env/bin/activate # 安装核心依赖 pip install subprocess32 pyyaml jsonschema虚拟环境这一步不能省。Agent 项目依赖的库比较多版本冲突是家常便饭。用虚拟环境隔离每个项目独立一套依赖省心很多。如果要从 GitHub 拉取 Agent-Reach 的源码网络问题可能是第一个拦路虎。GitHub 在国内的访问速度不稳定有时候能打开有时候打不开。我的经验是配置一个镜像源或者用代理工具加速。不过这里不展开讲网络配置你根据自己的网络环境处理就行。拉取代码之后先看 README 和 requirements.txt。README 会告诉你项目的基本用法和依赖关系requirements.txt 列出了所有需要的 Python 包。按照文档一步步来大部分问题都能避免。# 克隆仓库 git clone https://github.com/your-org/agent-reach.git cd agent-reach # 安装项目依赖 pip install -r requirements.txt # 运行测试确认环境正常 python -m pytest tests/ -v测试跑通了说明基础环境没问题。如果测试失败先看错误信息通常是某个依赖没装好或者版本不对。根据错误提示逐个解决就行。3.2 工具接入的完整流程接入一个新工具到 Agent-Reach需要完成四个步骤定义工具描述、实现执行逻辑、注册到工具库、测试调用链路。第一步定义工具描述。在 tools 目录下创建一个新的 YAML 文件按照前面说的格式填写工具信息。注意 description 要写清楚参数定义要完整命令模板要正确。name: git_log description: 获取 Git 仓库的提交历史 parameters: repo_path: type: string description: 仓库路径 required: true count: type: integer description: 返回的提交数量 required: false default: 10 command: git -C {repo_path} log --oneline -n {count} timeout: 15 output_format: lines第二步实现执行逻辑。如果命令模板能直接搞定就不需要额外写代码。如果需要预处理或后处理就在 handlers 目录下写一个 Python 函数。def preprocess_git_log(params): 执行前的参数预处理 if count in params: count int(params[count]) if count 1 or count 1000: raise ValueError(count 必须在 1 到 1000 之间) params[count] count return params def postprocess_git_log(result): 执行后的结果处理 if result[success]: commits [] for line in result[stdout].splitlines(): parts line.split( , 1) if len(parts) 2: commits.append({ hash: parts[0], message: parts[1] }) result[data] commits return result第三步注册到工具库。在配置文件中添加新工具的路径或者在代码中调用注册函数。具体方式取决于 Agent-Reach 的实现看文档就行。第四步测试调用链路。写一个简单的测试脚本模拟 Agent 调用这个工具检查参数传递、命令执行、结果解析各个环节是否正常。from agent_reach import ToolRegistry, ToolExecutor registry ToolRegistry() registry.load_tools(tools/) executor ToolExecutor(registry) result executor.execute(git_log, { repo_path: /path/to/repo, count: 5 }) print(result)这个流程看起来简单但每一步都有坑。工具描述写错了Agent 就找不到工具。参数校验没做好执行时就会报错。结果解析有问题Agent 拿到的数据就是错的。所以每一步都要仔细测试。3.3 与 AI Agent 的集成方式Agent-Reach 本身只是工具调用的基础设施真正发挥价值需要跟 AI Agent 集成。集成的核心是让 Agent 能够发现工具、选择工具、调用工具、理解结果。工具发现通常通过系统提示词来实现。把工具列表和描述注入到 Agent 的上下文中Agent 就能知道有哪些工具可用。工具数量少的时候全部注入没问题。工具数量多了就需要做检索和筛选只注入相关的工具。工具选择是 Agent 自己完成的。Agent 根据当前任务和工具描述判断应该调用哪个工具、传什么参数。这一步的准确率取决于模型能力和提示词质量。提示词里要明确告诉 Agent 工具的使用场景和限制。工具调用通过 Agent-Reach 的 API 完成。Agent 输出一个结构化的调用请求Agent-Reach 解析请求、执行工具、返回结果。这个过程中要做好错误处理工具执行失败时要把错误信息返回给 Agent让 Agent 决定是重试还是换一个方案。class AgentIntegration: def __init__(self, registry, executor, llm_client): self.registry registry self.executor executor self.llm llm_client def build_system_prompt(self): tools_desc self.registry.describe_all() return f你可以使用以下工具来完成任务 {tools_desc} 调用工具时请使用以下格式 tool_call {{name: 工具名, params: {{参数名: 参数值}}}} /tool_call 工具执行结果会以 tool_result 标签返回。 def run(self, user_input): messages [ {role: system, content: self.build_system_prompt()}, {role: user, content: user_input} ] while True: response self.llm.chat(messages) if tool_call not in response: return response tool_call self.parse_tool_call(response) result self.executor.execute( tool_call[name], tool_call[params] ) messages.append({role: assistant, content: response}) messages.append({ role: user, content: ftool_result{json.dumps(result)}/tool_result })这个集成模式是最常见的 ReAct 循环Agent 推理、调用工具、观察结果、继续推理直到任务完成。Agent-Reach 负责工具调用的部分LLM 负责推理和决策的部分。注意工具调用的结果要控制好长度。有些工具会返回大量数据全部塞回给 LLM 会消耗大量 token还可能超出上下文限制。最好在返回前做摘要或截断只保留关键信息。3.4 实际案例用 Agent 自动处理 GitHub 仓库拿一个具体场景来演示。假设你想让 Agent 自动分析一个 GitHub 仓库找出最近一周内修改过的 Python 文件并统计每个文件的代码行数。这个任务需要几个工具配合git 命令获取提交历史find 命令搜索文件wc 命令统计行数。在 Agent-Reach 里把这三个工具都注册好然后让 Agent 自己编排调用顺序。Agent 的推理过程大概是这样的先调用 git_log 获取最近一周的提交从提交信息里提取出修改过的文件名然后对每个文件调用 file_info 获取行数最后汇总结果。# 工具定义示例 tools [ { name: git_log_since, description: 获取指定时间之后的 Git 提交记录, parameters: { repo_path: {type: string, required: True}, since: {type: string, required: True, description: 起始时间如 1 week ago} }, command: git -C {repo_path} log --since{since} --name-only --prettyformat:%H %s, timeout: 30 }, { name: count_lines, description: 统计文件的行数, parameters: { file_path: {type: string, required: True} }, command: wc -l {file_path}, timeout: 10 } ]Agent 执行时会先生成 git_log_since 的调用拿到提交列表和文件名。然后过滤出 .py 结尾的文件对每个文件调用 count_lines。最后把结果整理成表格返回给用户。这个案例展示了 Agent-Reach 的核心价值把多个独立的 CLI 工具串联起来让 Agent 自动完成一个需要多步操作的任务。你不需要写死调用顺序Agent 会根据实际情况灵活调整。实际跑的时候可能会遇到一些问题。比如仓库路径不对git 命令会报错。文件被删除了wc 命令会失败。这些异常情况都需要 Agent 能够处理。Agent-Reach 的错误返回机制在这里就很重要了它把错误信息结构化后返回给 AgentAgent 可以根据错误类型决定下一步怎么做。4. 常见问题与排查技巧实录4.1 工具调用失败的排查思路工具调用失败是最常见的问题排查的时候按照从外到内的顺序来。先看 Agent 有没有正确生成调用请求。有时候 Agent 会生成格式错误的 JSON或者参数名写错了。这种情况检查系统提示词确保工具调用的格式说明清晰明确。再看 Agent-Reach 有没有正确解析请求。如果请求格式没问题但执行没发生可能是解析逻辑有 bug。打开调试日志看看解析后的参数是什么。然后看命令有没有正确执行。把 Agent 生成的命令复制出来在终端里手动跑一遍。如果手动跑也失败那就是命令本身的问题。如果手动跑成功但 Agent 调用失败那就是执行环境的问题。最后看结果有没有正确返回。有时候命令执行成功了但结果解析出错Agent 拿到的是空数据或错误数据。检查解析器的正则表达式和格式判断逻辑。# 调试辅助函数 def debug_tool_call(tool_name, params): 打印工具调用的详细信息 print(f工具名称: {tool_name}) print(f参数: {json.dumps(params, indent2, ensure_asciiFalse)}) tool registry.get(tool_name) if not tool: print(错误: 工具未注册) return command build_command(tool[command], params) print(f生成命令: {command}) result execute_with_timeout(command, tool.get(timeout, 30)) print(f执行结果: {json.dumps(result, indent2, ensure_asciiFalse)})这个调试函数在排查问题时非常有用。它把工具调用的完整链路都打印出来哪一步出问题一目了然。4.2 常见问题速查表问题现象可能原因排查方法解决方案Agent 不调用工具工具描述未注入或格式错误检查系统提示词中的工具列表修正提示词格式确保工具描述完整调用参数错误参数类型定义不清晰查看 Agent 生成的原始请求完善参数描述增加示例命令执行超时工具处理数据量过大手动执行命令观察耗时增加超时时间或优化命令结果解析失败输出格式与预期不符打印原始输出对比解析逻辑更新解析器增加格式兼容权限拒绝执行用户权限不足检查文件和目录权限调整权限或更换执行用户中文乱码编码不一致检查输出编码格式统一使用 UTF-8 编码进程残留超时后未正确终止查看系统进程列表使用进程组终止方式这张表覆盖了我遇到过的大部分问题。实际排查时先从最简单的可能性开始排除不要一上来就怀疑代码有 bug。大部分问题都是配置错误或环境问题真正需要改代码的情况反而不多。4.3 性能优化的几个实用技巧Agent 调用工具的频率可能很高性能优化不能忽视。第一个技巧是缓存。对于幂等的工具调用比如查询文件信息、获取系统状态可以把结果缓存起来。同样的参数在短时间内重复调用直接返回缓存结果不用重新执行命令。import hashlib import time class ToolCache: def __init__(self, ttl60): self.cache {} self.ttl ttl def _make_key(self, tool_name, params): raw f{tool_name}:{json.dumps(params, sort_keysTrue)} return hashlib.md5(raw.encode()).hexdigest() def get(self, tool_name, params): key self._make_key(tool_name, params) if key in self.cache: entry self.cache[key] if time.time() - entry[time] self.ttl: return entry[result] del self.cache[key] return None def set(self, tool_name, params, result): key self._make_key(tool_name, params) self.cache[key] { result: result, time: time.time() }第二个技巧是并发执行。如果 Agent 需要调用多个互不依赖的工具可以并发执行减少总耗时。Python 的 concurrent.futures 模块就能搞定。第三个技巧是结果截断。工具返回大量数据时只保留 Agent 需要的关键信息。比如搜索文件返回了一万条结果Agent 可能只需要前一百条。在返回前做截断减少数据传输和 token 消耗。提示缓存要注意失效策略。文件内容变了缓存的结果就不准了。对于依赖外部状态的工具要么不缓存要么设置很短的 TTL。4.4 安全加固的实操建议Agent 调用工具的安全风险主要来自两个方面Agent 生成恶意参数以及工具本身存在漏洞。对于第一个风险核心原则是永远不要信任 Agent 生成的参数。所有参数都要经过校验和转义。路径参数要限制在允许的目录内命令参数要防止注入数值参数要检查范围。对于第二个风险要定期审查接入的工具。有些 CLI 工具本身就有安全漏洞或者支持危险的操作。接入前要评估风险必要时做功能限制。比如一个文件删除工具可以限制只能删除特定目录下的文件。# 安全策略配置示例 security_policy { allowed_paths: [/home/user/workspace, /tmp/agent], blocked_commands: [rm -rf /, mkfs, dd if], max_output_size: 1024 * 1024, # 1MB max_execution_time: 60, # 秒 require_confirmation: [delete, modify, execute] } def check_security(tool_name, params, policy): 安全检查 # 检查路径 for key, value in params.items(): if path in key.lower() or dir in key.lower(): real_path os.path.realpath(value) if not any(real_path.startswith(p) for p in policy[allowed_paths]): raise SecurityError(f路径不在允许范围内: {value}) # 检查命令 command build_command(tool[command], params) for blocked in policy[blocked_commands]: if blocked in command: raise SecurityError(f命令包含禁止的操作: {blocked}) return True这套安全策略在实际项目中非常有必要。我见过因为没做路径校验Agent 把系统文件删了的案例。也见过因为没做命令过滤Agent 执行了危险操作的案例。这些问题的修复成本远高于预防成本。4.5 调试与日志的最佳实践Agent 系统的调试比普通程序复杂因为涉及多个组件的交互。好的日志系统能帮你快速定位问题。日志要记录几个关键信息Agent 的原始输出、解析后的工具调用请求、实际执行的命令、命令的输出结果、执行耗时。这些信息串起来就能还原完整的调用链路。import logging import json logger logging.getLogger(agent_reach) def log_tool_call(tool_name, params, command, result, duration): 记录工具调用的完整信息 log_entry { tool: tool_name, params: params, command: command, success: result.get(success, False), duration_ms: round(duration * 1000, 2), output_preview: result.get(stdout, )[:200] } logger.info(f工具调用: {json.dumps(log_entry, ensure_asciiFalse)})日志级别要合理设置。正常调用记 INFO异常情况记 WARNING 或 ERROR。调试阶段可以开 DEBUG 级别把更详细的信息也记录下来。生产环境记得调回 INFO避免日志文件膨胀太快。日志的存储和检索也要考虑。调用量大的时候日志文件会快速增长。建议按天分割日志文件定期清理旧日志。如果条件允许把日志送到集中的日志系统方便检索和分析。我在实际项目里踩过一个坑日志里记录了完整的命令输出结果某个工具返回了大量数据日志文件一天就涨到了几个 G。后来改成只记录输出的前 200 个字符问题就解决了。这个细节看起来小但在生产环境里很关键。4.6 扩展性与维护性考量Agent-Reach 这类项目要长期维护扩展性是必须考虑的。工具的组织方式要清晰。按功能分类放在不同的目录下每个工具一个文件。命名要有规律方便查找。文档要跟上每个工具都要有说明。版本兼容性要处理好。工具的描述格式可能会演进新版本要能兼容旧格式。执行器的接口要保持稳定不要频繁变动。如果必须做破坏性变更要提供迁移方案。测试覆盖要到位。每个工具都要有单元测试验证参数校验、命令生成、结果解析各个环节。集成测试要覆盖典型的调用场景确保端到端流程正常。# 工具测试示例 import pytest from agent_reach import ToolExecutor pytest.fixture def executor(): ex ToolExecutor() ex.load_tools(tools/) return ex def test_git_log_success(executor): result executor.execute(git_log, { repo_path: /tmp/test-repo, count: 5 }) assert result[success] is True assert len(result[data]) 5 def test_git_log_invalid_path(executor): result executor.execute(git_log, { repo_path: /nonexistent/path, count: 5 }) assert result[success] is False assert error in result def test_git_log_count_limit(executor): with pytest.raises(ValueError): executor.execute(git_log, { repo_path: /tmp/test-repo, count: 99999 })测试用例要覆盖正常情况和异常情况。正常情况验证功能正确异常情况验证错误处理。边界条件特别重要比如参数的最大值、最小值、空值。维护性还体现在代码的可读性上。Agent-Reach 的代码会被不同的人阅读和修改命名要清晰注释要到位逻辑要简单直接。不要为了炫技写复杂的代码简单可靠的实现比聪明的实现更有价值。我在维护自己的 Agent 工具库时最大的体会是文档和测试的时间投入绝对值得。每次加新工具花十分钟写清楚描述和测试用例后面能省下几个小时的排查时间。这个投入产出比非常高。
返回列表