From 6fdb8d03f292333d7e06bcfd5b1fa4649cf88354 Mon Sep 17 00:00:00 2001 From: Simon <10131203+gaomeng1900@users.noreply.github.com> Date: Mon, 9 Feb 2026 16:32:58 +0800 Subject: [PATCH] docs: trouble shooting --- packages/website/src/pages/docs/Layout.tsx | 4 + packages/website/src/pages/docs/index.tsx | 6 + .../introduction/troubleshooting/page.tsx | 429 ++++++++++++++++++ 3 files changed, 439 insertions(+) create mode 100644 packages/website/src/pages/docs/introduction/troubleshooting/page.tsx diff --git a/packages/website/src/pages/docs/Layout.tsx b/packages/website/src/pages/docs/Layout.tsx index 66e7720..8477ca1 100644 --- a/packages/website/src/pages/docs/Layout.tsx +++ b/packages/website/src/pages/docs/Layout.tsx @@ -30,6 +30,10 @@ export default function DocsLayout({ children }: DocsLayoutProps) { { title: isZh ? '概览' : 'Overview', path: '/introduction/overview' }, { title: isZh ? '快速开始' : 'Quick Start', path: '/introduction/quick-start' }, { title: isZh ? '使用限制' : 'Limitations', path: '/introduction/limitations' }, + { + title: isZh ? '故障排查' : 'Troubleshooting', + path: '/introduction/troubleshooting', + }, { title: '🚧 ' + (isZh ? '最佳实践' : 'Best Practices'), path: '/integration/best-practices', diff --git a/packages/website/src/pages/docs/index.tsx b/packages/website/src/pages/docs/index.tsx index bd8d768..359077b 100644 --- a/packages/website/src/pages/docs/index.tsx +++ b/packages/website/src/pages/docs/index.tsx @@ -20,6 +20,7 @@ import Limitations from './introduction/limitations/page' // Introduction import Overview from './introduction/overview/page' import QuickStart from './introduction/quick-start/page' +import Troubleshooting from './introduction/troubleshooting/page' function DocsPage({ children }: { children: React.ReactNode }) { return ( @@ -51,6 +52,11 @@ export default function DocsRouter() { + + + + + {/* Features */} diff --git a/packages/website/src/pages/docs/introduction/troubleshooting/page.tsx b/packages/website/src/pages/docs/introduction/troubleshooting/page.tsx new file mode 100644 index 0000000..55ddded --- /dev/null +++ b/packages/website/src/pages/docs/introduction/troubleshooting/page.tsx @@ -0,0 +1,429 @@ +import { useEffect, useRef, useState } from 'react' +import { Link } from 'wouter' + +import CodeEditor from '@/components/CodeEditor' +import { useLanguage } from '@/i18n/context' + +// --------------------------------------------------------------------------- +// Data: each section is a typed object for easy extension +// --------------------------------------------------------------------------- + +interface TroubleshootingSection { + id: string + title: { en: string; zh: string } + symptom: { en: string; zh: string } + color: 'red' | 'amber' | 'orange' | 'violet' + content: (isZh: boolean) => React.ReactNode +} + +const SECTIONS: TroubleshootingSection[] = [ + { + id: 'format-errors', + title: { en: 'Model Response Format Errors', zh: '模型返回格式错误' }, + symptom: { + en: 'The model returns malformed tool calls, plain text, or unexpected JSON instead of structured actions.', + zh: '模型返回了格式错误的 tool call、纯文本或非预期的 JSON,而非结构化的操作指令。', + }, + color: 'amber', + content: FormatErrorsContent, + }, + { + id: 'low-success-rate', + title: { en: 'Low Task Success Rate', zh: '任务成功率低' }, + symptom: { + en: 'The agent appears to understand the task but frequently fails to complete it, or produces incorrect results.', + zh: 'Agent 似乎理解了任务,但频繁执行失败或产生不正确的结果。', + }, + color: 'amber', + content: LowSuccessRateContent, + }, + { + id: 'wrong-element', + title: { en: "Can't Hit Target Elements", zh: '无法点击目标元素' }, + symptom: { + en: 'The agent repeatedly retries but keeps interacting with the wrong element, or fails to locate the correct one.', + zh: 'Agent 反复重试,但始终点击在错误的元素上,或无法定位到正确的目标元素。', + }, + color: 'amber', + content: WrongElementContent, + }, + { + id: 'api-errors', + title: { en: 'API Request Errors', zh: 'API 请求错误' }, + symptom: { + en: 'HTTP 400 Bad Request or similar errors when calling the LLM API.', + zh: '调用 LLM API 时出现 HTTP 400 Bad Request 或类似的参数错误。', + }, + color: 'amber', + content: ApiErrorsContent, + }, +] + +// --------------------------------------------------------------------------- +// Section content components +// --------------------------------------------------------------------------- + +function FormatErrorsContent(isZh: boolean) { + return ( +
    +
  1. + {isZh ? '确认模型是否支持' : 'Verify model compatibility'} +

    + {isZh + ? '并非所有模型都能正确处理 page-agent 的 tool 定义。请查看' + : 'Not all models can handle page-agent tool definitions correctly. Check the '} + + {isZh ? '已测试模型列表' : 'tested models list'} + + {isZh ? '。' : '.'} +

    +
  2. +
  3. + + {isZh ? '检查代理/网关的参数转发' : 'Check proxy/gateway parameter forwarding'} + +

    + {isZh + ? '如果使用了 API 代理或网关,请确保请求中的 ' + : 'If using an API proxy or gateway, make sure the '} + tools + {isZh + ? ' 字段被完整、无修改地转发给模型供应商。部分代理可能会剥离或修改此字段。' + : ' parameter is forwarded to the model provider intact. Some proxies may strip or alter this field.'} +

    +
  4. +
  5. + {isZh ? '寻求社区帮助' : 'Get community help'} +

    + {isZh ? ( + <> + 如果以上步骤无法解决问题,欢迎在{' '} + + GitHub Discussions + {' '} + 中反馈,附上模型名称和错误信息。 + + ) : ( + <> + If the above steps don't help, join the{' '} + + GitHub Discussions + {' '} + with your model name and error details. + + )} +

    +
  6. +
+ ) +} + +function LowSuccessRateContent(isZh: boolean) { + return ( + <> +

+ {isZh + ? '按以下顺序逐步排查,从最简单的情况开始:' + : 'Follow this diagnostic funnel from simplest to most advanced:'} +

+
    +
  1. + {isZh ? '先从简单指令开始' : 'Start with a simple instruction'} +

    + {isZh + ? '给一个具体的、单步的简单指令(如"点击登录按钮"),看 Agent 能否完成。如果连简单操作都失败了,问题可能不在模型能力上。' + : 'Give a concrete, single-step instruction (e.g. "click the login button"). If even simple actions fail, the issue is likely not model capability.'} +

    +
  2. +
  3. + {isZh ? '尝试最强模型' : 'Try the strongest model available'} +

    + {isZh + ? '切换到你能获取到的最先进、最大的模型,以排除是否是模型智能水平不足导致的问题。' + : "Switch to the most capable model you have access to, to isolate whether it's a model intelligence issue."} +

    +
  4. +
  5. + {isZh ? '优化指令质量' : 'Improve instruction quality'} +

    + {isZh + ? '给出尽可能具体的指令。对于复杂任务,建议使用另一个 LLM 来预先拆分和细化用户的需求,然后逐步执行。' + : "Be as specific as possible. For complex tasks, consider using another LLM to decompose and refine the user's request before execution."} +

    +
  6. +
  7. + {isZh ? '提供充足的上下文' : 'Provide sufficient context'} +

    + {isZh + ? '通过 instructions 配置注入网站背景描述、关键术语解释等上下文信息,帮助 Agent 更好地理解页面。' + : 'Use the instructions config to inject website descriptions, key terminology, and background context to help the agent understand the page.'} +

    +
  8. +
  9. + {isZh ? '检查 HTML 清洗结果' : 'Check HTML sanitization output'} +

    + {isZh + ? '使用开发者工具检查清洗后的 HTML,确认关键信息、文本和可操作元素是否被正确保留。' + : 'Inspect the sanitized HTML in dev tools to confirm that key information, text, and interactive elements are preserved correctly.'} +

    +
  10. +
+ + ) +} + +function WrongElementContent(isZh: boolean) { + return ( +
    +
  1. + {isZh ? '了解现实局限' : 'Understand the reality'} +

    + {isZh + ? '并非所有网站都提供了完善的语义化 HTML 和 accessibility 标签。对于此类网站,DOM 清洗可能无法产出足够好的结果。' + : 'Not all websites provide proper semantic HTML and accessibility labels. For such sites, DOM sanitization may not produce good enough results.'} +

    +
  2. +
  3. + {isZh ? '检查目标元素类型' : 'Check target element type'} +

    + {isZh + ? '确认目标元素是否为图片、Canvas、或需要复杂交互(如拖拽、基于坐标的点击)的元素。这些本身就超出了当前的能力范围。' + : 'Verify if the target is an image, Canvas, or requires complex interactions (drag-and-drop, coordinate-based clicking). These are beyond current capabilities.'} +

    +
  4. +
  5. + {isZh ? '检查清洗后的 HTML' : 'Inspect sanitized HTML'} +

    + {isZh + ? '检查清洗结果中是否存在关键信息丢失、可操作元素未被编号等问题。' + : 'Look for missing key information or unnumbered interactive elements in the sanitized output.'} +

    +
  6. +
  7. + {isZh ? '注入 accessibility 增强' : 'Inject accessibility improvements'} +

    + {isZh + ? '通过注入脚本为网站添加 aria-label、语义化标签等 accessibility 属性,改善 DOM 清洗质量。' + : 'Inject scripts to add aria-labels, semantic attributes, and other a11y improvements to enhance DOM sanitization quality.'} +

    +
  8. +
  9. + {isZh ? '开发专用 Tool' : 'Build a custom Tool'} +

    + {isZh ? ( + <> + 对于特定的、持续难以操作的元素,考虑开发{' '} + + 自定义 Tool + {' '} + 来直接操作这些元素。 + + ) : ( + <> + For consistently difficult elements, consider building a{' '} + + custom Tool + {' '} + to interact with them directly. + + )} +

    +
  10. +
+ ) +} + +function ApiErrorsContent(isZh: boolean) { + return ( +
+

+ {isZh + ? '一些 LLM 供应商使用了与 OpenAI 不完全兼容的参数格式,导致请求参数校验失败。' + : 'Some LLM providers use parameter formats that are not fully compatible with the OpenAI spec, causing request validation failures.'} +

+
+

+ {isZh ? '解决方案:使用 customFetch' : 'Solution: use customFetch'} +

+

+ {isZh + ? '通过 customFetch 配置拦截请求,在发送前调整参数格式以适配目标供应商的要求。' + : 'Use the customFetch config to intercept requests and adapt parameters before sending them to the target provider.'} +

+ { + const body = JSON.parse(init.body) + // Adapt parameters for your provider + delete body.stream_options + return fetch(url, { ...init, body: JSON.stringify(body) }) + }, +})`} + /> +
+

+ {isZh ? '参见 ' : 'See '} + + PageAgentCore API + + {isZh ? ' 了解 customFetch 的完整用法。' : ' for full customFetch documentation.'} +

+
+ ) +} + +// --------------------------------------------------------------------------- +// Color mapping for symptom callouts +// --------------------------------------------------------------------------- + +const SYMPTOM_COLORS = { + red: 'border-red-400 bg-red-50 dark:bg-red-900/15 text-red-800 dark:text-red-200', + amber: 'border-amber-400 bg-amber-50 dark:bg-amber-900/15 text-amber-800 dark:text-amber-200', + orange: + 'border-orange-400 bg-orange-50 dark:bg-orange-900/15 text-orange-800 dark:text-orange-200', + violet: + 'border-violet-400 bg-violet-50 dark:bg-violet-900/15 text-violet-800 dark:text-violet-200', +} as const + +// --------------------------------------------------------------------------- +// Right-side TOC with IntersectionObserver +// --------------------------------------------------------------------------- + +function useActiveSection(ids: string[]) { + const [activeId, setActiveId] = useState(ids[0]) + const observerRef = useRef(null) + + useEffect(() => { + observerRef.current?.disconnect() + + const visibleEntries = new Map() + + observerRef.current = new IntersectionObserver( + (entries) => { + for (const entry of entries) { + if (entry.isIntersecting) { + visibleEntries.set(entry.target.id, entry.intersectionRatio) + } else { + visibleEntries.delete(entry.target.id) + } + } + // Pick the first visible section in document order + const firstVisible = ids.find((id) => visibleEntries.has(id)) + if (firstVisible) setActiveId(firstVisible) + }, + { rootMargin: '-80px 0px -60% 0px', threshold: [0, 0.25] } + ) + + for (const id of ids) { + const el = document.getElementById(id) + if (el) observerRef.current.observe(el) + } + + return () => observerRef.current?.disconnect() + }, [ids]) + + return activeId +} + +// --------------------------------------------------------------------------- +// Page component +// --------------------------------------------------------------------------- + +export default function TroubleshootingPage() { + const { isZh } = useLanguage() + const sectionIds = SECTIONS.map((s) => s.id) + const activeId = useActiveSection(sectionIds) + + return ( +
+ {/* Header */} +
+

Troubleshooting

+ {/*

+ {isZh + ? '遇到问题了?按症状查找解决方案。' + : 'Running into issues? Find solutions by symptom.'} +

*/} +
+ + {/* Two-column: content + TOC */} +
+ {/* Main content */} +
+ {SECTIONS.map((section) => ( +
+

+ {isZh ? section.title.zh : section.title.en} +

+ + {/* Symptom callout */} +
+ + {isZh ? '症状' : 'Symptom'} + +

{isZh ? section.symptom.zh : section.symptom.en}

+
+ + {/* Diagnostic steps */} +
{section.content(isZh)}
+
+ ))} +
+ + {/* Right TOC */} + +
+
+ ) +}