BrowserPilot源码解析(一):InstructionCompiler如何把自然语言编译成Selenium代码的完整流程

发布时间:2026/8/24 8:19:11
BrowserPilot源码解析(一):InstructionCompiler如何把自然语言编译成Selenium代码的完整流程 BrowserPilot源码解析一InstructionCompiler如何把自然语言编译成Selenium代码的完整流程【免费下载链接】browserpilotNatural language browser automation项目地址: https://gitcode.com/gh_mirrors/br/browserpilotBrowserPilot是一个自然语言浏览器自动化工具你只需用普通英语写几行指令它就能操控 Chrome 浏览器完成搜索、点击、信息提取等任务。它背后的核心魔法藏在InstructionCompiler里——这个编译器把自然语言编译成 Selenium 代码再交给GPTSeleniumAgent执行。下面带你完整走读这套编译流程。看完你就能明白为什么写 BrowserPilot 提示词更像用 Copilot 写代码而不是跟朋友聊天。一、项目结构速览编译器在哪里先建立全局感。BrowserPilot 的代码非常精简核心就三个位置模块路径职责指令编译器instruction_compiler.py把自然语言指令编译成 Python/Selenium 代码浏览器智能体gpt_selenium_agent.py执行编译产物暴露env.*操作方法提示词示例库prompts/examples/开箱即用的自然语言指令模板记忆模块memories/init.py用向量索引记住浏览过的网页GPTSeleniumAgent初始化时会直接点火编译器见 gpt_selenium_agent.py#L108self.instruction_compiler InstructionCompiler( instructionsinstructions, modelself.model_for_instructions, )编译产物不是抽象语法树而是一段可以直接exec的 Python 代码——这是理解后面一切的关键。二、BASE_PROMPT编译器的大脑打开 instruction_compiler.py最先看到的是BASE_PROMPT。它由三部分组成相当于给大模型发的一份工作说明书1️⃣ 能力清单env 工具箱提示词告诉模型你手里有一个叫env的对象它是智能体本身能调用这些方法env.get(url)打开网址env.find_elements(by..., value...)/env.find_element(...)定位元素env.send_keys(element, text)输入文本注意Keys.ENTER等特殊键env.click(element)点击必须用它不能用element.click()env.wait(seconds)、env.scroll(direction)等待与滚动env.get_llm_response(text)直接向 AI 提问env.retrieve_information(prompt)从页面检索信息promptSummarize:可做摘要env.ask_llm_to_find_element(description)让 AI 按描述找元素env.query_memory(prompt)查询浏览记忆env.save(text, filename)、env.get_text_from_page()保存与取文本2️⃣ 硬性约束防止模型自由发挥XPath 中取文本用normalize-space()而不是text()匹配文本用contains(normalize-space(), text)禁止import任何模块、禁止外部库只写代码不写注释缩进必须正确只做指令要求的事大小写敏感3️⃣ 指令插槽{instructions}是占位符运行时会被当前这一块自然语言指令替换。最后以OUTPUT: python结尾把模型输出引导进代码格式。 每个env.*能力都与GPTSeleniumAgent中的方法一一对应。想扩展智能体就得同时改这两处README 的 Contributing 部分也明确这么说。三、三步队列解析函数定义、注入与分块编译这是InstructionCompiler最精巧的设计。用户指令支持四个标记 token定义在 instruction_compiler.py#L16-L19BEGIN_FUNCTION name/END_FUNCTION定义一个函数RUN_FUNCTION name把函数作为独立的一块执行INJECT_FUNCTION name把函数体内联展开进当前块以官方示例 buffalo_wikipedia.yaml 为例instructions: - BEGIN_FUNCTION search_buffalo - Go to Google.com - Find all textareas. - ... - END_FUNCTION - RUN_FUNCTION search_buffalo - Wait for 10 seconds._parse_instructions_into_queue用四队列流水线first → second → third → final分三轮扫描见 instruction_compiler.py#L183-L267第一遍抽出所有函数体存入self.functions字典跳过#注释其余行进第二队列第二遍遇到INJECT_FUNCTION就把函数体拆开、原地展开并和后续行合并第三遍连续的普通行合并成一个块block遇到RUN_FUNCTION则直接把函数体作为独立块入队。为什么按块编译因为每一块只调用一次大模型 API。连续的自然语言指令打包成一个块让模型能理解上下文比如find the firstvisibletextarea指的就是上一句找到的那个同时控制单次 API 成本和上下文长度。四、step() 与 retry()单步编译与自动重试编译的主循环是step()instruction_compiler.py#L341-L353从instructions_queue取出第一块指令塞进BASE_PROMPT的{instructions}插槽调用get_completion请求模型返回{instruction: 原始指令, action_output: 生成的代码}记入self.history。几个值得细看的工程细节API 缓存get_completion内置api_cache字典同样的提示词不会重复付费instruction_compiler.py#L269-L327还会自动剥离模型误写的import行限流容错捕获 OpenAI 的 RateLimit/API/Timeout 异常睡 5 秒后递归重试自动重试执行出错时retry(stack_trace_str)会把上次生成的代码 堆栈信息追加回提示词STACK_TRACE_SUFFIXRETRY_SUFFIX见 instruction_compiler.py#L22-L23让模型看着报错改代码。编译结果长什么样看官方缓存文件 buffalo_wikipedia.json自然语言与编译代码一一对应# 自然语言指令 # 编译产物Selenium 代码 Go to Google.com → env.get(https://www.google.com) Find all textareas. → text_boxes env.find_elements(byxpath, value//div[role textarea]|...) Click on the first visible… → env.click(visible_text_box) Type in buffalo… and press → env.send_keys(visible_text_box, buffalo …); env.send_keys(..., Keys.ENTER)五、从编译到执行GPTSeleniumAgent 如何落地代码编译只是上半场下半场在 gpt_selenium_agent.py1. 两种运行模式run()方法L390-L401如果 YAML/JSON 里已有compiled字段 → 直接执行缓存代码零 API 成本否则 →__step_through_instructions逐块编译执行并可通过instruction_output_file把编译结果存回文件下次免费复跑。2. 安全护栏_check_dangerL143-L168执行前检查代码是否含import是否引用shutil、requests、urllib等黑名单库发现即sys.exit退出。3. 执行与自愈__step_through_instructionsL333-L363exec(action, globals(), ldict) # ldict {env: self}env就是智能体自己所以生成的env.click(...)实际调用的是它的click方法。执行失败且开启retry时会把出错行 相关堆栈回传给编译器的retry()最多循环 3 次。4. 增强型元素操作find_elements会递归钻进每个 iframe找元素并过滤不可见元素包装成带iframe标记的GPTWebElement点击、输入等操作通过__switch_to_element_iframe装饰器自动切换/切回 iframeclick用ActionChains先移动再点并检测 URL 变化把新页面写入记忆。5. 可选的记忆系统传入memory_folder后智能体基于 Llama Index 建向量索引memories/init.py浏览过的页面文本都能被env.query_memory(...)追问——这就是提示词能力清单里Query memory的落地方式。六、写好指令的实用技巧新手避坑读完源码官方 README 给的提示词写作建议就更有出处了✅ 像写代码一样精确说textarea、input别说文本框✅ 关键动作拆行写find all the textareas 和 find the first visible textarea 分两行✅ 用BEGIN_FUNCTION/RUN_FUNCTION把可复用流程封装成函数✅ 用env.ask_llm_to_find_element(search textbox)这类描述性指令让 AI 从 HTML 里智能找元素参考 buffalo_wikipedia_ask_llm_to_find_element_example.yaml✅ 善用instruction_output_file缓存编译结果避免重复烧 API 费用。更复杂的场景可以翻看提示词库nytimes_headline_list.yaml抓头条AI 筛选政治新闻、nytimes_click_login.yaml、instagram.yaml、memory_summarization.yaml。七、动手跑起来pip install browserpilot下载 Chromedriver 并解压到工作目录配置环境变量OPENAI_API_KEY用命令行入口 examples.py 跑一个 YAMLpython examples.py selenium prompts/examples/buffalo_wikipedia.yaml --chromedriver_path ./chromedriver⚠️安全提醒BrowserPilot 通过exec执行 LLM 生成的代码官方 README 明确标注这不是安全惯例——请只在受信任的环境中使用并留意_check_danger的黑名单防护是有限的。小结BrowserPilot 的编译管线可以浓缩成一句话指令分块 → BASE_PROMPT 能力清单 约束 → LLM 生成带env.*调用的 Python 代码 → 危险检查后exec执行 → 失败则带堆栈重试。InstructionCompiler把自然语言 ↔ 代码的翻译问题简化成了给一个受限工具箱 一份严格说明书这是它既简单又稳定的根本原因。下一篇我们打算拆解Memory模块智能体是如何用向量索引记住自己浏览过的网页的。 参考文件instruction_compiler.py gpt_selenium_agent.py readme.md【免费下载链接】browserpilotNatural language browser automation项目地址: https://gitcode.com/gh_mirrors/br/browserpilot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考