HITL 人工介入拦截器

📅 2026/7/22 3:30:24
HITL 人工介入拦截器
对高危操作进行人工确认engine.setHitlEnabled(true);HITLInterceptor hitl new HITLInterceptor();hitl.onTool(“bash”, new HitlStrategy()); // bash 命令需要人工确认hitl.onTool(“write”, new WriteAuditStrategy()); // 写入操作审计HarnessEngine engine HarnessEngine.of(“work”, “.soloncode/”).hitlInterceptor(hitl).hitlEnabled(true).build();7.4 自定义拦截器HarnessEngine engine HarnessEngine.of(“work”, “.soloncode/”).extensionAdd((agentName, agentBuilder) - {agentBuilder.defaultInterceptorAdd(new ReActInterceptor() {Overridepublic void onAgentStart(ReActTrace trace) {System.out.println(“Agent agentName 开始执行traceId” trace.getTraceId());}});}).build();8. 扩展定制8.1 注册 OpenAPI 接口让 Agent 调用外部业务系统的 REST APIengine.addApiServer(new ApiSource().then(s - {s.setDocUrl(“http://xx.xx.xx/v3/api-docs”); // Swagger/OpenAPI 文档地址s.setApiBaseUrl(“http://xx.xx.xx/”);}));8.2 注册自定义工具HarnessEngine engine HarnessEngine.of(“work”, “.soloncode/”).extensionAdd((agentName, agentBuilder) - {// 注册自定义业务工具agentBuilder.defaultToolAdd(new OrderQueryTool());agentBuilder.defaultToolAdd(new InventoryCheckTool());}).build();8.3 动态系统提示词HarnessEngine engine HarnessEngine.of(“work”, “.soloncode/”).extensionAdd((agentName, agentBuilder) - {if (“main”.equals(agentName)) {agentBuilder.systemPrompt(context - {String project context.get(“projectName”);return “你是 project 项目的 AI 助手请严格遵循项目规范。”;});}}).build();// 也可以在运行时动态修改engine.setSystemPrompt(“新的系统提示词”);8.4 Prompt Caching对于支持缓存的大模型如 Anthropic Claude可以减少重复计算HarnessEngine engine HarnessEngine.of(“work”, “.soloncode/”).cacheControl(CacheControl.of(CacheControl.Type.EPHEMERAL, // 临时缓存“user”, 60_000 // 用户的最后一条消息缓存 60 秒)).build();9. 目录结构与挂载机制马具主目录harnessHome按用途划分子目录子目录 用途sessions/ 会话与任务清单持久化skills/ 技能SKILL.mdagents/ 子代理定义Markdowncommands/ 自定义命令memory/ 心智记忆download/ 下载缓存除了内置目录还可以通过挂载把外部目录接入马具HarnessEngine engine HarnessEngine.of(“work”, “.soloncode/”).mountAdd(MountDir.builder().alias(“team-agents”) // 别名须以 开头.type(MountType.AGENTS) // 挂载类型.path(“~/team/agents/”) // 物理路径.primary(true) // 原始挂载不可删除.writeable(false) // 只读.build()).mountAdd(MountDir.builder().alias(“global-skills”).type(MountType.SKILLS).path(“~/.soloncode/skills/”).build()).build();挂载后可通过别名直接引用team-agents/code-reviewer.mdHarness 自动转换为真实路径。运行时动态管理engine.addMount(mountDir); // 添加挂载engine.hasMount(“team-agents”); // 是否存在engine.refreshMount(“team-agents”); // 重新扫描engine.removeMount(“team-agents”); // 移除primary 不可移除engine.getMounts(); // 所有挂载engine.getAgents(); // 所有子代理engine.getSkills(); // 所有技能10. 完整实战代码审查 Agent下面是一个完整的例子结合了本节介绍的大部分特性import org.noear.solon.ai.agent.AgentSession;import org.noear.solon.ai.agent.session.InMemoryAgentSession;import org.noear.solon.ai.agent.session.AgentSessionProvider;import org.noear.solon.ai.chat.ChatConfig;import org.noear.solon.ai.harness.HarnessEngine;import org.noear.solon.ai.harness.permission.ToolPermission;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;public class CodeReviewApp {public static void main(String[] arg) throws Throwable {AgentSessionProvider sessionProvider new AgentSessionProvider() {private final MapString, AgentSession sessionMap new ConcurrentHashMap();Overridepublic AgentSession getSession(String instanceId) {return sessionMap.computeIfAbsent(instanceId, k - InMemoryAgentSession.of(k));}};HarnessEngine engine HarnessEngine.of(/data/projects/myapp, .soloncode/) .systemPrompt(你是一个资深代码审查专家负责分析代码质量。) .sessionProvider(sessionProvider) .sessionWindowSize(12) .compressionThreshold(50, 40_000) .maxTurns(30) .autoRethink(true) .toolsAdd(ToolPermission.TOOL_PI) // read, write, edit, bash .modelAdd(new ChatConfig().then(slf - { slf.setApiUrl(https://api.deepseek.com); slf.setApiKey(sk-***); slf.setModel(deepseek-chat); })) .sandboxEnabled(true) .build(); // 第一次对话审查代码 AgentSession session engine.getSession(review-001); engine.prompt(审查 src/main/java/com/example/UserService.java 检查潜在问题并输出审查报告到 code-review.md) .session(session) .call(); // 第二次对话基于历史修复问题 engine.prompt(根据刚才生成的审查报告修复代码中的问题) .session(session) .call(); }}总结