💡 一句话核心:Agent的能力边界 = 它注册了哪些tool。Registry是Agent的"能力清单",也是风险控制的第一道闸门。
ToolDefinition(带风险等级、超时、schema)引导问题:
答案揭示:
引导问题:
get_user_info 和 delete_all_data 是同一个危险等级吗?(RiskLevel)答案揭示:
生产级ToolDefinition至少包含:
| 字段 | 用途 |
|---|---|
| Name | 唯一标识,LLM用它call |
| Description | 给LLM看的自然语言描述 |
| InputSchema | JSON Schema,定义参数形状 |
| RiskLevel | low/medium/high,决定是否要审批 |
| Timeout | 单次执行的最大时长 |
| Execute | 真正的业务逻辑 |
引导问题:
{"name":"delete_customer","arguments":"..."},但你没注册这个tool,该怎么响应?答案揭示:
反思题:
ToolResult.Output 是string而不是any?(LLM只吃文本。结构化数据另存 Data 字段用于审计)error 返回值还要有 ToolResult.Error 字段?(区分"系统错误"vs"业务错误"——系统错误要重试,业务错误要喂回LLM)关键设计点:
Execute 永不panic(defer recover 兜底)context.WithTimeout 强制实施*ToolResult{Error: ...},LLM能读懂错误enum / required 等约束additionalProperties: false 禁止未知字段(Day 5会实现审批流)
context.WithTimeout 必须传给底层调用defer recover() 兜住ToolResult.Error,系统错误返回 errorerror 和 ToolResult.Error 的区别internal/tools/types.go + schema.go + registry.gointernal/tools/builtin/ 下三个toolsend_email tool(mock即可)RiskHighprioritystream_logs),接口要改成什么样?Q1:为什么 Execute 返回 (*ToolResult, error) 两个值?直接一个不行吗?
A:区分"系统错误(需重试/报警)"和"业务错误(喂回给LLM)"。
Q2:同名tool再注册会怎样? A:返回error。静默覆盖是最难调的bug。
Q3:LLM传了不符合schema的arguments怎么办? A:两层防护:
json.Unmarshal 失败时返回 ToolResult.Error——LLM下一轮会self-correct更严格的做法:用 gojsonschema 库做schema validation。
Q4:Tool执行时想访问请求的 user_id / trace_id,怎么拿?
A:通过context传:
不要用全局变量,不要塞到args里(那是给LLM看的)。
Q5:需要对tool做限流吗?
A:是的。尤其是 create_ticket 这种写操作。实现思路:
RateLimitedRegistry(装饰器)rate.Limiter题目: 给一组区间 [[1,3],[2,6],[8,10]],合并重叠区间。
思路: 按起点排序,遍历合并。
复杂度: O(n log n) / O(1)。
Agent上下文联想: 多个tool调用的time window合并、audit log聚合都能用到。
题目: 有序数组中找target的插入位置(二分变体)。
复杂度: O(log n) / O(1)。
Agent上下文联想: 工具调用的优先级队列插入、timestamp定位。
题目: 返回出现次数前k高的元素。
思路: 哈希计数 + 桶排序(O(n))或最小堆(O(n log k))。
复杂度: O(n log k) / O(n + k)。
Agent上下文联想: 最常用top-k工具统计、热门query分析、cache预热候选。
明天是整个Week 1最关键的一天——Agent Loop:
准备问题: