GitHub Copilot SDK 实战指南(Java 版):七大可运行用例详解
GitHub Copilot SDK 实战指南Java 版七大可运行用例详解【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilotGitHub Copilot SDK 提供了一组跨语言的编程接口让开发者可以绕过 GitHub Copilot CLI 交互层直接在自有应用中驱动 Copilot 完成会话创建、消息发送、工具调用与 MCP 服务器接入。本指南基于当前仓库 cookbook/copilot-sdk/java 中的 Java 菜谱展开覆盖 Ralph 循环、错误处理、多会话、文件管理、PR 可视化、会话持久化与可访问性报告 7 个完整用例读完本文你将掌握使用 Java 17 与 JBang 直接运行 Copilot SDK 程序的核心 API、事件模型与工程化最佳实践。环境准备JBang 与依赖声明Java 版菜谱的所有示例都是单文件可运行程序不依赖 Maven/Gradle 工程脚手架而是统一通过 JBang。前置条件Java 17 及以上版本JBang 已安装macOS 可用brew install jbangdev/tap/jbangLinux/macOS 也可用curl -Ls https://sh.jbang.dev | bash -s - app setupWindows 可用scoop install jbang。每个.java文件顶部通过两行特殊注释声明运行方式与依赖///usr/bin/env jbang $0 $ ; exit $? //DEPS com.github:copilot-sdk-java:0.2.1-java.1其中//DEPS声明了当前仓库各菜谱统一使用的 Java SDK 版本0.2.1-java.1JBang 会自动解析并下载依赖。运行方式统一为jbang recipe/XXX.java支持带参运行例如 cookbook/copilot-sdk/java/recipe/README.md 中列举的jbang recipe/RalphLoop.java PROMPT_build.md 20 jbang recipe/PRVisualization.java github/copilot-sdk jbang recipe/ManagingLocalFiles.java /path/to/your/folder核心 API 一览从客户端到会话到消息在深入各菜谱前先建立对 SDK 核心对象的整体认知下述类型均来自com.github.copilot.sdk及其子包见各 recipe 源码的 import 语句API 类型典型方法说明CopilotClientstart()、createSession()、resumeSession()、listSessions()、deleteSession()、close()与 Copilot CLI 通信的客户端入口多数方法返回CompletableFutureSessionConfigsetModel()、setSessionId()、setWorkingDirectory()、setMcpServers()、setStreaming()、setSystemMessage()、setTools()、setOnPermissionRequest()会话配置项链式调用CopilotSessionsend()、sendAndWait()、abort()、getMessages()、getSessionId()、close()一次独立对话的句柄MessageOptionssetPrompt()单条消息的载体PermissionHandlerAPPROVE_ALL权限策略常量自动批准工具调用事件类型AssistantMessageEvent、AssistantMessageDeltaEvent、ToolExecutionStartEvent、ToolExecutionCompleteEvent、SessionIdleEvent、SessionErrorEvent、UserMessageEvent通过session.on(Class, handler)订阅SDK 以异步为设计主轴几乎所有操作都返回CompletableFuture调用方通过.get()同步阻塞或用CompletableFuture.allOf并行编排。模型名直接以字符串传入如gpt-5、gpt-5.1-codex-mini、claude-sonnet-4.5、claude-opus-4.6具体可用模型取决于本地 Copilot CLI 环境。用例一Ralph Loop——自治 AI 编码循环入口文档cookbook/copilot-sdk/java/ralph-loop.md可运行源码cookbook/copilot-sdk/java/recipe/RalphLoop.java。Ralph Loop 是一种自治开发工作流AI Agent 在隔离的上下文窗口中逐轮迭代——每轮读取PROMPT.md、研究规格与代码、挑选计划中的下一个任务、实现并跑测试、更新计划并提交然后退出下一轮以全新上下文重启。其核心洞见是状态活在磁盘上而不是模型的上下文里。while true: ┌─────────────────────────────────────────┐ │ Fresh session隔离上下文 │ │ 1. 读 PROMPT.md AGENTS.md │ │ 2. 研究 specs/* 和代码 │ │ 3. 从 plan 中挑选下一个任务 │ │ 4. 实现 运行测试 │ │ 5. 更新 plan、commit、退出 │ └─────────────────────────────────────────┘ ↻ 下一轮迭代全新上下文简单版最小循环对应源码中RalphLoop.java的主逻辑等价于 Shell 层面的while :; do cat PROMPT.md | copilot ; doneString promptFile args.length 0 ? args[0] : PROMPT.md; int maxIterations args.length 1 ? Integer.parseInt(args[1]) : 50; try (var client new CopilotClient()) { client.start().get(); String prompt Files.readString(Path.of(promptFile)); for (int i 1; i maxIterations; i) { // 每轮新建会话 —— 上下文隔离正是要点 var session client.createSession( new SessionConfig() .setOnPermissionRequest(PermissionHandler.APPROVE_ALL) .setModel(gpt-5.1-codex-mini) .setWorkingDirectory(System.getProperty(user.dir)) ).get(); // 记录工具调用便于观察源码实际实现 session.on(ToolExecutionStartEvent.class, ev - System.out.printf( ⚙ %s%n, ev.getData().toolName())); try { session.sendAndWait(new MessageOptions().setPrompt(prompt)).get(); } finally { session.close(); } } }参数语义args[0]为提示词文件默认PROMPT.mdargs[1]为最大迭代次数默认 50。理想版PLANNING / BUILDING 双模式完整版支持plan参数切换模式——plan模式读取PROMPT_plan.md做差距分析并生成计划否则进入build模式读取PROMPT_build.md实施计划boolean planMode Arrays.asList(args).contains(plan); String mode planMode ? plan : build; int maxIterations Arrays.stream(args) .filter(a - a.matches(\\d)).findFirst() .map(Integer::parseInt).orElse(50); String promptFile planMode ? PROMPT_plan.md : PROMPT_build.md;配套项目文件约定理想版依赖如下目录结构PROMPT_plan.md与PROMPT_build.md的完整提示词模板见 cookbook/copilot-sdk/java/ralph-loop.md两者都要求 Agent 先研究specs/*、IMPLEMENTATION_PLAN.md与src/且强调先搜索代码库确认、不要假设功能缺失project-root/ ├── PROMPT_plan.md # 规划模式指令差距分析 → 生成计划不实现 ├── PROMPT_build.md # 构建模式指令挑任务 → 实现 → 测试 → 提交 ├── AGENTS.md # 操作指南构建/测试/检查命令约 60 行内 ├── IMPLEMENTATION_PLAN.md # 任务清单由规划模式生成是跨会话的共享状态 ├── specs/ # 需求规格每个主题一个文件 └── src/ # 源码AGENTS.md每轮都会被加载应保持精简、只含操作信息如mvn compile、mvn test、mvn checkstyle:check避免上下文浪费。IMPLEMENTATION_PLAN.md是各隔离会话之间的共享数据库。十个最佳实践要点原文给出了可操作性极强的十条准则① 每轮全新上下文绝不跨轮累积② 以磁盘为共享状态③ 用测试/构建/检查构成背压backpressure不过关不允许提交④ 先 PLANNING 再 BUILDING⑤ 观察早期迭代并给提示词加护栏⑥ 计划可丢弃——跑偏就删掉IMPLEMENTATION_PLAN.md重新规划⑦AGENTS.md保持精简⑧ 使用沙箱隔离Agent 拥有完整工具权限⑨ 设置workingDirectory固定项目根目录⑩ 用PermissionHandler.APPROVE_ALL避免打断循环。适用边界适合规格明确、可用测试验证、可无人值守长时间运行的工作功能实现、大重构拆分不适合需要中途人工判断、需求含糊、方向未明的探索性任务。用例二错误处理——连接失败、超时与优雅清理入口文档cookbook/copilot-sdk/java/error-handling.md可运行源码cookbook/copilot-sdk/java/recipe/ErrorHandling.java。try-with-resources 兜底SDK 操作大量使用异步但资源清理仍推荐 Java 原生try-with-resources保证无论是否抛异常客户端与会话都被关闭try (var client new CopilotClient()) { client.start().get(); try (var session client.createSession( new SessionConfig() .setOnPermissionRequest(PermissionHandler.APPROVE_ALL) .setModel(gpt-5)).get()) { var response session.sendAndWait( new MessageOptions().setPrompt(Hello!)).get(); System.out.println(response.getData().content()); } } catch (Exception ex) { System.err.println(Error: ex.getMessage()); }拆解 ExecutionException定位真实错误所有CompletableFuture.get()失败都会被包装成ExecutionException必须getCause()才能看到真实异常例如 Copilot CLI 未安装或连接失败时的IOException。同时处理InterruptedException时要恢复中断标志try (var client new CopilotClient()) { client.start().get(); } catch (ExecutionException ex) { var cause ex.getCause(); if (cause instanceof IOException) { System.err.println(Copilot CLI not found or could not connect: cause.getMessage()); } else { System.err.println(Unexpected error: cause.getMessage()); } } catch (InterruptedException ex) { Thread.currentThread().interrupt(); // 恢复中断标志 System.err.println(Interrupted while starting client.); }对应源码 cookbook/copilot-sdk/java/recipe/ErrorHandling.java 中还演示了分层 catch先ExecutionException、再InterruptedException、最后兜底Exception并打印堆栈便于排查。超时与中止对任何可能无限阻塞的调用用get(timeout, TimeUnit)代替裸get()超时后调用session.abort()取消在途请求try { var response session.sendAndWait( new MessageOptions().setPrompt(Complex question...)) .get(30, TimeUnit.SECONDS); System.out.println(response.getData().content()); } catch (TimeoutException ex) { System.err.println(Request timed out after 30 seconds.); session.abort().get(); }abort()也可配合先send()异步发送、后按条件中止的模式使用session.send(new MessageOptions().setPrompt(Write a very long story...)); Thread.sleep(5000); session.abort().get();优雅关闭与工具错误进程被中断时可通过 JVM shutdown hook 清理Runtime.getRuntime().addShutdownHook(new Thread(() - { try { client.close(); } catch (Exception ex) { System.err.println(Cleanup error: ex.getMessage()); } }));自定义工具出错时返回错误字符串而非抛异常让模型可以优雅恢复var readFileTool ToolDefinition.create( read_file, Read a file from disk, Map.of(type, object, properties, Map.of(path, Map.of(type, string, description, File path)), required, List.of(path)), invocation - { try { var path (String) invocation.getArguments().get(path); return CompletableFuture.completedFuture( Files.readString(Path.of(path))); } catch (IOException ex) { return CompletableFuture.completedFuture( Error: Failed to read file: ex.getMessage()); } } ); var session client.createSession(new SessionConfig() .setOnPermissionRequest(PermissionHandler.APPROVE_ALL) .setModel(gpt-5) .setTools(List.of(readFileTool))).get();最佳实践总结始终 try-with-resources拆ExecutionException.getCause()恢复中断标志为所有可能阻塞的调用设超时工具错误用返回值而非异常生产环境用 SLF4J 等日志框架记录错误详情。用例三多会话并发——同时管理多路独立对话入口文档cookbook/copilot-sdk/java/multiple-sessions.md可运行源码cookbook/copilot-sdk/java/recipe/MultipleSessions.java。每个CopilotSession拥有独立上下文与历史。可创建多会话并分别发消息Follow-up 消息会停留在各自上下文中var session1 client.createSession(new SessionConfig() .setModel(gpt-5) .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)).get(); var session3 client.createSession(new SessionConfig() .setModel(claude-sonnet-4.5) // 不同模型也可并行 .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)).get(); session1.sendAndWait(new MessageOptions().setPrompt(You are helping with a Python project)).get(); session3.sendAndWait(new MessageOptions().setPrompt(You are helping with a Go project)).get();自定义会话 ID 与增删查var session client.createSession(new SessionConfig() .setSessionId(user-123-chat) // 自定义 ID 便于跟踪 .setModel(gpt-5) .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)).get(); System.out.println(session.getSessionId()); // user-123-chat var sessions client.listSessions().get(); // 列出所有会话 client.deleteSession(user-123-chat).get(); // 删除指定会话用 CompletableFuture 并行编排SDK 方法本就返回CompletableFuture因此可先用CompletableFuture.allOf(f1, f2, f3).get()并行创建会话再并行发送消息对应源码 cookbook/copilot-sdk/java/recipe/MultipleSessions.java 正是这种写法三个会话并行创建后分别询问 Java records、sealed classes 与 pattern matchingvar f1 client.createSession(new SessionConfig() .setModel(gpt-5).setOnPermissionRequest(PermissionHandler.APPROVE_ALL)); var f2 client.createSession(new SessionConfig() .setModel(gpt-5).setOnPermissionRequest(PermissionHandler.APPROVE_ALL)); CompletableFuture.allOf(f1, f2).get(); var s1 f1.get(); var s2 f2.get(); CompletableFuture.allOf( s1.sendAndWait(new MessageOptions().setPrompt(Explain Java records)), s2.sendAndWait(new MessageOptions().setPrompt(Explain sealed classes)) ).get();自定义 Executor想控制并发度时可通过CopilotClientOptions.setExecutor()注入自己的线程池var executor Executors.newFixedThreadPool(4); var client new CopilotClient(new CopilotClientOptions().setExecutor(executor)); client.start().get(); // ... 会话运行在自定义线程池上 ... session.close(); client.stop().get(); executor.shutdown();典型场景多用户应用每用户一会话、多任务工作流每任务一会话、不同模型间的 A/B 对比。用例四本地文件管理——按元数据的 AI 分组入口文档cookbook/copilot-sdk/java/managing-local-files.md可运行源码cookbook/copilot-sdk/java/recipe/ManagingLocalFiles.java。本用例让 Copilot 分析指定文件夹中的文件元数据类型、日期、大小等并提出分组策略。建议显式传文件夹路径无参数时使用安全默认值——系统临时目录下的example-filesString targetFolder args.length 0 ? args[0] : System.getProperty(java.io.tmpdir) /example-files;核心实现见源码通过事件驱动的方式等待任务完成用CountDownLatch作为完成信号SessionIdleEvent触发countDown()同时订阅三类事件把执行过程实时打印出来var done new CountDownLatch(1); session.on(AssistantMessageEvent.class, msg - System.out.println(\nCopilot: msg.getData().content())); session.on(ToolExecutionStartEvent.class, evt - System.out.println( → Running: evt.getData().toolName())); session.on(ToolExecutionCompleteEvent.class, evt - System.out.println( ✓ Completed: evt.getData().toolCallId())); session.on(SessionIdleEvent.class, evt - done.countDown()); session.send(new MessageOptions().setPrompt(String.format( Analyze the files in %s and show how you would organize them into subfolders. 1. First, list all files and their metadata 2. Preview grouping by file extension 3. Suggest appropriate subfolders (e.g., images, documents, videos) IMPORTANT: DO NOT move any files. Only show the plan. , targetFolder))); done.await(); session.close();分组策略与干跑模式原文档给出了可直接套用的提示词策略按扩展名images/.jpg/.png/.gif、documents/.pdf/.docx/.txt、videos/.mp4/.avi/.mov按创建日期2024-01/、2024-02/等月份目录按大小tiny-under-1kb/、small-under-1mb/、medium-under-100mb/、large-over-100mb/。干跑dry-run模式提示词中明确DO NOT move any files - just show me the plan先预览再执行。自定义 AI 分组让 Copilot 结合文件名、类型与日期规律给出描述性目录名。交互式整理InteractiveFileOrganizer示例用BufferedReader读标准输入先让 Copilot 提方案、等用户确认再进入命令行循环持续追问。安全要点移动前要求确认考虑同名文件冲突重要文件优先复制而非移动先干跑再实操。用例五PR 可视化——零自定义工具的图表生成器入口文档cookbook/copilot-sdk/java/pr-visualization.md可运行源码cookbook/copilot-sdk/java/recipe/PRVisualization.java。该用例展示如何完全依赖 Copilot 内置能力GitHub MCP Server 拉取 PR 数据、文件工具保存图表、代码执行能力用 matplotlib 等生成图表而不写任何自定义工具。运行方式jbang recipe/PRVisualization.java # 从当前 git 仓库自动探测 jbang recipe/PRVisualization.java github/copilot-sdk # 显式指定仓库仓库探测三连源码中的isGitRepo()/getGitHubRemote()实现了自动探测逻辑先检查命令行参数否则用git rev-parse --git-dir判断是否在 git 仓库是则用git remote get-url origin解析远程地址并通过正则同时兼容 SSHgitgithub.com:owner/repo.git与 HTTPShttps://github.com/owner/repo.git两种格式探测失败再回退到交互式输入且校验owner/repo格式。系统消息注入上下文关键技巧是SystemMessageConfig把仓库与工作目录信息注入系统提示词让 Copilot 具备自主行动所需的背景var systemMessage String.format( context You are analyzing pull requests for the GitHub repository: %s/%s The current working directory is: %s /context instructions - Use the GitHub MCP Server tools to fetch PR data - Use your file and code execution tools to generate charts - Save any generated images to the current working directory - Be concise in your responses /instructions , owner, repoName, cwd); var session client.createSession(new SessionConfig() .setOnPermissionRequest(PermissionHandler.APPROVE_ALL) .setModel(gpt-5) .setSystemMessage(new SystemMessageConfig().setContent(systemMessage)) ).get();随后向会话发送任务提示词拉取最近一周的开放 PR → 计算每个 PR 的天数年龄 → 按合理桶如1 day、1-3 days生成柱状图并保存为pr-age-chart.png→ 总结 PR 健康度平均年龄、最老 PR、疑似停滞数量。会话保持打开用户可继续追问扩展到最近一个月展示最老的 5 个 PR改画饼图按作者分组等。为何选择内置能力而非自定义工具维度自定义工具Copilot 内置能力代码复杂度高极低维护成本自己维护Copilot 维护灵活性逻辑固定AI 自主决策最佳方案图表类型仅限已编码的类型Copilot 能生成的任意类型数据分组桶写死智能分组最佳实践优先自动探测仓库再交互用系统消息提供仓库与工作目录上下文APPROVE_ALL允许工具自动执行保留交互式追问能力指示 Copilot 把图表保存到当前目录便于取用。用例六会话持久化——重启后无缝续聊入口文档cookbook/copilot-sdk/java/persisting-sessions.md可运行源码cookbook/copilot-sdk/java/recipe/PersistingSessions.java。SDK 会自动把会话状态持久化到磁盘应用重启后只要提供稳定的会话 ID即可恢复上下文。创建带 ID 的会话并持久化var session client.createSession(new SessionConfig() .setOnPermissionRequest(PermissionHandler.APPROVE_ALL) .setSessionId(user-123-conversation) // 记住这个 ID .setModel(gpt-5)).get(); session.sendAndWait(new MessageOptions() .setPrompt(Lets discuss TypeScript generics)).get(); System.out.println(Session ID: session.getSessionId()); session.close(); // 关闭会话但数据保留在磁盘恢复会话var session client.resumeSession(user-123-conversation, new ResumeSessionConfig() .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)).get(); // 之前的上下文已恢复 session.sendAndWait(new MessageOptions() .setPrompt(What were we discussing?)).get();列出、删除与读取历史client.listSessions().get()遍历SessionInfo.getSessionId()列出全部会话client.deleteSession(user-123-conversation).get()连同磁盘数据一并删除session.getMessages().get()取回历史消息按event instanceof AssistantMessageEvent / UserMessageEvent分流打印其他事件打印getType()。原文档还提供了完整的SessionManager交互式程序菜单选择创建/恢复/列出恢复失败时打印错误而不崩溃以及检查会话是否存在的辅助函数——用listSessions().stream().anyMatch(...)判断后再决定resumeSession还是createSession。最佳实践会话 ID 融入用户或任务语义如user-123-chat、task-456-review恢复前用listSessions()或 try-catch 处理会话已被删除/过期的情况定期清理无用会话恢复操作务必包 try-catch会话与工作区路径绑定跨环境恢复时要保证工作区一致。用例七可访问性报告——Playwright MCP 驱动的 WCAG 审计入口文档cookbook/copilot-sdk/java/accessibility-report.md可运行源码cookbook/copilot-sdk/java/recipe/AccessibilityReport.java。该用例用 Playwright MCP Server 做浏览器自动化访问目标 URL、抓取可访问性快照、生成结构化 WCAG 报告并可选生成 Playwright 测试文件。除 JBang 外还需npxNode.js可用用npx --version验证运行后按提示输入 URL缺省协议时自动补全https://。会话级 MCP Server 配置核心 API 是SessionConfig.setMcpServers()以Map方式声明本地 MCP 服务器会话创建时即随会话启动MapString, Object mcpConfig Map.of( type, local, command, npx, args, List.of(playwright/mcplatest), tools, List.of(*) ); var session client.createSession(new SessionConfig() .setOnPermissionRequest(PermissionHandler.APPROVE_ALL) .setModel(claude-opus-4.6) .setStreaming(true) // 开启流式输出 .setMcpServers(Map.of(playwright, mcpConfig)) ).get();这使模型获得browser_navigate、browser_snapshot、browser_click等 Playwright 浏览器工具。流式输出与事件同步与sendAndWait不同本用例用AssistantMessageDeltaEvent逐 token 打印增量内容并用SessionIdleEventCountDownLatch在主线程与异步事件流之间同步SessionErrorEvent既打印错误也释放闩锁避免死等var idleLatch new CountDownLatch(1); session.on(AssistantMessageDeltaEvent.class, ev - System.out.print(ev.getData().deltaContent())); session.on(SessionIdleEvent.class, ev - idleLatch.countDown()); session.on(SessionErrorEvent.class, ev - { System.err.printf(%nError: %s%n, ev.getData().message()); idleLatch.countDown(); });提示词工程规范化报告格式任务提示词要求 Copilot① 用playwright-browser_navigate导航② 用playwright-browser_snapshot抓取可访问性快照③ 按固定模板输出报告—— 报告头、✅ 工作良好项Category/Status/Details 表、⚠️ 发现的问题Severity/Issue/WCAG Criterion/Recommendation 表、 统计摘要链接数、标题层级、可聚焦元素、地标、⚙️ 优先级建议并用 ✅///❌ 作严重度标记。报告完成后询问是否生成 Playwright 可访问性测试覆盖 lang 属性、title、标题层级、alt 文本、地标、跳过导航、焦点指示、触摸目标等断言。工作流程配置本地 MCP → 流式输出 → 快照分析 → 结构化报告 → 可选测试生成。原文档还给出了示例交互输出针对github.com的审计含部分图标链接缺少描述文本WCAG 2.4.4建议添加 aria-label这类典型发现可作为报告格式的验收参照。综合最佳实践与阅读延伸七个用例共同勾勒出 Java 版 GitHub Copilot SDK 的完整编程模型可提炼为以下跨用例准则生命周期管理CopilotClient用 try-with-resources 包裹start()后使用close()前确保会话关闭异步与并发拥抱CompletableFuture——串行用.get()并行用allOf控制并发用CopilotClientOptions.setExecutor()事件驱动输出、工具调用、空闲、错误全部走事件订阅长任务用CountDownLatch同步主线程上下文策略需要隔离就用多会话或 Ralph Loop每轮新会话 磁盘共享状态需要延续就用setSessionId()resumeSession()权限与安全自动化场景用PermissionHandler.APPROVE_ALL但 Ralph Loop 等全权限自治任务应放入沙箱文件操作先干跑工具边界优先复用 Copilot 内置能力GitHub MCP、文件工具、代码执行、Playwright MCP仅在必要时用ToolDefinition.create()自定义工具且错误用返回值反馈给模型。更多语言版本.NET/C#、Node.js/TypeScript、Python、Go 的相同 7 个用例可参考 cookbook/copilot-sdk/README.md各 recipe 的可运行源码与参数示例见 cookbook/copilot-sdk/java/recipe/README.md。若要为仓库贡献新的 recipe请遵循 CONTRIBUTING.md 的指引——在语言目录下新增 markdown 文档并附上recipe/中的可运行示例即可。【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考