harness - OpenAPI 业务接口接入
Harness 可以把 OpenAPI v2 / v3 文档描述的 HTTP 接口接入为 Agent 工具。需要区分两个概念:
apiServerAdd(name, source)的name是 Harness 构建期配置 Map 的键;ApiSource.docUrl是OpenApiGatewayTalent的运行时管理键。
1、开启 OpenAPI 工具权限
当前工具权限枚举是 ToolName.TOOL_OPENAPI,实际工具名为 openapi:
HarnessEngine engine = HarnessEngine.of("work", ".soloncode/")
.sessionProvider(sessionProvider)
.toolsAdd(ToolName.TOOL_OPENAPI)
.build();
// 运行时动态授权
engine.allowTool("openapi");
新代码不要再使用旧的 REST API 工具枚举;AgentFactory 仍兼容旧字符串 restapi,但推荐统一使用 ToolName.TOOL_OPENAPI 或字符串 openapi。
2、构建期静态注册
ApiSource source = new ApiSource().then(api -> {
api.setDocUrl("https://api.example.com/v3/api-docs");
api.setApiBaseUrl("https://api.example.com");
});
HarnessEngine engine = HarnessEngine.of("work", ".soloncode/")
.sessionProvider(sessionProvider)
.toolsAdd(ToolName.TOOL_OPENAPI)
.apiServerAdd("orders", source)
.build();
这里的 "orders" 只作为 HarnessOptions.apiServers 配置 Map 的键。引擎构建 OpenApiGatewayTalent 时遍历 Map 的 value,并通过 source.getDocUrl() 注册运行时 API 源;配置键 orders 不会传给网关,也不是 Agent 工具名。
因此,运行时查询、刷新和移除必须传 docUrl,不能传 orders:
String docUrl = "https://api.example.com/v3/api-docs";
ApiSourceClient client = engine.getApiServer(docUrl);
engine.refreshApiServer(docUrl);
engine.removeApiServer(docUrl);
3、ApiSource 配置
ApiSource source = new ApiSource();
source.setDocUrl("https://api.example.com/v3/api-docs");
source.setApiBaseUrl("https://api.example.com");
source.addHeaderVar("Authorization", "Bearer ${token}");
source.addAllowedTool("getOrder");
source.addDisallowedTool("deleteOrder");
source.setTimeout(Duration.ofSeconds(30));
source.setAuthenticator(authenticator);
source.setEnabled(true);
主要字段:
| 字段 | 说明 |
|---|---|
docUrl | OpenAPI 文档地址;也是网关运行时 API 源键 |
apiBaseUrl | 实际业务接口基地址,可覆盖文档中的 server 地址 |
headers | 获取文档或调用接口时使用的请求头,可用 addHeaderVar 追加 |
allowedTools | 工具白名单;为空时不按白名单限制 |
disallowedTools | 工具黑名单,从候选接口中排除 |
timeout | HTTP 请求超时,类型为 Duration |
authenticator | 自定义 ApiAuthenticator |
enabled | 是否把该源的工具加入激活索引,默认 true |
allowedTools / disallowedTools 用于裁剪最终激活的接口工具。修改运行时 Client 的过滤配置后,应刷新对应 docUrl,使网关工具索引重新同步。
4、运行时动态管理
ApiSource source = new ApiSource();
source.setDocUrl("https://api.example.com/v3/api-docs");
source.setApiBaseUrl("https://api.example.com");
// 运行时添加:docUrl 同时作为网关运行键和 Harness 配置 Map 键
engine.addApiServer(source);
String docUrl = source.getDocUrl();
ApiSourceClient client = engine.getApiServer(docUrl);
engine.refreshApiServer(docUrl);
engine.removeApiServer(docUrl);
运行时 API 的键语义如下:
| API | 使用的键 |
|---|---|
Builder.apiServerAdd(name, source) | name 写入 Harness 配置 Map;网关仍以 source.docUrl 注册 |
engine.addApiServer(source) | source.docUrl 同时写入配置 Map 和网关 |
engine.getApiServer(docUrl) | 网关运行时 docUrl |
engine.refreshApiServer(docUrl) | 网关运行时 docUrl |
engine.removeApiServer(docUrl) | 按 docUrl 移除网关项,并尝试移除同键配置项 |
engine.getApiServers() | 返回 Harness 配置 Map<String, ApiSource> |
这意味着 engine.getApiServers() 的 Map 键取决于注册入口:
- 构建期
.apiServerAdd("orders", source)的键是orders; - 运行时
engine.addApiServer(source)的键是source.getDocUrl()。
还要注意:如果构建期配置键 orders 与 docUrl 不同,removeApiServer(docUrl) 能移除网关运行项,但配置 Map 中的 orders 项不是同一个键。不要把配置 Map 的 name 与网关运行时 docUrl 混为一谈。
5、查看与刷新接口工具
String docUrl = "https://api.example.com/v3/api-docs";
ApiSourceClient client = engine.getApiServer(docUrl);
client.getTools(); // 文档解析出的全部接口工具
client.getToolsActivated(); // 经允许/禁用列表裁剪后的激活工具
client.setAllowedTools(Arrays.asList("getOrder", "listOrders"));
client.setDisallowedTools(Collections.singletonList("deleteOrder"));
engine.refreshApiServer(docUrl);
ApiSourceClient 的运行时过滤配置与网关全局工具索引是两个层次;调整允许/禁用列表后调用 refreshApiServer(docUrl),才能把变化同步到后续 Agent 工具选择中。
6、说明
- OpenAPI 私域工具权限使用
ToolName.TOOL_OPENAPI,实际工具名为openapi。 apiServerAdd(name, source)的name是构建期配置键;运行时管理 API 一律使用docUrl。- OpenAPI 工具由
OpenApiGatewayTalent管理,重试次数由apiRetries控制,默认 3。 - MCP 接入见 《harness - MCP 服务接入》,LSP 接入见 《harness - LSP 服务接入》。