7. 进入 harness
本章向 harness 的 IToolRegistry 注册一个模型可调用的工具,并观察工具流水线的结果。
示例不需要 API 密钥,也不会调用模型。
工具插件
using Microsoft.Extensions.AI;
using Tether.Core;
ctx.Plugin(Plugin.From(c =>
{
var registry = c.Require<IToolRegistry>();
var tool = AIFunctionFactory.Create(
(string name) => $"Hello, {name}!",
name: "greet",
description: "Greet the named person.");
var registration = registry.Register(tool);
c.Effect(registration.Dispose); // 工具注册随插件卸载而注销
}, typeof(IToolRegistry))); // inject:注册表就绪前保持 PENDING
这里的每个模式都来自前几章:typeof(IToolRegistry) inject
(第 3 章)让插件等待工具注册表就绪;
Register 返回的 IDisposable 交给 ctx.Effect
(第 2 章),卸载时注销工具。
AIFunctionFactory 对应 dsh 的 defineTool:从方法签名推导向模型展示的 JSON Schema,
并在执行前校验模型提供的参数——对齐 Microsoft.Extensions.AI 的既定选型。
观察插件
观察方是独立插件,通过工具流水线的监听器接口观察每次调用(对应 dsh 的 ctx.on('tools/result', ...)):
ctx.Plugin(Plugin.From(c =>
{
var registry = c.Require<IToolRegistry>();
var subscription = registry.RegisterPostExecuteListener(null, (execution, outcome, next) =>
{
Console.WriteLine($"[tool-logger] {execution.Name} -> settled");
return next(); // 观察型监听器必须委托(第 4 章 waterfall 纪律)
});
c.Effect(subscription.Dispose);
}, typeof(IToolRegistry)));
两个插件互不知道对方存在——它们由注册表服务和流水线事件连接。
组合并运行
真实组合里,IToolRegistry 由 Tether.Core.Tools 的 ToolRegistry 提供,连同系统提示词、
LLM 适配器等一起写进 Bundles YAML;Headless 与 CLI 都从 compositions/bundles/ 解析同一份组合
(见 Composition Root 与运行)。缺少提供方时,工具插件会像
第 6 章所述保持 PENDING。
从这里走向完整 agent
真实 agent 就是这套组合再加更多插件:LLM 适配器、agent loop、持久化和运行入口。 对照 预设与组合包,你现在已经可以读懂其中每个配置项。
后续可以阅读: