DS-160 Auto-fill Skill
This skill automates the filling of US nonimmigrant visa DS-160 forms by combining:
- - CDP (Chrome DevTools Protocol) for fast element location
- CSV data source for user information
- LLM assistance for complex cases (captcha, missing elements)
- Session persistence for resume capability
- Chinese to English translation for user input
Quick Start
Starting a New Application
- 1. Provide CSV data: User must provide a CSV file with their personal information (use
ds160-user-info.csv as template)
- 2. Open DS-160 website: Use
browser tool to open https://ceac.state.gov/genniv/ with profile INLINECODE3
- 3. Initialize session: Load and execute
scripts/ds160-filler.js to parse mappings and CSV
- 4. Start filling: Begin with the home page, handle captcha with LLM, then proceed page by page
Resuming an Application
- 1. Load existing session: Check
ds160/ds160-session.json for saved Application ID
- 2. Open application: Use the saved Application ID to resume on DS-160 website
- 3. Continue filling: Load CSV from saved location and continue from last page
Core Workflow
Step 1: Prepare Data
Always check if session exists first:
CODEBLOCK0
New application mode:
- - Ask user for CSV file path or content
- Save CSV to
ds160/ds160-user-info.csv using write tool - Initialize session data in
ds160/ds160-session.json:
CODEBLOCK1
Resume mode:
- - Load CSV from INLINECODE9
- Load session from INLINECODE10
- Report current progress to user
Step 2: Initialize Browser
CODEBLOCK2
Step 3: Fill Current Page
For each page in sequence:
- 1. Snapshot page to understand current state:
CODEBLOCK3
- 2. Load mappings from INLINECODE11
- 3. Execute fill logic using
browser act with evaluate:
CODEBLOCK4
- 4. Handle results:
-
Success: Continue to next page
-
Needs LLM assistance: Call LLM and retry
-
Needs user input: Save progress and pause
Step 4: Handle Special Cases
Captcha:
- - Take screenshot of captcha area
- Use
image tool to analyze captcha - Fill captcha code via browser evaluate
Missing element:
- - Call LLM with page snapshot
- Ask LLM to locate element and provide alternative selector
- Retry fill operation
Translation needed:
- - Call LLM with field context and Chinese value
- Ask LLM to translate to appropriate English value
- Update CSV and retry fill operation
Missing user data:
- - Identify which field is missing
- Report to user with field name and description
- Important: Save current page using browser evaluate before pausing
- Wait for user to provide data
Step 5: Save Progress & Continue
After completing a page:
- 1. Update session data:
CODEBLOCK5
- 2. Save to file: INLINECODE14
- 3. Report progress to user:
- Current page completed
- Next page name
- Application ID
- Security question/answer (first time only)
- Overall progress (X/Y pages)
- 4. Click "Continue" button to proceed to next page
Data Structures
CSV Format
The CSV must have these columns:
- 1.
页面 - Page name - INLINECODE16 - Field identifier (matches YAML
name field) - INLINECODE18 - English description
- INLINECODE19 - Chinese description
- INLINECODE20 - Required? (是/否)
- INLINECODE21 - Example value
- INLINECODE22 - User-provided value (this is what gets filled)
Important: Users can provide values in Chinese. The script includes a built-in translation dictionary for common fields (gender, marital status, countries, etc.). For fields not in the dictionary, LLM will be called for translation automatically.
YAML Structure
Each page in ds160-elements.yaml contains:
- -
page_id: Unique page identifier - INLINECODE25 : Human-readable page name
- INLINECODE26 : Page URL pattern
- INLINECODE27 : Array of form elements with:
-
id: Element ID
-
name: Field identifier (matches CSV)
-
type: Element type (text, select, radio, checkbox, button)
-
label: English label
-
label_cn: Chinese label
-
required: Is required?
-
options: Available options (for select)
-
group: Radio group name
Error Handling
Element Not Found
Symptoms: fillPage returns INLINECODE37
Action:
- 1. Take page snapshot
- Call LLM with:
- Current URL
- Element information (id, name, type)
- Page HTML snippet
- Ask LLM to analyze and provide alternative selector
- 3. Retry with LLM-suggested selector
Translation Needed
Symptoms: fillPage returns INLINECODE39
Action:
- 1. Call LLM with translation context:
- Field name and description (EN/CN)
- Field type and available options
- Original Chinese value
- Ask LLM to translate to appropriate English value for the field
- 2. Update CSV with translated value
- Retry fill operation with translated value
Example LLM prompt for translation:
CODEBLOCK6
Data Missing
Symptoms: fillPage returns INLINECODE41
Action:
- 1. CRITICAL: Save current page before pausing:
// Find and click "Save" button
browser_act: {
request: { kind: "click", ref: "save_button" }
}
- 2. Report missing field to user:
- Field name (English and Chinese)
- Description
- Whether it's required
- 3. Update CSV with new data using
write tool - Resume filling
Captcha
Symptoms: Captcha image detected on page
Action:
- 1. Take screenshot of captcha area
- Use
image tool:
image: {
image: "/path/to/captcha.png",
prompt: "What is the code shown in this captcha? Return only the code characters."
}
- 3. Fill captcha field via browser evaluate
- Submit form
Page Sequence
The pages are filled in this order:
- 1. home - Start application, select location, handle captcha
- securityquestion - Confirm Application ID, set security question
- personal1 - Personal information (name, gender, DOB)
- personal2 - Nationality, other nationalities, IDs
- travel - Travel purpose, dates, who is paying
- travelcompanions - People traveling with you
- previousustravel - Previous US visits
- addressphone - Current address and phone
- passport - Passport information
- uscontact - US point of contact
- familyrelatives - Family information
- workeducation - Work and education history
- security_background - Security questions
Progress Reporting
Report to user after each page:
CODEBLOCK9
Include in every report:
- - Application ID (once obtained)
- Security question and answer (once generated)
- Current progress (X/Y pages)
- Next page name
LLM Integration
When to Call LLM
- 1. Captcha detection: Always use LLM to read captcha
- Element not found: When multiple locator strategies fail
- Translation needed: When user provides Chinese value not in built-in dictionary
- Complex elements: For elements that require understanding context
- Validation errors: When form submission fails with unclear reason
LLM Prompts
For element location:
CODEBLOCK10
For captcha:
CODEBLOCK11
Translation Dictionary
The script includes a built-in translation dictionary for common Chinese values. This covers:
Gender:
- - 男/男性 → MALE
- 女/女性 → FEMALE
Marital Status:
- - 已婚 → MARRIED
- 未婚 → SINGLE
- 离异 → DIVORCED
- 丧偶 → WIDOWED
- 合法分居 → LEGALLY SEPARATED
- 事实婚姻 → COMMON LAW MARRIAGE
- 民事结合 → CIVIL UNION/DOMESTIC PARTNERSHIP
Yes/No:
- - 是/有/是,有 → Yes
- 否/没有/否,没有 → No
Countries:
- - 中国 → CHINA
- 美国 → USA
- 英国 → UNITED KINGDOM
- 日本 → JAPAN
- 韩国 → KOREA, SOUTH
Visa Types:
- - 旅游/商务/商务/旅游 → B1/B2
- 学生 → F1
- 访问学者 → J1
- 工作 → H1B
Payment:
- - 自己/自费 → SELF
- 公司 → OTHER COMPANY
- 其他人 → OTHER PERSON
Relationship (US Point of Contact):
- - 朋友 → Friend
- 亲戚 → Relative
- 同事 → Colleague
- 配偶 → Spouse
- 同学 → Classmate
- 其他 → Other
Other Values:
- - 不适用/不,不适用 → Does Not Apply
For values not in this dictionary, LLM will be automatically called for translation.
Session Persistence
Session file location: INLINECODE44
Session data structure:
CODEBLOCK12
When to save session:
- - After completing each page
- Before pausing for user input
- After receiving Application ID
- After setting security question/answer
Browser Automation Notes
Always use openclaw profile to maintain session across pages.
Use browser act with evaluate for form filling:
- - More reliable than individual click/type actions
- Can execute complex JavaScript
- Better error handling
Use browser snapshot before each page:
- - Check page state
- Identify dynamic elements
- Verify page loaded correctly
Testing Checklist
Before using this skill with real data:
- - [ ] Test element location on each page type
- [ ] Verify CSV parsing with sample data
- [ ] Test captcha handling with LLM
- [ ] Verify session save/load functionality
- [ ] Test resume from middle of application
- [ ] Verify "Save" button clicking works before pauses
- [ ] Test with various element types (text, select, radio, checkbox)
- [ ] Verify progress reporting format
- [ ] Test Chinese to English translation
Example Usage
User says: "Help me fill DS-160 form with my data in this.csv"
Agent workflow:
- 1. Load SKILL.md (this file)
- Check for existing session
- Save CSV to ds160/ds160-user-info.csv
- Initialize session
- Open browser to DS-160
- Fill page by page
- Report progress after each page
- Handle errors with LLM or user input
- Save progress and continue
User says: "Continue filling my DS-160 form"
Agent workflow:
- 1. Load SKILL.md
- Load existing session
- Open browser to DS-160 with Application ID
- Load CSV from saved location
- Continue from last page
- Report progress
- Complete remaining pages
Files Reference
- - scripts/ds160-filler.js - Core automation logic (run via browser evaluate)
- references/ds160-elements.yaml - Element mappings (read-only)
- references/ds160-user-info.csv - User data template (copy to workspace)
- ds160/ds160-session.json - Session persistence (auto-created)
- ds160/ds160-user-info.csv - Active user data (auto-created)
Important Notes
- - NEVER submit the final form - this is for automation/testing only
- Always save before pausing - prevents data loss
- Report progress frequently - at least every page
- Keep Application ID secure - it's sensitive information
- Use fake data for testing - don't use real personal info
- Chinese input is supported - use built-in dictionary or LLM for translation
DS-160 自动填写技能
本技能通过结合以下技术,自动填写美国非移民签证DS-160表格:
- - CDP(Chrome DevTools协议)用于快速定位元素
- CSV数据源用于用户信息
- LLM辅助处理复杂情况(验证码、缺失元素)
- 会话持久化支持恢复功能
- 用户输入的中文到英文翻译
快速开始
开始新申请
- 1. 提供CSV数据:用户必须提供包含个人信息的CSV文件(使用ds160-user-info.csv作为模板)
- 2. 打开DS-160网站:使用browser工具,以openclaw配置文件打开https://ceac.state.gov/genniv/
- 3. 初始化会话:加载并执行scripts/ds160-filler.js以解析映射和CSV
- 4. 开始填写:从首页开始,用LLM处理验证码,然后逐页进行
恢复申请
- 1. 加载现有会话:检查ds160/ds160-session.json中保存的申请ID
- 2. 打开申请:使用保存的申请ID在DS-160网站上恢复
- 3. 继续填写:从保存的位置加载CSV,并从上一页继续
核心工作流程
步骤1:准备数据
始终先检查会话是否存在:
javascript
// 读取 ds160/ds160-session.json
// 如果存在 → 恢复模式
// 如果不存在 → 新申请模式
新申请模式:
- - 询问用户CSV文件路径或内容
- 使用write工具将CSV保存到ds160/ds160-user-info.csv
- 在ds160/ds160-session.json中初始化会话数据:
json
{
applicationId: null,
securityQuestion: null,
securityAnswer: null,
currentPageIndex: 0,
completedPages: [],
startDate: 2026-02-06T21:00:00Z
}
恢复模式:
- - 从ds160/ds160-user-info.csv加载CSV
- 从ds160/ds160-session.json加载会话
- 向用户报告当前进度
步骤2:初始化浏览器
javascript
// 使用openclaw配置文件打开浏览器
browser_start: { profile: openclaw, targetUrl: https://ceac.state.gov/genniv/ }
// 恢复模式时,将申请ID添加到URL
// 示例:https://ceac.state.gov/GenNIV/Common/ConfirmApplicationID.aspx
步骤3:填写当前页面
按顺序处理每个页面:
- 1. 快照页面以了解当前状态:
javascript
browser_snapshot: { refs: role, profile: openclaw }
- 2. 加载映射从references/ds160-elements.yaml
- 3. 执行填写逻辑,使用browser act配合evaluate:
javascript
// 加载 ds160-filler.js
// 调用 fillPage(page, currentUrl, userData, yamlData)
- 4. 处理结果:
-
成功:继续到下一页
-
需要LLM协助:调用LLM并重试
-
需要用户输入:保存进度并暂停
步骤4:处理特殊情况
验证码:
- - 截取验证码区域截图
- 使用image工具分析验证码
- 通过浏览器evaluate填写验证码
缺失元素:
- - 使用页面快照调用LLM
- 请求LLM定位元素并提供替代选择器
- 重试填写操作
需要翻译:
- - 使用字段上下文和中文值调用LLM
- 请求LLM翻译为适当的英文值
- 更新CSV并重试填写操作
用户数据缺失:
- - 识别缺失的字段
- 向用户报告字段名称和描述
- 重要:在暂停前使用浏览器evaluate保存当前页面
- 等待用户提供数据
步骤5:保存进度并继续
完成一个页面后:
- 1. 更新会话数据:
json
{
applicationId: AA00FBLCQP,
securityQuestion: What is the given name of your mothers mother?,
securityAnswer: LiMei,
currentPageIndex: 5,
completedPages: [home, security
question, personal1, personal_2],
startDate: 2026-02-06T21:00:00Z
}
- 2. 保存到文件:write(ds160/ds160-session.json, JSON.stringify(sessionData))
- 3. 向用户报告进度:
- 当前页面已完成
- 下一页名称
- 申请ID
- 安全问题/答案(仅首次)
- 总体进度(X/Y页)
- 4. 点击继续按钮以进入下一页
数据结构
CSV格式
CSV必须包含以下列:
- 1. 页面 - 页面名称
- 字段名称 - 字段标识符(匹配YAML中的name字段)
- 英文说明 - 英文描述
- 中文说明 - 中文描述
- 必填 - 是否必填(是/否)
- 示例值 - 示例值
- 用户填写 - 用户提供的值(这是实际填写的内容)
重要:用户可以提供中文值。脚本包含常用字段的内置翻译字典(性别、婚姻状况、国家等)。对于字典中没有的字段,将自动调用LLM进行翻译。
YAML结构
ds160-elements.yaml中的每个页面包含:
- - pageid:唯一页面标识符
- pagename:人类可读的页面名称
- url:页面URL模式
- elements:表单元素数组,包含:
- id:元素ID
- name:字段标识符(匹配CSV)
- type:元素类型(text、select、radio、checkbox、button)
- label:英文标签
- label_cn:中文标签
- required:是否必填
- options:可用选项(用于select)
- group:单选按钮组名称
错误处理
元素未找到
症状:fillPage返回needsLLM: true
操作:
- 1. 获取页面快照
- 调用LLM,提供:
- 当前URL
- 元素信息(id、name、type)
- 页面HTML片段
- 请求LLM分析并提供替代选择器
- 3. 使用LLM建议的选择器重试
需要翻译
症状:fillPage返回needsTranslation: true
操作:
- 1. 调用LLM,提供翻译上下文:
- 字段名称和描述(中/英文)
- 字段类型和可用选项
- 原始中文值
- 请求LLM翻译为适合该字段的英文值
- 2. 用翻译后的值更新CSV
- 使用翻译后的值重试填写操作
LLM翻译提示示例:
我需要将这个中文值翻译为DS-160表格字段的英文值:
字段:${elementName}
类型:${elementType}
英文标签:${label}
中文标签:${label_cn}
中文值:${originalValue}
可用选项(如果是选择框):${options}
请提供该字段的正确英文值。请考虑:
- - 字段类型和上下文
- 可用选项(如适用)
- 标准DS-160术语
只返回英文值,无需解释。
数据缺失
症状:fillPage返回needsUserInput: true
操作:
- 1. 关键:在暂停前保存当前页面:
javascript
// 查找并点击保存按钮
browser_act: {
request: { kind: click, ref: save_button }
}
- 2. 向用户报告缺失字段:
- 字段名称(英文和中文)
- 描述
- 是否必填
- 3. 使用write工具用新数据更新CSV
- 继续填写
验证码
症状:页面上检测到验证码图片
操作:
- 1. 截取验证码区域截图
- 使用image工具:
javascript
image: {
image: /path/to/captcha.png,
prompt: 这个验证码中显示的代码是什么?只返回代码字符。
}
- 3. 通过浏览器evaluate填写验证码字段
- 提交表单
页面顺序
按以下顺序填写页面:
- 1. home