æ°ãããã©ãŠã¶æäœç³»ãšãŒãžã§ã³ãã®workflow-useãããªãè¯ããããªäºæ
BrowserãUseããæ°ãããã©ãŠã¶æäœç³»ãšãŒãžã§ã³ããç»å ŽããŸãã
ãã¡ããã¡ãé
åçã ã£ãã®ã§ç޹ä»ããŸãã
åŸæ¥ã®ãã©ãŠã¶æäœç³»ãšãŒãžã§ã³ã
browser-useã«éãããåŸæ¥ã®ãã©ãŠã¶æäœç³»ãšãŒãžã§ã³ãã¯ãŠãŒã¶ãŒããã®èªç¶èšèªãªæä»€ãããšã«ãã©ãŠã¶ãæäœããŸãã
AIãšãŒãžã§ã³ãã¯ç»é¢ãã£ãã㣠+ DOMã®ååŸ â ãã£ããã£ãè§£æ â ã¯ãªãã¯ãã¹ãèŠçŽ ãæšè« â playwrightã§æäœãã«ãŒãããŠã¿ã¹ã¯ãè¡ããŸãã
çŸåšåããã䜿ã£ãŠããã®ã§ãããäœç¹ã課é¡ããããŸãã
ã©ãããŠãã¢ã¯ã·ã§ã³ã«æºããããã
èªç¶èšèªã§ã®æç€ºã§ãã以äžä»æ¹ãªãã®ã§ãããããããã¯ãªãã¯ããŠãããããŠã»ããããšèšã£ã现ããæç€ºã¯ããã³ããã®ãã¥ãŒãã³ã°ãäžå¯æ¬ ã§ãã䜿çšã¢ãã«ã®è³¢ãã«ãäŸåããŸãã
åŠçã«æéãããã
ç»é¢ãã£ãã㣠+ DOMã®ååŸ â ãã£ããã£ãè§£æ â ã¯ãªãã¯ãã¹ãèŠçŽ ãæšè« â playwrightã§æäœ...ãç¹°ãè¿ãã®ã§ã©ãããŠãåŠçã«æéãããã£ãŠããŸããŸãã
ããŒã«ã«ã®PCã§åãããšãã§ããã°ããã®ã§ãããVMãšãã«ãããã€ããŠéçšã«äœ¿ããšãªããšã¡ãã£ãšããã©ãã§ãã
workflow-use
æ°ããç»å Žããworkflow-useã¯äžèšã§æãããããªèª²é¡ã解決ããããšãã§ããŸãã
åŸæ¥ã®ãããªèªç¶èšèªã«ãããã©ãŠã¶ã®æäœã§ã¯ãªããäºããŠå®çŸ©ããworkflowã«æºããŠãã©ãŠã¶ãæäœããŸãã
å®çŸ©ããã¯ãŒã¯ãããŒã¯ãŠãŒã¶ãŒèªèº«ã§äºåã«å®çŸ©ãããŸãã
å®çŸ©ããããã®æ©èœãworkflow-useã®äžã«APIãšããŠåãã£ãŠãããã³ãã³ããå®è¡ããŠãAI Agentã«æäœããŠã»ããã¢ã¯ã·ã§ã³ããŠãŒã¶ãŒããææ¬ãšããŠå®è·µããŸãã
ãããã¬ã³ãŒãã£ã³ã°ããŠã¯ãŒã¯ãããŒãjson圢åŒã§åãåºããŠãããŸãã
ããã«å¯å€ããããªãšããïŒinputã¿ã°ãselectãã¿ã³ãªã©ïŒã¯å€æ°ãšããŠå€åºãããŠããããããAIã«ãã©ãŠã¶æäœãå®è¡ããŠããããšãã«æ¯å倿Žããããšãã§ããŸãã
ã¡ãªãã
- èªç¶èšèªã«ããæºãããçºçããªã
- ãããããæ±ºãããããããŒã«æ²¿ã£ãŠå®è¡ãããã®ã§ããŒã¯ã³æ¶è²»éãåŠçé床ãéåžžã«éã
- èªåã§ã¯ãŒã¯ãããŒãåŸããä¿®æ£ããããšãå¯èœ
- ãããŒã®1éšåã ãAI Agentã«æšè«ããŠå§ããã£ãŠããšãå¯èœ
ãã¡ãªãã
- ãã©ãŠã¶ã®ä»æ§ãUIã®å€æŽã«ãã£ãœã匱ã
- ããã±ãŒãžãšããŠæäŸãããŠãªã
䜿ãåã
äžèšå
容ããbrowser-useã®å®å
šäžäœäºæã£ãŠããã§ã¯ãªãããšãåãããšæããŸãã
ãã©ãŠã¶æäœãããŠãã£ãŠæ¬²ããã¿ã¹ã¯ã«ãã£ãŠäœ¿ãåããå¿
èŠã§ãã
browser-use
- äœã調ã¹ç©ãããŠæ¬²ãããšã
- ææ°ã®æ å ±ããšã£ãŠããŠæ¬²ãããšã
- å€å°ã¿ã¹ã¯æäœã«æºããããã£ãŠãåé¡ãªããšã
workflow-use
- APIãæäŸãããŠãªãã·ã¹ãã ïŒæ¥ååãã瀟å åãã·ã¹ãã ãªã©ïŒãAI Agentã§èªååããããšã
- ã¬ã¬ã·ãŒã·ã¹ãã ãªã©ã§UIã®å€æŽãæ» å€ã«çºçããªããšã
- AIã«äœæ¥ããŠæ¬²ããããšãã¯ãªãã¯ããŠæ¬²ãããã¿ã³ããµã€ããªã©ãäºã決ãŸã£ãŠãããšã
- AIã«ããæºãããæ¥µéãŸã§åé¿ããããšã
äœ¿ãæ¹
åæ
çŸç¶OpenAIãããµããŒãããŠãªãã®ã§ãã
èªåã¯Azure OpenAIã䜿ãã®ã§ã³ãŒãã®ä¿®æ£ãå¿
èŠã§ãã
1. ç°å¢æ§ç¯
以äžã®ãªããžããªã«ã¢ã¯ã»ã¹ããŠãgit clone
READMEã®éãã«ã³ãã³ããå®è¡
2. Azure OpenAI仿§ã«å€æŽ
ã䜿ãã®ãšãã£ã¿ã§ChatOpenAIã§å
šäœæ€çŽ¢ãããã

以äžã®ãããªæãã§ãChatOpenAIâAzureChatOpenAIã«å€ããŸãã
from langchain_openai import AzureChatOpenAI
from workflow_use.builder.service import BuilderService
from workflow_use.controller.service import WorkflowController
from workflow_use.recorder.service import RecordingService # Added import
from workflow_use.workflow.service import Workflow
# Placeholder for recorder functionality
# from src.recorder.service import RecorderService
app = typer.Typer(
name='workflow-cli',
help='A CLI tool to create and run workflows.',
add_completion=False,
no_args_is_help=True,
)
# Default LLM instance to None
llm_instance = None
try:
llm_instance = AzureChatOpenAI(
openai_api_version="2024-10-21",
azure_endpoint="<your azure openai endpoint>",
azure_deployment="gpt-4.1",
model="gpt-4.1",
validate_base_url=False,
api_key="<your aoai api key>"
)
ãã®ãŸãŸã ãšãšã©ãŒã«ãªã£ã¡ããã®ã§ããäžåä¿®æ£ãå¿
èŠã§ãã
workflow-use/workflow/service.pyã®ã³ãŒããäžéšæ¹ä¿®ããŸãã
async def _run_agent_step(self, step: AgenticWorkflowStep) -> AgentHistoryList | dict[str, Any]:
"""Spin-up an Agent based on step dictionary."""
if self.llm is None:
raise ValueError("An 'llm' instance must be supplied for agent-based steps")
task: str = step.task
max_steps: int = step.max_steps or 5
agent = Agent(
task=task,
llm=self.llm,
browser=self.browser,
browser_context=self.browser_context,
ãããããããã# ââ以äžã远å
tool_calling_method="function_calling",
use_vision=True, # Consider making this configurable via WorkflowStep schema
)
return await agent.run(max_steps=max_steps)
3. å®éã«è©Šã
ä»åã¯ãMicrosoftã®ææ°ã®ã€ãã³ãã«åºåžç»é²ããšããã¿ã¹ã¯ã§ãã£ãŠã¿ãŸãã
ãŸãã¯ã¯ãŒã¯ãããŒãäœæããŸãã
以äžã®ã³ãã³ããå®è¡
python cli.py create-workflow
ãããšããã©ã«ããã©ãŠã¶ã®ã·ãŒã¯ã¬ãããŠã£ã³ããŠãç«ã¡äžãããŸãã

ãªã³ã¯ãå
¥åããŠãç»é²ãã¿ã³ãã¯ãªãã¯ããŠæ°ããã¿ããç«ã¡äžããŠãæ
å ±ãå
¥åããŸãã




ç»é²ãã¿ã³ãæŒããŠãAIãšãŒãžã§ã³ãã«ãã£ãŠæ¬²ããã¿ã¹ã¯ãäžéãåçŸãããã¿ãŒããã«ã«æ»ã£ãŠctrl + cãã¯ãªãã¯ã
ãããšãã¯ãŒã¯ãããŒã®ç»é²ãããããã®è³ªåãããã€ãããã®ã§é©åœã«å
¥åã

以äžã®ãããªã¯ãŒã¯ãããŒãäœæãããŸããã
{
"workflow_analysis": "This workflow automates the registration process for a Microsoft Virtual Training Event. It begins by navigating to the event listing page, then locates and clicks on a specific event registration link, taking the user to the registration form. The workflow proceeds to fill out the registration form fields such as first name, last name, email, phone number, job title, company name, country, and company size, and finally submits the form. Key dynamic inputs are the user's first name, last name, email, phone number, job title, company name, country, and company size, which must be provided for the automation to be reusable and flexible. Agentic steps are not required, as the form fields use stable selectors and all form values are directly determined by user input. Placeholder navigation and interaction steps (like excessive key presses and navigation refreshes) are condensed into streamlined deterministic actions for efficiency. All relevant values should be parameterized to allow the workflow's reuse for different registrants.",
"name": "microsoft_virtual_training_event_registration",
"description": "Automates registration for a Microsoft Dynamics 365 Virtual Training Day on the official Microsoft events site.",
"version": "1.0",
"steps": [
{
"description": "Navigate to the Microsoft Japan event listing page.",
"output": null,
"timestamp": null,
"tabId": null,
"type": "navigation",
"url": "https://www.microsoft.com/ja-jp/events/top/training-days?activetab=a1%3aprimaryr3"
},
{
"description": "Click the registration link for the Microsoft Dynamics 365 Virtual Training Day event.",
"output": null,
"timestamp": null,
"tabId": null,
"type": "click",
"cssSelector": "a.cta[role*=\" \"][aria-label*=\"\u767b\u9332: 5 \u6708 26\u65e5\uff08\u6708\uff09\u30015 \u6708 27\u65e5\uff08\u706b\uff09...Microsoft Dynamics 365 Virtual Training Day: \u57fa\u790e(ERP)...\"]",
"xpath": "id(\"tableV2Row-uida79j7n\")/td[3]/div[1]/div[1]/a[1]",
"elementTag": "A",
"elementText": "\u767b\u9332"
},
{
"description": "Navigate to the specific event registration form.",
"output": null,
"timestamp": null,
"tabId": null,
"type": "navigation",
"url": "https://msevents.microsoft.com/event?id=1307512370"
},
{
"description": "Fill in the first name field.",
"output": null,
"timestamp": null,
"tabId": null,
"type": "input",
"cssSelector": "input.form-control[type=\"text\"][id=\"firstName\"]",
"value": "{first_name}",
"xpath": "id(\"firstName\")",
"elementTag": "INPUT"
},
{
"description": "Fill in the last name field.",
"output": null,
"timestamp": null,
"tabId": null,
"type": "input",
"cssSelector": "input.form-control[type=\"text\"][id=\"lastName\"]",
"value": "{last_name}",
"xpath": "id(\"lastName\")",
"elementTag": "INPUT"
},
{
"description": "Fill in the email field.",
"output": null,
"timestamp": null,
"tabId": null,
"type": "input",
"cssSelector": "input.form-control[type=\"email\"][id=\"email\"]",
"value": "{email}",
"xpath": "id(\"email\")",
"elementTag": "INPUT"
},
{
"description": "Fill in the phone number field.",
"output": null,
"timestamp": null,
"tabId": null,
"type": "input",
"cssSelector": "input.form-control[type=\"text\"][id=\"640735e1-9bbc-ea11-a812-000d3a321938\"]",
"value": "{phone}",
"xpath": "id(\"640735e1-9bbc-ea11-a812-000d3a321938\")",
"elementTag": "INPUT"
},
{
"description": "Fill in the job title field.",
"output": null,
"timestamp": null,
"tabId": null,
"type": "input",
"cssSelector": "input.form-control[type=\"text\"][id=\"d4ffb6df-1ef5-e911-a98d-000d3a30dc0a\"]",
"value": "{job_title}",
"xpath": "id(\"d4ffb6df-1ef5-e911-a98d-000d3a30dc0a\")",
"elementTag": "INPUT"
},
{
"description": "Fill in the company name field.",
"output": null,
"timestamp": null,
"tabId": null,
"type": "input",
"cssSelector": "input.form-control[type=\"text\"][id=\"46165aee-289a-ea11-a811-000d3a5cec97\"]",
"value": "{company_name}",
"xpath": "id(\"46165aee-289a-ea11-a811-000d3a5cec97\")",
"elementTag": "INPUT"
},
{
"description": "Select the country from the dropdown.",
"output": null,
"timestamp": null,
"tabId": null,
"type": "input",
"cssSelector": "select.form-select[id=\"6ccc2d02-2b9a-ea11-a811-000d3a5cec97\"][aria-label=\"Country\"]",
"value": "{country}",
"xpath": "id(\"6ccc2d02-2b9a-ea11-a811-000d3a5cec97\")",
"elementTag": "SELECT"
},
{
"description": "Choose the company size from the dropdown.",
"output": null,
"timestamp": null,
"tabId": null,
"type": "input",
"cssSelector": "select.form-select[id=\"b9f74f51-4664-ef11-a671-000d3a355617\"][aria-label*=\"What best describes the size of your organization?\"]",
"value": "{company_size}",
"xpath": "id(\"b9f74f51-4664-ef11-a671-000d3a355617\")",
"elementTag": "SELECT"
},
{
"description": "Click the submit button to complete registration.",
"output": null,
"timestamp": null,
"tabId": null,
"type": "click",
"cssSelector": "span",
"xpath": "id(\"submitbtn\")/span[1]",
"elementTag": "SPAN",
"elementText": "\u767b\u9332\u3059\u308b"
}
],
"input_schema": [
{
"name": "first_name",
"type": "string",
"required": true
},
{
"name": "last_name",
"type": "string",
"required": true
},
{
"name": "email",
"type": "string",
"required": true
},
{
"name": "phone",
"type": "string",
"required": true
},
{
"name": "job_title",
"type": "string",
"required": true
},
{
"name": "company_name",
"type": "string",
"required": true
},
{
"name": "country",
"type": "string",
"required": true
},
{
"name": "company_size",
"type": "string",
"required": true
}
]
}
åãããŠã¿ãŸãã
以äžã®ã³ãã³ããå®è¡
python cli.py run-workflow tmp/<your workflow>.workflow.json
ãããšãã©ãŒã ã«å
¥åããå€ã¯å€æ°ãšããŠèªèããŠãããŠããã®ã§ãŠãŒã¶ãŒã«å
¥åããå€ãä¿ããŠããŸãã

åç»ãã¢ããã§ããªããã§ãã»ãã®äžéšã«ãªã£ã¡ãããŸãããèªåã®æäœãšå
šãåãããã«åŠçããŠãããŸãã!

Discussion