<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      12-factor-agents

      https://github.com/humanlayer/12-factor-agents

      傳統agent的困境:

      這種方法的問題在于:

      • 控制流不可預測:完全依賴LLM決策
      • 錯誤處理困難:缺乏結構化的異常處理
      • 狀態管理混亂:執行狀態與業務狀態混合
      • 可觀測性差:難以調試和監控

      真正優秀的Agent不是"給LLM一堆工具讓它自由發揮",而是大部分由確定性代碼構成,在關鍵決策點巧妙地融入LLM能力。

      那么Agent到底是什么?

      • 提示- 告訴 LLM 如何操作,以及它有哪些可用的“工具”。提示的輸出是一個 JSON 對象,它描述了工作流程的下一步(“工具調用”或“函數調用”)。
      • switch 語句- 根據 LLM 返回的 JSON,決定如何處理它。
      • 累積上下文- 存儲已發生的步驟及其結果的列表。
      • for 循環- 直到 LLM 發出某種“終端”工具調用(或純文本響應),將 switch 語句的結果添加到上下文窗口并要求 LLM 選擇下一步。

      1 Natural Language to Tool Calls

      **原則**:將自然語言輸入轉換為結構化的工具調用,而非直接文本輸出。

      // ? 錯誤方式 - 依賴文本解析
      const response = await llm.complete("幫我發送郵件給張三")
      // 需要解析:"我將為您發送郵件..."
      
      // ? 正確方式 - 結構化輸出
      const toolCall = await llm.generateToolCall(prompt, tools)
      // 返回:{ tool: "send_email", params: { to: "張三", ... } }
      

      2 Own your prompts

      **原則**:將提示詞作為代碼資產管理,而非隱藏在框架中。
      • 提示詞應該版本化管理
      • 支持A/B測試和灰度發布
      • 提供清晰的提示詞模板系統

      一些框架提供了類似這樣的“黑箱”方法:

      agent = Agent(
        role="...",
        goal="...",
        personality="...",
        tools=[tool1, tool2, tool3]
      )
      
      task = Task(
        instructions="...",
        expected_output=OutputModel
      )
      
      result = agent.run(task)
      

      這非常適合引入一些頂級的提示詞工程來幫助你開始,但通常很難調整和/或逆向工程以將完全正確的標記輸入到你的模型中。相反,你應該擁有自己的提示詞,并將它們視為一級代碼:

      function DetermineNextStep(thread: string) -> DoneForNow | ListGitTags | DeployBackend | DeployFrontend | RequestMoreInformation {
        prompt #"
          {{ _.role("system") }}
          
          You are a helpful assistant that manages deployments for frontend and backend systems.
          You work diligently to ensure safe and successful deployments by following best practices
          and proper deployment procedures.
          
          Before deploying any system, you should check:
          - The deployment environment (staging vs production)
          - The correct tag/version to deploy
          - The current system status
          
          You can use tools like deploy_backend, deploy_frontend, and check_deployment_status
          to manage deployments. For sensitive deployments, use request_approval to get
          human verification.
          
          Always think about what to do first, like:
          - Check current deployment status
          - Verify the deployment tag exists
          - Request approval if needed
          - Deploy to staging before production
          - Monitor deployment progress
          
          {{ _.role("user") }}
      
          {{ thread }}
          
          What should the next step be?
        "#
      }
      

      (上述示例使用了 BAML 來生成提示詞,但你可以使用任何你想要的提示詞工程工具,甚至可以手動進行模板化)

      function DetermineNextStep(thread: string) -> DoneForNow | ListGitTags | DeployBackend | DeployFrontend | RequestMoreInformation {
      

      擁有自己的提示詞的主要好處:

      完全控制:精確編寫你的代理所需的指令,無需依賴黑箱式的抽象層。

      測試與評估:像對待其他代碼一樣,為你的提示詞構建測試和評估。

      迭代:根據實際表現快速修改提示詞。

      透明度:確切了解你的代理正在使用的指令。

      角色黑客:利用支持用戶/助手角色非標準使用的API——例如,現已廢棄的OpenAI“補全”API的非聊天版本。

      這包括一些所謂的“模型誤導”技巧。記?。耗愕奶崾驹~是你的應用程序邏輯與大型語言模型(LLM)之間的主要接口。

      3 Own your context window

      **原則**:主動管理上下文內容,而非被動累積。

      一切都與上下文工程有關。LLM是無狀態函數,它將輸入轉化為輸出。為了獲得最佳輸出,你需要為它們提供最佳輸入。

      創造良好的環境意味著:

      • 你給模特的提示和指示
      • 您檢索的任何文檔或外部數據(例如 RAG)
      • 任何過去的狀態、工具調用、結果或其他歷史記錄
      • 任何來自相關但獨立的歷史/對話的過去信息或事件(記憶)
      • 關于輸出什么類型的結構化數據的說明

      關于上下文工程本指南旨在盡可能多地從當前的模型中獲取價值。值得注意的是,以下內容并未提及:

      ? 對模型參數的調整,例如溫度(temperature)、top_p、頻率懲罰(frequency_penalty)、存在懲罰(presence_penalty)等。

      ? 訓練你自己的補全或嵌入模型。

      ? 對現有模型進行微調。

      再次強調,我不知道將上下文傳遞給 LLM 的最佳方法是什么,但我知道你希望擁有足夠的靈活性來嘗試一切。

      xml格式:

      擁有上下文窗口的主要好處:

      1. 信息密度:以最大化 LLM 理解的方式構建信息
      2. 錯誤處理:以有助于 LLM 恢復的格式包含錯誤信息??紤]在錯誤和失敗的調用解決后將其從上下文窗口中隱藏。
      3. 安全性:控制傳遞給 LLM 的信息,過濾掉敏感數據
      4. 靈活性:根據你的使用情況調整格式
      5. 令牌效率:優化上下文格式以提高令牌效率和 LLM 理解

      上下文包括:Prompt、說明、RAG 文檔、歷史記錄、工具調用、記憶

      4 Tools are just structured outputs

      **原則**:將工具調用視為結構化數據生成,而非函數執行。

      工具不需要復雜。在本質上,它們只是從你的大型語言模型(LLM)中產生的結構化輸出,這些輸出觸發確定性的代碼。

      工具定義應該:

      • 明確輸入輸出schema
      • 提供詳細的描述和示例
      • 支持參數驗證

      例如,假設你有兩個工具:CreateIssue(創建問題)和SearchIssues(搜索問題)。要讓一個大型語言模型(LLM)“使用多個工具中的一個”,實際上就是要求它輸出我們可以解析為表示這些工具的對象的JSON格式數據。

      
      class Issue:
        title: str
        description: str
        team_id: str
        assignee_id: str
      
      class CreateIssue:
        intent: "create_issue"
        issue: Issue
      
      class SearchIssues:
        intent: "search_issues"
        query: str
        what_youre_looking_for: str
      

      這個模式很簡單:

      1. LLM 輸出結構化的 JSON:

      ? LLM 生成一個結構化的 JSON 輸出,這個 JSON 表示了需要執行的操作或調用的工具。

      1. 確定性的代碼執行適當的動作:

      ? 你的代碼解析這個 JSON 輸出,并根據其內容執行相應的操作,例如調用外部 API。

      1. 捕獲結果并反饋到上下文中:

      ? 執行操作的結果被捕獲并反饋到上下文中,以便 LLM 在后續的決策中可以使用這些結果。這種模式在 LLM 的決策和應用程序的動作之間創建了一個清晰的分離。

      LLM 決定要做什么,但你的代碼控制如何去做。僅僅因為 LLM“調用了一個工具”,并不意味著你每次都要以相同的方式執行一個特定的對應函數。

      if nextStep.intent == 'create_payment_link':
          stripe.paymentlinks.create(nextStep.parameters)
          return # or whatever you want, see below
      elif nextStep.intent == 'wait_for_a_while': 
          # do something monadic idk
      else: #... the model didn't call a tool we know about
          # do something else
      

      注:關于“純文本提示”與“工具調用”以及“JSON 模式”的優勢,以及各自的性能權衡,已經有很多討論了。我們很快會鏈接一些相關資源,但在這里不會深入探討。請參考以下內容:《Prompting vs JSON Mode vs Function Calling vs Constrained Generation vs SAP》,《When should I use function calling, structured outputs, or JSON mode?》,以及《OpenAI JSON vs Function Calling》?!跋乱徊健笨赡懿⒉幌瘛斑\行一個純函數并返回結果”那么簡單。當你把“工具調用”看作是模型輸出 JSON 來描述確定性代碼應該執行什么操作時,你就能獲得很大的靈活性。將這一點與第 8 個因素——掌控你的流程——結合起來。

      5 Unify execution state and business state

      **原則**:將Agent的執行狀態與業務邏輯狀態統一管理。

      即使在人工智能領域之外,許多基礎設施系統也試圖將“執行狀態”與“業務狀態”分離開來。對于人工智能應用程序來說,這可能涉及到復雜的抽象概念,用以跟蹤諸如當前步驟、下一步驟、等待狀態、重試次數等事項。這種分離可能會帶來值得的復雜性,但對于你的使用場景來說,可能過于復雜了。

      和往常一樣,由你來決定什么最適合你的應用程序。但不要認為你必須將它們分開管理。

      更明確地說:

      ? 執行狀態:當前步驟、下一步驟、等待狀態、重試次數等。

      ? 業務狀態:到目前為止在代理工作流程中發生的事情(例如,OpenAI 消息列表、工具調用和結果列表等)。

      如果可能的話,盡量簡化——盡可能地將這些內容統一起來。

      實際上,你可以設計你的應用程序,以便能夠從上下文窗口中推斷出所有的執行狀態。在許多情況下,執行狀態(當前步驟、等待狀態等)只是關于到目前為止發生了什么的元數據。

      你可能有一些東西不能放入上下文窗口,比如會話ID、密碼上下文等,但你的目標應該是盡量減少這些內容。通過擁抱第3個因素,你可以控制實際進入LLM的內容。

      這種方法有多個好處:

      ? 簡單性:所有狀態都有一個單一的真相來源。

      ? 序列化:線程可以輕松地進行序列化和反序列化。

      ? 調試:整個歷史記錄可以在一個地方看到。

      ? 靈活性:通過簡單地添加新的事件類型,可以輕松添加新的狀態。

      ? 恢復:只需加載線程,就可以從任何點恢復。

      ? 分支:可以通過將線程的某個子集復制到新的上下文/狀態ID中,在任何點對線程進行分支。

      ? 人類接口和可觀察性:將線程轉換為人類可讀的Markdown或豐富的Web應用程序UI非常簡單。

      6 Launch/Pause/Resume

      **原則**:支持長時間運行任務的暫停和恢復。

      代理只是程序,我們對如何啟動、查詢、恢復和停止它們有相應的預期。

      應該有一個簡單的 API,方便用戶、應用程序、管道以及其他代理來啟動一個代理。當需要執行長時間運行的操作時,代理及其協調確定性代碼應該能夠暫停代理。像網絡鉤子(webhooks)這樣的外部觸發器應該能夠讓代理從它們停止的地方恢復執行,而無需與代理協調器進行深度集成。

      7 Contact Humans with Tool Calls

      **原則**:人機交互也應該通過結構化的工具調用實現。

      默認情況下,大型語言模型(LLM)的API依賴于一個基本的、高風險的令牌選擇:我們是返回純文本內容,還是返回結構化數據?

      你在這個第一個標記的選擇上賦予了很大的權重,在the weather in tokyo這個例子中,它是

      “the”

      但在 fetch_weather 這個例子中,它是一些特殊的標記,用來表示一個 JSON 對象的開始。

      |JSON>

      你可能會通過讓 LLM 總是輸出 json,并用一些自然語言標記(如 request_human_input 或 done_for_now)來表明它的意圖(而不是一個“正式”的工具,如 check_weather_in_city),從而獲得更好的結果。

      同樣,你可能不會從這當中獲得任何性能提升,但你應該進行實驗,并確保你可以自由地嘗試一些奇怪的東西以獲得最佳結果。

      
      class Options:
        urgency: Literal["low", "medium", "high"]
        format: Literal["free_text", "yes_no", "multiple_choice"]
        choices: List[str]
      
      # Tool definition for human interaction
      class RequestHumanInput:
        intent: "request_human_input"
        question: str
        context: str
        options: Options
      
      # Example usage in the agent loop
      if nextStep.intent == 'request_human_input':
        thread.events.append({
          type: 'human_input_requested',
          data: nextStep
        })
        thread_id = await save_state(thread)
        await notify_human(nextStep, thread_id)
        return # Break loop and wait for response to come back with thread ID
      else:
        # ... other cases
      

      稍后,你可能會從處理 Slack、電子郵件、短信或其他事件的系統中收到一個網絡鉤子(webhook)。

      
      @app.post('/webhook')
      def webhook(req: Request):
        thread_id = req.body.threadId
        thread = await load_state(thread_id)
        thread.events.push({
          type: 'response_from_human',
          data: req.body
        })
        # ... simplified for brevity, you likely don't want to block the web worker here
        next_step = await determine_next_step(thread_to_prompt(thread))
        thread.events.append(next_step)
        result = await handle_next_step(thread, next_step)
        # todo - loop or break or whatever you want
      
        return {"status": "ok"}
      

      上述內容包含了第 5 個因素、第 8 個因素、第 3 個因素以及第 4 個因素,還有其他幾個因素的模式。

      如果我們使用第 3 個因素中的 XML 格式——掌控你的上下文窗口,那么在經過幾次交互后,我們的上下文窗口可能看起來像這樣:

      
      (snipped for brevity)
      
      <slack_message>
          From: @alex
          Channel: #deployments
          Text: Can you deploy backend v1.2.3 to production?
          Thread: []
      </slack_message>
      
      <request_human_input>
          intent: "request_human_input"
          question: "Would you like to proceed with deploying v1.2.3 to production?"
          context: "This is a production deployment that will affect live users."
          options: {
              urgency: "high"
              format: "yes_no"
          }
      </request_human_input>
      
      <human_response>
          response: "yes please proceed"
          approved: true
          timestamp: "2024-03-15T10:30:00Z"
          user: "alex@company.com"
      </human_response>
      
      <deploy_backend>
          intent: "deploy_backend"
          tag: "v1.2.3"
          environment: "production"
      </deploy_backend>
      
      <deploy_backend_result>
          status: "success"
          message: "Deployment v1.2.3 to production completed successfully."
          timestamp: "2024-03-15T10:30:00Z"
      </deploy_backend_result>
      

      好處:

      ? 明確的指令:不同類型的人員接觸工具允許 LLM 提供更具體的指令。

      ? 內部循環與外部循環:使代理工作流能夠脫離傳統的類似 ChatGPT 風格的界面,在這種界面中,控制流程和上下文初始化可能是代理->人類,而不是人類->代理(想想那些由定時任務或事件觸發的代理)。

      ? 多人訪問:能夠輕松地跟蹤和協調來自不同人類的輸入,通過結構化事件進行協調。

      ? 多代理:簡單的抽象可以輕松擴展以支持代理->代理的請求和響應。

      ? 持久性:結合第 6 個因素——使用簡單 API 啟動/暫停/恢復,這使得多人工作流變得持久、可靠且可內省。

      8 Own Your Control Flow

      **原則**:不要讓LLM完全控制程序流程,而是在預定義的流程中讓LLM做決策。

      做選擇題,而不是做生成題。

      構建適合你特定用例的自定義控制結構。具體來說,某些類型的工具調用可能是退出循環并等待來自人類或另一個長時間運行的任務(如訓練管道)的響應的原因。你可能還想結合自定義實現:

      ? 工具調用結果的總結或緩存

      ? 結構化輸出的 LLM 作為評判

      ? 上下文窗口壓縮或其他內存管理

      ? 日志記錄、跟蹤和指標

      ? 客戶端速率限制

      ? 持久化睡眠/暫停/“等待事件”

      下面的例子展示了三種可能的控制流模式:

      ? request_clarification:模型請求更多信息,退出循環并等待人類的響應。

      ? fetch_git_tags:模型請求一個 git 標簽列表,獲取標簽,追加到上下文窗口中,并直接傳遞回模型。

      ? deploy_backend:模型請求部署后端,這是一個高風險的操作,因此退出循環并等待人類批準。

      def handle_next_step(thread: Thread):
      
        while True:
          next_step = await determine_next_step(thread_to_prompt(thread))
          
          # inlined for clarity - in reality you could put 
          # this in a method, use exceptions for control flow, or whatever you want
          if next_step.intent == 'request_clarification':
            thread.events.append({
              type: 'request_clarification',
                data: nextStep,
              })
      
            await send_message_to_human(next_step)
            await db.save_thread(thread)
            # async step - break the loop, we'll get a webhook later
            break
          elif next_step.intent == 'fetch_open_issues':
            thread.events.append({
              type: 'fetch_open_issues',
              data: next_step,
            })
      
            issues = await linear_client.issues()
      
            thread.events.append({
              type: 'fetch_open_issues_result',
              data: issues,
            })
            # sync step - pass the new context to the LLM to determine the NEXT next step
            continue
          elif next_step.intent == 'create_issue':
            thread.events.append({
              type: 'create_issue',
              data: next_step,
            })
      
            await request_human_approval(next_step)
            await db.save_thread(thread)
            # async step - break the loop, we'll get a webhook later
            break
      

      這種模式允許你根據需要中斷和恢復代理的流程,從而創造出更自然的對話和工作流程。

      舉例來說——我對每一個AI框架提出的首要功能需求是,我們需要能夠中斷一個正在工作的代理,并在之后恢復工作,尤其是在選擇工具的時刻和調用工具的時刻之間。

      如果沒有這種可恢復性/粒度,就無法在工具調用運行之前進行審查/批準,這意味著你只能被迫選擇以下幾種方式之一:

      ? 在等待長時間運行的任務完成時將任務暫停在內存中(想想while...sleep),如果進程被中斷,就從頭開始重新啟動;

      ? 限制代理僅能進行低風險、低風險的調用,比如研究和總結;

      ? 給代理提供執行更大、更有用任務的權限,然后只能聽天由命,希望它不會搞砸。

      9 Compact Errors

      **原則**:錯誤信息應該結構化并適合上下文窗口。

      這點比較短,但值得一提。agent的優點之一是“自我修復”——對于短任務,LLM 可能會調用失敗的工具。優秀的 LLM 能夠很好地讀取錯誤消息或堆棧跟蹤,并確定在后續工具調用中需要更改的內容。

      好處:

      1. 自我修復:LLM 可以讀取錯誤消息并找出在后續工具調用中需要更改的內容
      2. 持久:即使一個工具調用失敗,代理仍可繼續運行

      我確信你會發現,如果你這樣做太多次,你的agent就會開始失控,并可能一遍又一遍地重復同樣的錯誤。所以需要第10步。

      thread = {"events": [initial_message]}
      
      while True:
        next_step = await determine_next_step(thread_to_prompt(thread))
        thread["events"].append({
          "type": next_step.intent,
          "data": next_step,
        })
        try:
          result = await handle_next_step(thread, next_step) # our switch statement
        except Exception as e:
          # if we get an error, we can add it to the context window and try again
          thread["events"].append({
            "type": 'error',
            "data": format_error(e),
          })
          # loop, or do whatever else here to try to recover
      

      你可能希望為特定的工具調用實現一個錯誤計數器(errorCounter),以限制對單一工具的嘗試次數,比如大約3次,或者其他任何適用于你使用場景的邏輯。

      consecutive_errors = 0
      
      while True:
      
        # ... existing code ...
      
        try:
          result = await handle_next_step(thread, next_step)
          thread["events"].append({
            "type": next_step.intent + '_result',
            data: result,
          })
          # success! reset the error counter
          consecutive_errors = 0
        except Exception as e:
          consecutive_errors += 1
          if consecutive_errors < 3:
            # do the loop and try again
            thread["events"].append({
              "type": 'error',
              "data": format_error(e),
            })
          else:
            # break the loop, reset parts of the context window, escalate to a human, or whatever else you want to do
            break
        }
      }
      

      10 Small, Focused Agents

      **原則**:構建多個專門化的小Agent,而非一個萬能大Agent。

      不要構建試圖包攬一切的龐大代理,而應構建小巧、專注的代理,使其擅長做好一件事。代理只是更大、主要由確定性代碼構成的系統中的一個構建模塊。

      這里的關鍵洞察是關于大型語言模型(LLM)的局限性:

      任務越大越復雜,所需的步驟就越多,這意味著上下文窗口會更長。隨著上下文的增長,LLM 更容易迷失方向或失去焦點。通過讓代理專注于特定領域,步驟數保持在3到10步,最多20步,我們可以使上下文窗口保持在可管理的范圍內,同時保持 LLM 的高性能。

      隨著上下文的增長,LLM 更容易迷失方向或失去焦點。構建小巧、專注的代理的好處包括:

      ? 可管理的上下文:較小的上下文窗口意味著更好的 LLM 性能。

      ? 明確的職責:每個代理都有明確的范圍和目的。

      ? 更高的可靠性:在復雜的工作流程中迷失方向的可能性更小。

      ? 更簡單的測試:更容易測試和驗證特定的功能。

      ? 更有效的調試:當問題出現時,更容易識別和修復問題。

      如果 LLM 變得更聰明呢?

      如果 LLM 足夠聰明,能夠處理 100 步以上的工作流程,我們還需要這樣做嗎?

      簡而言之,答案是肯定的。隨著代理和 LLM 的改進,它們可能會自然地擴展到能夠處理更長的上下文窗口。這意味著能夠處理更大有向無環圖(DAG)的更多部分。這種小巧、專注的方法確保你今天就能取得成果,同時也為你逐步擴大代理范圍做好了準備,因為 LLM 的上下文窗口變得更加可靠。(如果你曾經重構過大型確定性代碼庫,你現在可能會點頭表示認同)。

      11 Trigger from Anywhere

      **原則**:Agent應該能從多種渠道觸發,滿足用戶在不同場景的需求。

      支持的觸發方式:

      • API調用
      • Webhook
      • 定時任務
      • 消息隊列
      • 用戶界面

      好處:

      ? 貼近用戶需求:這有助于你構建感覺像真人的 AI 應用程序,或者至少像數字同事一樣。

      ? 外部循環代理:使代理能夠被非人類觸發,例如事件、定時任務、故障等。它們可能工作 5 分鐘、20 分鐘、90 分鐘,但當它們到達一個關鍵點時,可以聯系人類尋求幫助、反饋或批準。

      ? 高風險工具:如果你能夠快速地讓各種人類參與進來,你就可以讓代理訪問更高風險的操作,比如發送外部郵件、更新生產數據等。保持明確的標準可以讓你對執行更大更好任務的代理進行審計,并對其充滿信心。

      12 Stateless Reducer

      **原則**:Agent的核心邏輯應該是純函數,便于測試和水平擴展。

      實踐建議

      漸進式采用

      不要一次性重寫整個系統,而是逐步引入這些原則:
      1. 從Factor 1開始:先實現結構化輸出
      2. 管理提示詞:將提示詞從代碼中分離
      3. 優化上下文管理:實現智能的上下文選擇
      4. 添加狀態管理:統一業務和執行狀態
      5. 增強控制流:預定義關鍵流程步驟

      工具選擇

      推薦的技術棧:
      • 結構化輸出:OpenAI Function Calling、Anthropic Tool Use
      • 提示詞管理BAML、LangSmith
      • 狀態管理:Redux模式、狀態機
      • 監控觀測:LangSmith、Weights & Biases

      質量保證

      + **單元測試**:對每個Factor進行測試 + **集成測試**:測試完整的Agent流程 + **A/B測試**:比較不同實現方案 + **監控告警**:實時監控Agent性能

      總結

      12-Factor Agents提供了一套經過實踐驗證的原則,幫助開發者構建真正可用的LLM應用。關鍵在于:
      1. 不要讓LLM控制一切:在結構化的框架內使用LLM能力
      2. 擁有核心組件主動管理提示詞、上下文和控制流
      3. 漸進式優化:從簡單開始,逐步完善
      4. 重視工程實踐:測試、監控、版本管理一樣不能少
      posted @ 2025-09-22 22:02  不負如來不負卿x  閱讀(21)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 东京热人妻无码一区二区av| 四虎影视一区二区精品| 久久久天堂国产精品女人| 国产精品久久久久久久久久妞妞| 亚洲综合视频一区二区三区| 欧美亚洲另类制服卡通动漫| 天天干天天日| 极品无码国模国产在线观看| 国产一区二区三区美女| 99九九成人免费视频精品| 国产欧美一区二区精品仙草咪| 亚洲欧美偷国产日韩| 国产免费高清69式视频在线观看| 丰满少妇69激情啪啪无| 锡林浩特市| 国产精品美女www爽爽爽视频| 久久精品一区二区东京热| 手机无码人妻一区二区三区免费| 国产成人啪精品午夜网站| 伊人中文在线最新版天堂| 久久国语对白| 吉川爱美一区二区三区视频| 91精品蜜臀国产综合久久| 撕开奶罩揉吮奶头高潮AV| 国产老妇伦国产熟女老妇高清| 久久久久久久久久久久中文字幕 | 国产一区二区三区av在线无码观看| 青草青草久热国产精品| 婷婷综合亚洲| 最新av中文字幕无码专区| 亚洲国产成人无码影片在线播放| 女人喷液抽搐高潮视频| 久久香蕉国产线熟妇人妻| 成人看的污污超级黄网站免费| 亚洲另类激情专区小说图片| 忘忧草日本在线播放www| 欧美高清freexxxx性| 2020年最新国产精品正在播放 | 精品人妻伦九区久久aaa片| 精品一区二区三区女性色| 亚洲国产成人资源在线|