ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

nanobot My Tool 深度指南:让 AI Agent 具备运行时自我感知与动态调优能力

nanobot My Tool 深度指南:让 AI Agent 具备运行时自我感知与动态调优能力 nanobot My Tool 深度指南让 AI Agent 具备运行时自我感知与动态调优能力【免费下载链接】nanobotUltra-lightweight, open-source, self-hosted personal AI agent framework in Python with WebUI, tools, memory, MCP, multi-agent workflows, automation, and chat apps项目地址: https://gitcode.com/gh_mirrors/nanob/nanobot本篇指南系统讲解 nanobot 内置的my自省工具Self-Awareness Skill它让 Agent 能够检查自己正在运行的模型、上下文窗口、工作区与工具配置诊断为什么某个功能不可用在任务过程中动态切换模型预设、调整迭代上限并通过 scratchpad 在会话内跨轮次记住偏好。读完本文你将掌握my工具的完整配置方式、check/set两种动作的全部关键参数、安全边界设计以及从源码实现到测试用例的完整证据链。为什么 Agent 需要自我感知常规工具让 Agent 作用于外部世界——读写文件、搜索代码、执行命令。但 Agent 对自己的运行状态几乎一无所知它不知道自己在跑哪个模型、能访问哪个工作区、每轮对话的迭代上限是多少。nanobot 的my工具Skill 定义填补了这个空白。在 官方文档 中它的定位被形象地描述为像问同事你现在忙不忙能换个大点的显示器吗。借助该工具Agent 可以认识自己我用的什么模型我的工作区在哪我的每轮迭代上限是多少动态适应任务复杂就扩大上下文窗口简单问答就切换更快的模型。跨轮次记忆把临时偏好写进 scratchpad在下一轮对话中继续读取。my工具的实现位于 nanobot/agent/tools/self.py其背后的运行时状态边界由 nanobot/agent/tools/runtime_control.py 提供并配有完整的单元测试 tests/agent/tools/test_self_tool.py。一、基础用法两种动作与三个参数my工具暴露了极简的接口——两个动作action、一个键key、一个值value参数类型说明actionstring必填check检查或set设置枚举值见 self.py 的参数定义keystring点路径dot-path。例如max_iterations、web_config.enable、request.channel留空表示查看全部配置概览valueany仅set时需要类型必须与目标匹配max_iterations/context_window_tokens为 intmodel/model_preset为 strSkill 文档 SKILL.md 给出的推荐使用流程是四步从下方分类中识别当前场景以合适的action调用my工具若涉及set在改动模型或运行时上限这类影响较大的设置前先警告用户需要详细示例时查阅 references/examples.md。二、配置默认只读可一键放开写权限my工具默认启用但处于只读模式Agent 可以检查状态但不能修改。配置项在 MyToolConfig 定义 中对应 YAML 配置为tools: my: enable: true # 默认 true启用工具 allow_set: false # 默认 false只读模式将allow_set设为true后Agent 才可以修改运行时配置切换模型、调整参数等。工具是否可用由 MyTool.enabled 决定需要ctx.runtime_control存在且ctx.config.my.enable为真create时若没有 runtime control 能力会直接抛错。旧配置键自动迁移早期版本使用扁平键tools.myEnabled/tools.mySet加载时会被自动迁移为tools.my.enable/tools.my.allowSet下次运行nanobot onboard刷新配置时会原地重写。迁移逻辑见 nanobot/config/loader.py。持久化边界除model_preset外绝大多数修改只在内存中生效model_preset会保存到当前会话从而在重启后依然生效细节见下文约束一节。三、check查看我的当前状态3.1 无 key一键获取关键配置概览不带key参数时返回核心配置概览内容来自 RuntimeSnapshot.as_mapping 的白名单字段my(actioncheck) # → max_iterations: 40 # context_window_tokens: 200000 # model: anthropic/claude-sonnet-4-6 # workspace: PosixPath(/tmp/workspace) # provider_retry_mode: standard # max_tool_result_chars: 16000 # _last_usage: {prompt_tokens: 45000, completion_tokens: 8000}概览的渲染顺序与内容在 _inspect_all 中定义依次输出受保护参数、model_preset、workspace、provider_retry_mode、max_tool_result_chars、web_config、exec_config、subagents若 scratchpad 非空还会追加展示。注意prompt_tokens是跨所有轮次的累计值不是当前上下文窗口的占用率。3.2 带 key点路径精准下钻my(actioncheck, keymodel) # 当前运行的模型 my(actioncheck, keymodel_preset) # 当前生效的模型预设 my(actioncheck, keymax_iterations) # 每轮迭代上限 my(actioncheck, keyworkspace) # 工作目录 my(actioncheck, keyweb_config.enable) # 网页搜索是否启用 my(actioncheck, keysubagents) # 子 Agent 运行状态点路径解析由 _resolve_path 实现按.切分逐级下钻同时每一级都会经过_DENIED_ATTRSPython 内省属性、BLOCKED核心子系统和敏感字段名的三重拦截。若 key 位于模型运行时字段model/model_preset/context_window_tokens则优先读取当前请求的实时运行时值见 _current_runtime_value保证返回的是本次会话真正生效的配置。3.3 请求路由元数据request.*request是只读的当前消息路由元数据支持三个子字段对应 RequestContext 测试my(actioncheck, keyrequest.channel) # → feishu渠道 my(actioncheck, keyrequest.chat_id) # → oc_abc123聊天 ID my(actioncheck, keyrequest.sender_id) # → ou_user456发送者 ID该元数据只在显式查询时返回——my(actioncheck)的概览输出中不会包含chat_id、sender_id避免把敏感路由信息写进上下文。四、set运行时动态调优set允许在不重启进程的情况下调整运行时状态。修改生效时机分两类见 docs/my-tool.mdmodel_preset保存到当前会话作用于该会话的下一轮对话其他可写参数立即生效。my(actionset, keymax_iterations, value80) # → Bump iteration limit from 40 to 80 my(actionset, keymodel_preset, valuefast) # → 为当前会话的下一轮切换配置好的模型预设4.1 受保护参数类型与范围双重校验以下参数在 RESTRICTED 定义 中声明了类型和取值范围非法值一律拒绝参数类型范围用途max_iterationsint1–100每轮对话的最大工具调用次数context_window_tokensint4,096–1,000,000实例默认上下文窗口会话内应通过 preset 切换modelstr非空实例默认模型会话内应通过 preset 切换model_presetstr已配置的 preset 名称当前会话下一轮使用的预设校验逻辑在 _modify_restricted先校验类型bool 不会被当作 int 接受字符串80会被尝试强转成 int再校验min/max/min_len范围。测试 test_self_tool.py 覆盖了越界、类型错误、bool 冒充 int、None 值等全部拒绝路径。会话内禁止直接改model/context_window_tokens这两个 setter 修改的是共享的实例默认值在活跃会话中会被拒绝返回错误并提示use a configured model_preset。这是刻意的安全设计——实例级变更会影响其他会话会话级需求应通过model_preset表达。4.2 可自由设置的参数workspace、provider_retry_mode、max_tool_result_chars等参数可以随意设置值必须 JSON-safe。workspace的修改尤其特殊_modify_runtime_setting 调用set_workspace_display只更新展示用的工作区路径不会改变文件工具的沙箱边界——这也是 SKILL.md 中Dont set workspace反模式的源码依据。4.3 Scratchpad会话内的临时记忆set一个未知的新 key时值会被写入 scratchpad内存中的 JSON 安全字典跨轮次保留、重启后消失my(actionset, keycurrent_project, valuenanobot) my(actionset, keyuser_style_preference, valueconcise) my(actionset, keytask_complexity, valuehigh)scratchpad 的实现约束见 _modify_scratchpad 与_validate_json_safe最多64 个 key_MAX_RUNTIME_KEYS写满后新增会被拒绝更新已有 key 不受影响测试见 test_self_tool.py值必须是 JSON 安全的str/int/float/bool/None/list/dict拒绝 callable、Path 等复杂对象嵌套深度上限 10 层dict 的 key 必须是字符串敏感字段名api_key、password、secret、token等在任何路径层级都被拦截防止凭据泄入上下文。五、何时用、何时不用Skill 内置的使用规则SKILL.md 把使用时机总结为可操作的规则先诊断再解释Diagnose before explaining当某个功能不工作时先检查自身状态再向用户解释。例如用户问为什么你不能搜网页Agent 应先执行check(web_config.enable)确认开关状态。复杂任务前先查预算Check budget before complex tasks接受大型任务前先确认自己的上下文窗口与迭代上限避免承诺后失败。跨轮次回忆Recall across turns把偏好写进 scratchpad后续轮次再读回来。只在收益明确且用户知情时 setOnly set when benefit is clear and user is informed切换模型前必须警告用户。权衡原则是偏向稳定bias toward stability——只在默认值确实不够用时才动手。反模式Anti-patterns不要每轮都 checkcheck 也是一次工具调用有成本。需要信息时才用不要形成反射式调用。不要在 scratchpad 存敏感数据API key、密码、token 一律不得写入。不要 set workspace如前所述它不更新文件工具边界改了也没用。六、约束与持久化语义model_preset保存到当前会话重启后依然生效其他修改仅存于内存。活跃会话中直接写model和context_window_tokens会被拒绝会改变共享实例默认值请改用配置好的model_preset。受保护参数有类型/范围校验max_iterations1–100、context_window_tokens4096–1M、model非空字符串。若tools.my.allow_set为 false则只能 check、不能 set——此时set会返回Error: set is disabled (tools.my.allow_set is false)见 execute 分支 与 只读模式测试。与其他记忆机制的取舍需求使用持久性会话内临时状态my(actionset, key..., value...)否重启丢失长期事实Memory skillMEMORY.md、USER.md是永久配置变更编辑配置文件是经验法则Rule of thumb明天还要用 → Memory只在本次轮次有用 → My。七、实用场景示例以下示例均来自 references/examples.md可直接作为 Agent 行为模式的参考。7.1 诊断类# 为什么你不能搜网页 → my(actioncheck, keyweb_config.enable) → False → Web search is disabled. Add web.enable: true to your config to enable it. # 你为什么停了 → my(actioncheck, keymax_iterations) → 40 → I hit the iteration limit (40). The task was complex. I can ask the user if they want to increase it. # 你现在跑的是什么模型 → my(actioncheck, keymodel) → anthropic/claude-sonnet-4-6 → my(actioncheck, keymodel_preset) → deep7.2 自适应行为类# 大型代码库分析先查容量再切换到 deep 预设 → my(actioncheck) → context_window_tokens: 200000 → my(actionset, keymodel_preset, valuedeep) → Set model_preset deep for the next turn; context_window_tokens will be 262144 # 简单问题切换到 fast 预设省算力 → my(actionset, keymodel_preset, valuefast) → Set model_preset fast for the next turn; model will be openai/gpt-4.1-mini7.3 跨轮次记忆类# 第 1 轮用户说说简洁点 → my(actionset, keyuser_style, valueconcise) → Set scratchpad.user_style concise # 第 3 轮换了新话题 → my(actioncheck, keyuser_style) → concise 据此调整回答风格 # 跟踪项目上下文 → my(actionset, keyactive_branch, valuefeat/auth) → my(actionset, keytest_framework, valuepytest) → my(actionset, keyhas_docker, valuetrue)7.4 子 Agent 监控subagents是只读字段但提供了丰富的监控信息含阶段、迭代次数、耗时、最近 5 个工具事件和用量格式化逻辑见 _format_status→ my(actioncheck, keysubagents) # → 2 subagent(s): # [task-1] Code review # phase: running, iteration: 5, elapsed: 12.3s # tools: read(✓), grep(✓) # usage: {prompt_tokens: 8000, completion_tokens: 1200} # [task-2] Write tests # phase: pending, iteration: 0, elapsed: 0.2s # tools: none八、安全机制工具绝不改写 config.jsonmy工具的核心设计原则是它不重写配置文件。实例级变更只存在于内存model_preset仅作为当前会话的选择器持久化。在此基础上访问控制分为三个层次定义见 self.py均有对应测试验证BLOCKED——完全隐藏check 和 set 均拒绝类别属性原因核心基础设施bus、provider、runtime_resolver、_running、tools改动会直接搞崩系统或让 Agent 移走自己的工具配置管理_runtime_vars—子系统runner、sessions、consolidator、dream、auto_compact、context、commands影响其他用户/会话敏感运行时状态_pending_queues、_session_locks、_active_tasks、_background_tasks含凭据与消息路由信息安全边界restrict_to_workspace、channels_config绕过会破坏隔离Python 内省__class__、__dict__、__globals__、__wrapped__、__closure__等_DENIED_ATTRS防止沙箱逃逸注意tools与subagents的差异subagents属于READ_ONLY可观察但不可替换tools属于BLOCKED连检查都拒绝因为工具注册表自身也是工具之一。READ_ONLY——只读check 允许set 拒绝属性说明subagents可观察但替换会破坏系统tool_names工具清单exec_config可查看沙箱/启用状态不可修改web_config可查看启用状态不可修改model_presets配置派生的预设目录修改需重新加载配置workspace_sandbox工作区强制级别的只读视图request当前消息路由元数据敏感字段保护子字段名若命中敏感名称集合api_key、secret、password、token、credential、private_key、access_token、refresh_token、auth无论父路径是什么check 和 set 都会被拦截——这防止了通过点路径遍历泄密例如web_config.search.api_key测试见 test_self_tool.py。同时web_config快照在生成时就会对代理 URL 做脱敏处理只显示configured见 _snapshot_web_config。此外所有set操作都会经 _audit 写入结构化日志动作、详情、会话标识便于事后审计被 BLOCKED/READ_ONLY/敏感字段拒绝的写操作同样会记录审计日志。九、源码导读从调用到落地的完整链路如果希望深入理解my工具推荐按以下路径阅读nanobot/skills/my/SKILL.mdSkill 使用规则本体本指南的骨架来源nanobot/skills/my/references/examples.md配套实战示例nanobot/agent/tools/self.pyMyTool完整实现——参数 schema、路径解析、拦截清单、格式化与动作分发nanobot/agent/tools/runtime_control.pyRuntimeSnapshot白名单数据契约与AgentRuntimeControl适配器——它定义了 Agent 能看见和改动的边界docs/my-tool.md面向使用者的官方文档tests/agent/tools/test_self_tool.py1139 行单元测试几乎覆盖了上文提到的每一个拦截规则与格式化分支是理解安全边界的规范说明书。结语my工具是 nanobot 赋予 Agent 的元认知能力通过一个统一的白名单快照RuntimeSnapshot把模型、上下文、工作区、工具、子 Agent 状态安全地暴露给 Agent 自己再用严格的三层拦截BLOCKED / READ_ONLY / 敏感字段把修改能力限制在安全范围内。理解它既能帮助你在配置中正确开启tools.my.allow_set也能让你在设计自己的 Agent 系统时借鉴这种可自省、可自调、有边界的运行时控制模式。【免费下载链接】nanobotUltra-lightweight, open-source, self-hosted personal AI agent framework in Python with WebUI, tools, memory, MCP, multi-agent workflows, automation, and chat apps项目地址: https://gitcode.com/gh_mirrors/nanob/nanobot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进