精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Agent設計12要素:構建可靠的AI Agent 原創(chuàng)

發(fā)布于 2025-7-28 09:37
瀏覽
0收藏

本文僅做記錄譯自:raw repo:https://github.com/humanlayer/12-factor-agents

因素 1. 自然語言到工具調用

在構建智能體時最常見的模式之一是將自然語言轉換為結構化工具調用。這是一種強大的模式,它允許你構建能夠推理任務并執(zhí)行它們的智能體。

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

當原子化地應用此模式時,它可以將類似以下的短語

你能為Terri創(chuàng)建一個750美元的支付鏈接,用于贊助二月的AI Tinkerers聚會嗎?

轉換為描述Stripe API調用的結構化對象,例如

{
  "function": {
    "name": "create_payment_link",
    "parameters": {
      "amount": 750,
      "customer": "cust_128934ddasf9",
      "product": "prod_8675309",
      "price": "prc_09874329fds",
      "quantity": 1,
      "memo": "嘿Jeff - 請參見下方用于二月AI Tinkerers聚會的支付鏈接"
    }
  }
}

注意:實際上,Stripe API稍微復雜一些,一個真正執(zhí)行此操作的智能體(視頻)會列出客戶、產(chǎn)品、價格等,以使用正確的ID構建此有效載荷,或在提示/上下文窗口中包含這些ID(我們將在下面看到,它們其實是一回事!)

從那里,確定性代碼可以接收有效載荷并對其進行處理。(更多內容請參見因素3)

# LLM接收自然語言并返回一個結構化對象
nextStep = await llm.determineNextStep(
"""
  為Jeff創(chuàng)建一個750美元的支付鏈接
  用于贊助二月的AI Tinkerers聚會
  """
  )

# 根據(jù)其功能處理結構化輸出
if nextStep.function == 'create_payment_link':
    stripe.paymentlinks.create(nextStep.parameters)
    return# 或者你想要的任何內容,請參見下文
elif nextStep.function == 'something_else':
    # ... 更多情況
    pass
else:  # 模型未調用我們知道的工具
    # 做其他事情
    pass

注意:雖然一個完整的智能體會接收API調用結果并與其循環(huán),最終返回類似

我已成功為Terri創(chuàng)建了一個750美元的支付鏈接,用于贊助二月的AI Tinkerers聚會。鏈接如下:https://buy.stripe.com/test_1234567890

相反,我們在這里實際上會跳過這一步,并將其留給另一個因素,你可以選擇是否也采用(由你決定!)

因素 2. 擁有你的提示

不要將你的提示工程外包給一個框架。

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

順便說一句,這遠非新穎的建議:

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

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

agent = Agent(
  role="...",
  goal="...",
  persnotallow="...",
  tools=[tool1, tool2, tool3]
)

task = Task(
  instructinotallow="...",
  expected_output=OutputModel
)

result = agent.run(task)

這對于引入一些頂級的提示工程來幫助你入門是很好的,但通常很難進行微調和/或逆向工程,以獲得進入模型的精確標記。

相反,擁有你的提示,并將其視為一等公民的代碼:

function DetermineNextStep(thread: string) -> DoneForNow | ListGitTags | DeployBackend | DeployFrontend | RequestMoreInformation {
  prompt #"
    {{ _.role("system") }}
    
    你是一個管理前端和后端系統(tǒng)部署的有用助手。
    你勤奮地確保通過遵循最佳實踐和正確的部署程序來實現(xiàn)安全和成功的部署。
    
    在部署任何系統(tǒng)之前,你應該檢查:
    - 部署環(huán)境(暫存 vs 生產(chǎn))
    - 要部署的正確標簽/版本
    - 當前系統(tǒng)狀態(tài)
    
    你可以使用諸如 deploy_backend、deploy_frontend 和 check_deployment_status
    等工具來管理部署。對于敏感部署,使用 request_approval 來獲得
    人工驗證。
    
    始終思考首先該做什么,比如:
    - 檢查當前部署狀態(tài)
    - 驗證部署標簽是否存在
    - 如有需要,請求批準
    - 在生產(chǎn)之前先部署到暫存環(huán)境
    - 監(jiān)控部署進度
    
    {{ _.role("user") }}

    {{ thread }}
    
    下一步應該是什么?
  "#
}

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

如果簽名看起來有點奇怪,我們將在因素4 - 工具只是結構化輸出中討論這一點

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

擁有你的提示的關鍵好處:

  1. 完全控制:編寫你的智能體需要的確切指令,沒有黑盒抽象
  2. 測試和評估:像對待任何其他代碼一樣,為你的提示構建測試和評估
  3. 迭代:根據(jù)實際表現(xiàn)快速修改提示
  4. 透明性:確切知道你的智能體在使用什么指令
  5. 角色黑客:利用支持用戶/助手角色非標準用法的API - 例如,現(xiàn)已棄用的OpenAI“completions” API的非聊天版本。這包括一些所謂的“模型誤導”技術

記住:你的提示是你應用程序邏輯和LLM之間的主要接口。

完全控制你的提示能為你提供生產(chǎn)級智能體所需的靈活性和提示控制。

我不知道什么是最好的提示,但我知道你想要嘗試一切的靈活性。

因素 3. 擁有你的上下文窗口

你不一定需要使用標準的基于消息的格式來向LLM傳遞上下文。

在任何給定的時刻,你向智能體中的LLM輸入的內容是:“到目前為止發(fā)生了什么,下一步是什么”

一切皆是上下文工程。LLM是無狀態(tài)函數(shù),它們將輸入轉換為輸出。為了獲得最佳輸出,你需要給它們提供最佳輸入。

創(chuàng)建優(yōu)秀的上下文意味著:

  • 你給模型的提示和指令
  • 你檢索的任何文檔或外部數(shù)據(jù)(例如RAG)
  • 任何過去的狀態(tài)、工具調用、結果或其他歷史記錄
  • 來自相關但獨立的歷史/對話的任何過去消息或事件(記憶)
  • 關于應輸出何種結構化數(shù)據(jù)的指令

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

關于上下文工程

本指南的全部內容都是關于如何從今天的模型中獲取盡可能多的價值。值得注意的是,以下內容并未提及:

  • 模型參數(shù)的更改,如 temperature、top_p、frequency_penalty、presence_penalty 等。
  • 訓練你自己的補全或嵌入模型
  • 微調現(xiàn)有模型

再次強調,我不知道將上下文交給LLM的最佳方式是什么,但我知道你需要有靈活性來嘗試一切。

標準與自定義上下文格式

大多數(shù)LLM客戶端使用類似這樣的標準基于消息的格式:

[
  {
    "role":"system",
    "content":"You are a helpful assistant..."
},
{
    "role":"user",
    "content":"Can you deploy the backend?"
},
{
    "role":"assistant",
    "content":null,
    "tool_calls":[
      {
        "id":"1",
        "name":"list_git_tags",
        "arguments":"{}"
      }
    ]
},
{
    "role":"tool",
    "name":"list_git_tags",
    "content":"{\"tags\": [{\"name\": \"v1.2.3\", \"commit\": \"abc123\", \"date\": \"2024-03-15T10:00:00Z\"}, {\"name\": \"v1.2.2\", \"commit\": \"def456\", \"date\": \"2024-03-14T15:30:00Z\"}, {\"name\": \"v1.2.1\", \"commit\": \"abe033d\", \"date\": \"2024-03-13T09:15:00Z\"}]}",
    "tool_call_id":"1"
}
]

雖然這在大多數(shù)用例中效果很好,但如果你想真正從今天的LLM中榨取最大價值,你需要以最節(jié)省token和注意力的方式將你的上下文輸入到LLM中。

作為標準基于消息格式的替代方案,你可以構建自己的上下文格式,以優(yōu)化你的特定用例。例如,你可以使用自定義對象,并根據(jù)需要將它們打包/展開到一個或多個用戶、系統(tǒng)、助手或工具消息中。

以下是一個將整個上下文窗口放入單個用戶消息中的示例:

[
{
    "role":"system",
    "content":"You are a helpful assistant..."
},
{
    "role":"user",
    "content":|
            Here's everything that happened so far:
        
        <slack_message>
            From:@alex
            Channel:#deployments
            Text:Canyoudeploythebackend?
        </slack_message>
        
        <list_git_tags>
            intent:"list_git_tags"
        </list_git_tags>
        
        <list_git_tags_result>
            tags:
              -name:"v1.2.3"
                commit:"abc123"
                date:"2024-03-15T10:00:00Z"
              -name:"v1.2.2"
                commit:"def456"
                date:"2024-03-14T15:30:00Z"
              -name:"v1.2.1"
                commit:"ghi789"
                date:"2024-03-13T09:15:00Z"
        </list_git_tags_result>
        
        what'sthenextstep?
    }
]

模型可能會通過你提供的工具模式推斷出你在詢問它??下一步是什么??,但將其融入你的提示模板也無妨。

代碼示例

我們可以用類似這樣的方式來構建:

class Thread:
  events: List[Event]

class Event:
# 可以只用字符串,也可以顯式定義 - 由你決定
  type: Literal["list_git_tags", "deploy_backend", "deploy_frontend", "request_more_information", "done_for_now", "list_git_tags_result", "deploy_backend_result", "deploy_frontend_result", "request_more_information_result", "done_for_now_result", "error"]
  data: ListGitTags | DeployBackend | DeployFrontend | RequestMoreInformation |  
        ListGitTagsResult | DeployBackendResult | DeployFrontendResult | RequestMoreInformationResult | string

def event_to_prompt(event: Event) -> str:
    data = event.data if isinstance(event.data, str) \
           else stringifyToYaml(event.data)

    returnf"<{event.type}>\n{data}\n</{event.type}>"


def thread_to_prompt(thread: Thread) -> str:
return'\n\n'.join(event_to_prompt(event) for event in thread.events)

示例上下文窗口

以下是使用這種方法的上下文窗口可能的樣子:

初始Slack請求:

<slack_message>
    From: @alex
    Channel: #deployments
    Text: Can you deploy the latest backend to production?
</slack_message>

列出Git標簽后:

<slack_message>
    From: @alex
    Channel: #deployments
    Text: Can you deploy the latest backend to production?
    Thread: []
</slack_message>

<list_git_tags>
    intent: "list_git_tags"
</list_git_tags>

<list_git_tags_result>
    tags:
      - name: "v1.2.3"
        commit: "abc123"
        date: "2024-03-15T10:00:00Z"
      - name: "v1.2.2"
        commit: "def456"
        date: "2024-03-14T15:30:00Z"
      - name: "v1.2.1"
        commit: "ghi789"
        date: "2024-03-13T09:15:00Z"
</list_git_tags_result>

出錯并恢復后:

<slack_message>
    From: @alex
    Channel: #deployments
    Text: Can you deploy the latest backend to production?
    Thread: []
</slack_message>

<deploy_backend>
    intent: "deploy_backend"
    tag: "v1.2.3"
    environment: "production"
</deploy_backend>

<error>
    error running deploy_backend: Failed to connect to deployment service
</error>

<request_more_information>
    intent: "request_more_information_from_human"
    question: "I had trouble connecting to the deployment service, can you provide more details and/or check on the status of the service?"
</request_more_information>

<human_response>
    data:
      response: "I'm not sure what's going on, can you check on the status of the latest workflow?"
</human_response>

從這里開始,你的下一步可能是:

nextStep = await determine_next_step(thread_to_prompt(thread))

{
  "intent": "get_workflow_status",
  "workflow_name": "tag_push_prod.yaml",
}

XML風格的格式只是一個例子 - 關鍵是你可以構建自己的格式,使其符合你的應用程序需求。如果你有靈活性去嘗試不同的上下文結構以及存儲和傳遞給LLM的內容,你將獲得更好的質量。

擁有你的上下文窗口的關鍵好處:

  1. 信息密度:以最大化LLM理解的方式組織信息
  2. 錯誤處理:以幫助LLM恢復的格式包含錯誤信息。考慮在錯誤和失敗的調用解決后將其從上下文窗口中隱藏。
  3. 安全性:控制傳遞給LLM的信息,過濾掉敏感數(shù)據(jù)
  4. 靈活性:根據(jù)你學到的最佳實踐調整格式
  5. Token效率:優(yōu)化上下文格式以提高token效率和LLM理解

上下文包括:提示、指令、RAG文檔、歷史、工具調用、記憶

記住:上下文窗口是你與LLM的主要接口。掌控如何結構化和呈現(xiàn)信息可以顯著提升你的智能體性能。

示例 - 信息密度 - 相同消息,更少的tokens:

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

Loom Screenshot 2025-04-22 at 09 00 56

不要聽我說的

在12因子智能體發(fā)布約2個月后,上下文工程開始成為一個相當流行的術語。

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

還有來自@lenadroid的相當不錯的上下文工程備忘單,發(fā)布于2025年7月。

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

這里反復出現(xiàn)的主題是:我不知道最好的方法是什么,但我知道你需要有靈活性來嘗試一切。

因素  4. 工具只是結構化輸出

工具不需要很復雜。在核心上,它們只是來自你LLM的結構化輸出,觸發(fā)了確定性的代碼。

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

例如,假設你有兩個工具 ??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
  2. 確定性代碼執(zhí)行相應的操作(例如調用外部API)
  3. 捕獲結果并反饋到上下文中

這在LLM的決策和你的應用程序操作之間創(chuàng)建了一個清晰的分離。LLM決定做什么,但你的代碼控制如何做。僅僅因為LLM“調用了一個工具”,并不意味著你必須每次都以相同的方式執(zhí)行一個特定的對應函數(shù)。

如果你還記得我們上面的switch語句

if nextStep.intent == 'create_payment_link':
    stripe.paymentlinks.create(nextStep.parameters)
    return # 或者你想要的任何內容,請參見下文
elif nextStep.intent == 'wait_for_a_while': 
    # 做一些單子操作,我不知道
else: #... 模型沒有調用我們知道的工具
    # 做其他事情

注意:關于“純提示”與“工具調用”與“JSON模式”的好處以及每種方法的性能權衡,已經(jīng)有很多討論。我們很快會鏈接一些關于這些內容的資源,但在這里不會深入探討。參見提示 vs JSON模式 vs 函數(shù)調用 vs 約束生成 vs SAP,我什么時候應該使用函數(shù)調用、結構化輸出或JSON模式? 和 OpenAI JSON vs 函數(shù)調用。

“下一步”可能不像“運行一個純函數(shù)并返回結果”那樣原子化。當你將“工具調用”視為模型輸出描述確定性代碼應該做什么的JSON時,你會解鎖很多靈活性。將這一點與因素8 擁有你的控制流結合起來。

因素  5. 統(tǒng)一執(zhí)行狀態(tài)和業(yè)務狀態(tài)

即使在AI世界之外,許多基礎設施系統(tǒng)也試圖將“執(zhí)行狀態(tài)”與“業(yè)務狀態(tài)”分開。對于AI應用,這可能涉及復雜的抽象來跟蹤當前步驟、下一步、等待狀態(tài)、重試次數(shù)等。這種分離會帶來復雜性,可能值得,但也可能對你的用例來說是過度設計。

一如既往,決定什么適合你的應用由你決定。但不要認為你必須將它們分開管理。

更明確地說:

  • 執(zhí)行狀態(tài):當前步驟、下一步、等待狀態(tài)、重試次數(shù)等。
  • 業(yè)務狀態(tài):代理工作流到目前為止發(fā)生了什么(例如,OpenAI消息列表、工具調用和結果列表等)。

如果可能,盡量簡化——盡可能統(tǒng)一這些狀態(tài)。

實際上,你可以設計你的應用,以便從上下文窗口推斷出所有執(zhí)行狀態(tài)。在許多情況下,執(zhí)行狀態(tài)(當前步驟、等待狀態(tài)等)只是到目前為止發(fā)生的事情的元數(shù)據(jù)。

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

這種方法有幾個好處:

  1. 簡單性:所有狀態(tài)的單一事實來源
  2. 序列化:線程可以輕松地序列化/反序列化
  3. 調試:整個歷史記錄在一個地方可見
  4. 靈活性:只需添加新的事件類型即可輕松添加新狀態(tài)
  5. 恢復:只需加載線程即可從任何點恢復
  6. 分叉:通過將線程的某個子集復制到新的上下文/狀態(tài)ID中,可以在任何點分叉線程
  7. 人機接口和可觀測性:可以輕松將線程轉換為人類可讀的markdown或豐富的Web應用UI

因素  6. 使用簡單API啟動/暫停/恢復

智能體只是程序,我們對其啟動、查詢、恢復和停止的方式有相應的期望。

用戶、應用程序、管道和其他智能體應該能夠通過簡單的API輕松啟動智能體。

智能體及其協(xié)調的確定性代碼應該能夠在需要長時間運行操作時暫停智能體。

外部觸發(fā)器(如webhooks)應允許智能體從中斷處恢復,而無需與智能體協(xié)調器進行深度集成。

這與因素5 - 統(tǒng)一執(zhí)行狀態(tài)和業(yè)務狀態(tài)和因素8 - 擁有你的控制流密切相關,但可以獨立實現(xiàn)。

注意 - 通常AI協(xié)調器允許暫停和恢復,但不能在工具選擇和工具執(zhí)行的瞬間之間進行。另見因素7 - 使用工具調用聯(lián)系人類和因素11 - 從任何地方觸發(fā),與用戶會面。

因素  7. 使用工具調用聯(lián)系人類

默認情況下,LLM API 依賴于一個基本的高風險 token 選擇:我們是返回純文本內容,還是返回結構化數(shù)據(jù)?

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

你把這個選擇的權重放在了第一個 token 上,對于 ??the weather in tokyo?? 這種情況,它是

"the"

但在 ??fetch_weather?? 的情況下,它是一些特殊 token 來表示 JSON 對象的開始。

|JSON>

你可能會通過讓 LLM 始終 輸出 json 獲得更好的結果,然后用一些自然語言 token 聲明其意圖,比如 ??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]

# 用于人機交互的工具定義
class RequestHumanInput:
  intent: "request_human_input"
  question: str
  context: str
  options: Options

# 在代理循環(huán)中的示例用法
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# 中斷循環(huán)并等待帶有線程ID的響應
else:
# ... 其他情況

稍后,你可能會收到來自處理 Slack、電子郵件、短信或其他事件的系統(tǒng)的 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
  })
# ... 為簡潔起見,你可能不希望在這里阻塞 web worker
  next_step = await determine_next_step(thread_to_prompt(thread))
  thread.events.append(next_step)
  result = await handle_next_step(thread, next_step)
# todo - 循環(huán)或中斷或任何你想要的

return {"status": "ok"}

上述內容包含了因素 5 - 統(tǒng)一執(zhí)行狀態(tài)和業(yè)務狀態(tài)、因素 8 - 擁有你的控制流、因素 3 - 擁有你的上下文窗口和因素 4 - 工具只是結構化輸出以及其他幾個因素的模式。

如果我們使用因素 3 - 擁有你的上下文窗口中的 XML 風格格式,經(jīng)過幾次交互后,我們的上下文窗口可能看起來像這樣:

(為簡潔起見省略)

<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>

好處:

  1. 明確的指令:用于不同類型人機聯(lián)系的工具允許 LLM 提供更多具體信息
  2. 內循環(huán)與外循環(huán):使代理工作流能夠超出傳統(tǒng)的 chatGPT 風格界面,其中控制流和上下文初始化可能是??Agent->Human?? 而不是??Human->Agent??(想想由 cron 或事件觸發(fā)的代理)
  3. 多個人訪問:可以通過結構化事件輕松跟蹤和協(xié)調來自不同人的輸入
  4. 多代理:簡單的抽象可以輕松擴展以支持??Agent->Agent?? 的請求和響應
  5. 持久性:結合因素 6 - 使用簡單 API 啟動/暫停/恢復,這使得持久、可靠且可檢查的多人工作流成為可能

更多關于外循環(huán)代理的內容在這里

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

與因素 11 - 從任何地方觸發(fā),與用戶會面配合使用效果很好

← 啟動/暫停/恢復 | 擁有你的控制流 →

因素  8. 擁有你的控制流

如果你擁有你的控制流,你就可以做很多有趣的事情。

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

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

  • 工具調用結果的摘要或緩存
  • 對結構化輸出的LLM評判
  • 上下文窗口壓縮或其他內存管理
  • 日志記錄、追蹤和指標
  • 客戶端速率限制
  • 持久性睡眠/暫停/"等待事件"

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

  • request_clarification:模型請求更多信息,跳出循環(huán)并等待來自人類的響應
  • fetch_git_tags:模型請求獲取git標簽列表,獲取標簽,附加到上下文窗口,并直接傳回給模型
  • deploy_backend:模型請求部署后端,這是一件高風險的事情,因此跳出循環(huán)并等待人工批準

def handle_next_step(thread: Thread):

whileTrue:
    next_step = await determine_next_step(thread_to_prompt(thread))
    
    # 為了清晰起見內聯(lián) - 實際上你可以將其放入一個方法中,使用異常進行控制流,或任何你想要的方式
    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)
      # 異步步驟 - 跳出循環(huán),我們稍后會收到一個webhook
      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,
      })
      # 同步步驟 - 將新上下文傳遞給LLM以確定下一步
      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)
      # 異步步驟 - 跳出循環(huán),我們稍后會收到一個webhook
      break

這種模式允許你根據(jù)需要中斷和恢復智能體的流程,從而創(chuàng)建更自然的對話和工作流。

示例 - 我對每個AI框架的最大功能請求是我們需要能夠中斷正在工作的智能體并稍后恢復,尤其是在工具選擇和工具調用時刻之間

如果沒有這種級別的可恢復性/粒度,就無法在工具調用運行前進行審查/批準,這意味著你只能:

  1. 在等待長時間運行的任務完成時在內存中暫停任務(想想??while...sleep??),如果過程被中斷,則從頭開始重新啟動
  2. 將智能體限制為僅進行低風險、低風險的調用,如研究和摘要
  3. 允許智能體訪問進行更大、更有用的操作,并希望它不會搞砸

你可能會注意到這與因素5 - 統(tǒng)一執(zhí)行狀態(tài)和業(yè)務狀態(tài)和因素6 - 使用簡單API啟動/暫停/恢復密切相關,但可以獨立實現(xiàn)。

← 返回 README

因素 9. 將錯誤壓縮到上下文窗口

這一點雖然有點簡短,但值得提及。智能體的好處之一是“自我修復”——對于短期任務,LLM可能會調用一個失敗的工具。好的LLM有很大幾率能夠讀取錯誤消息或堆棧跟蹤,并在后續(xù)的工具調用中找出需要更改的內容。

大多數(shù)框架都實現(xiàn)了這一點,但你可以在不進行其他11個因素的情況下僅實現(xiàn)這一點。以下是一個示例:

thread = {"events": [initial_message]}

whileTrue:
  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) # 我們的switch語句
except Exception as e:
    # 如果出現(xiàn)錯誤,可以將其添加到上下文窗口并重試
    thread["events"].append({
      "type": 'error',
      "data": format_error(e),
    })
    # 循環(huán),或在此處執(zhí)行其他操作以嘗試恢復

你可能希望為特定的工具調用實現(xiàn)一個錯誤計數(shù)器,以限制單個工具的嘗試次數(shù)約為3次,或根據(jù)你的用例實施其他邏輯。

consecutive_errors = 0

whileTrue:

# ... 現(xiàn)有代碼 ...

try:
    result = await handle_next_step(thread, next_step)
    thread["events"].append({
      "type": next_step.intent + '_result',
      data: result,
    })
    # 成功!重置錯誤計數(shù)器
    consecutive_errors = 0
except Exception as e:
    consecutive_errors += 1
    if consecutive_errors < 3:
      # 進行循環(huán)并重試
      thread["events"].append({
        "type": 'error',
        "data": format_error(e),
      })
    else:
      # 中斷循環(huán),重置上下文窗口的部分內容,升級到人工,或執(zhí)行其他操作
      break
  }
}

達到連續(xù)錯誤閾值可能是升級到人工的好時機,無論是通過模型決策還是通過控制流的確定性接管。

好處:

  1. 自我修復:LLM可以讀取錯誤消息并找出在后續(xù)工具調用中需要更改的內容
  2. 持久性:即使一個工具調用失敗,智能體也可以繼續(xù)運行

我確信你會發(fā)現(xiàn),如果這樣做得太多,你的智能體會開始失控,并可能一遍又一遍地重復相同的錯誤。

這就是因素8 - 擁有你的控制流和因素3 - 擁有你的上下文構建發(fā)揮作用的地方——你不需要僅僅將原始錯誤放回,你可以完全重構其表示方式,從上下文窗口中移除先前的事件,或執(zhí)行任何確定性操作來使智能體重回正軌。

但防止錯誤失控的首要方法是擁抱因素10 - 小而專注的智能體。

因素 10. 小而專注的智能體

與其構建試圖做所有事情的龐大智能體,不如構建小而專注、能做好一件事的智能體。智能體只是更大、主要是確定性系統(tǒng)中的一個構建模塊。

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

這里的關鍵見解是關于LLM的局限性:任務越大越復雜,需要的步驟就越多,這意味著上下文窗口會更長。隨著上下文的增長,LLM更有可能迷失或失去焦點。通過讓智能體專注于特定領域,最多3-10步,可能20步,我們就能保持上下文窗口的可管理性,從而保持LLM的高性能。

隨著上下文的增長,LLM更有可能迷失或失去焦點

小而專注的智能體的好處:

  1. 可管理的上下文:較小的上下文窗口意味著更好的LLM性能
  2. 明確的責任:每個智能體都有明確定義的范圍和目的
  3. 更好的可靠性:在復雜工作流中迷失的可能性更小
  4. 更易測試:更容易測試和驗證特定功能
  5. 改進的調試:在出現(xiàn)問題時更容易識別和修復

如果LLM變得更聰明了怎么辦?

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

簡而言之,是的。隨著智能體和LLM的進步,它們可能自然擴展到能夠處理更長的上下文窗口。這意味著能夠處理更大的DAG的更多部分。這種小而專注的方法確保你今天就能獲得結果,同時為隨著LLM上下文窗口變得更加可靠而慢慢擴展智能體范圍做好準備。(如果你之前重構過大型確定性代碼庫,你可能現(xiàn)在就在點頭了)。

,時長00:14

有意地控制智能體的大小/范圍,并且只以允許你保持質量的方式增長,是這里的關鍵。正如構建NotebookLM的團隊所說:

我覺得,對我來說,AI構建中最神奇的時刻總是當我真的、真的、真的接近模型能力的邊緣時

無論那個邊界在哪里,如果你能找到那個邊界并持續(xù)正確地做到,你就能構建出神奇的體驗。這里有很多護城河可以建立,但和往常一樣,它們需要一些工程嚴謹性。

因素 11. 從任何地方觸發(fā),與用戶會面

如果你在等待 humanlayer 的推薦,你已經(jīng)找到了。如果你正在執(zhí)行因素6 - 使用簡單API啟動/暫停/恢復和因素7 - 使用工具調用聯(lián)系人類,你已經(jīng)準備好融入這一因素。

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

允許用戶通過Slack、電子郵件、短信或他們想要的任何其他渠道觸發(fā)智能體。允許智能體通過相同的渠道進行響應。

好處:

  • 與用戶會面:這有助于你構建感覺像真人或至少是數(shù)字同事的AI應用
  • 外循環(huán)智能體:允許智能體由非人類觸發(fā),例如事件、cron、故障或其他任何情況。它們可能工作5、20、90分鐘,但當它們到達關鍵點時,可以聯(lián)系人類尋求幫助、反饋或批準
  • 高風險工具:如果你能夠快速引入各種人類,你可以讓智能體訪問更高風險的操作,如發(fā)送外部電子郵件、更新生產(chǎn)數(shù)據(jù)等。保持清晰的標準可以讓你對智能體進行審計并對其執(zhí)行更大更好的事情充滿信心

因素 12. 讓你的智能體成為一個無狀態(tài)的歸約器

好吧,到目前為止我們已經(jīng)有1000多行的markdown了。這一點主要是為了好玩。

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

Agent設計12要素:構建可靠的AI Agent-AI.x社區(qū)

本文轉載自???大模型自然語言處理??   作者:Agent

?著作權歸作者所有,如需轉載,請注明出處,否則將追究法律責任
收藏
回復
舉報
回復
相關推薦
成人免费视频入口| 亚洲一区二区三区加勒比 | 日本一区二区在线| 久久不卡免费视频| 国产探花在线精品一区二区| 91精品91久久久中77777| 色噜噜色狠狠狠狠狠综合色一| 国产乱码在线观看| 午夜国产精品视频| 国产视频自拍一区| 国产精品亚洲a| avtt在线播放| 成人性视频免费网站| 97久久超碰福利国产精品…| 少妇精品一区二区三区| 国产精品无码久久久久| 一区二区三区精品久久久| 久久久久久九九| 97人妻人人澡人人爽人人精品 | 无码精品国产一区二区三区免费| 理论片午午伦夜理片在线播放| 成人精品一区二区三区四区| 国产精品香蕉国产| 六月丁香激情综合| 午夜欧美精品| 日韩在线视频播放| 久久久久久久久久久国产精品| 精品一区二区三区视频在线播放| 色八戒一区二区三区| 欧美午夜性视频| 超碰免费在线播放| 国产精品国产自产拍高清av王其| 久久精品国产理论片免费| 国产高清在线观看视频| 日本亚洲三级在线| 国产成人精品在线| 超碰中文字幕在线| 一区二区激情| 午夜精品在线视频| 久久久久久久久久综合| 欧美久久99| 欧美成人精品在线观看| 自拍偷拍第9页| 欧美高清视频手机在在线| 亚洲一二三在线| 亚洲精品视频久久久| 欧美调教视频| 日韩精品免费在线播放| 亚洲一区二区三区四区五区六区| 99re8这里有精品热视频8在线| 91精品国产一区二区人妖| 亚洲综合在线网站| 日韩欧美看国产| 一本色道久久综合亚洲91| 国模无码视频一区二区三区| sm捆绑调教国产免费网站在线观看| 一区二区三区在线视频播放| 亚洲乱码日产精品bd在线观看| 亚洲妇熟xxxx妇色黄| 伊人夜夜躁av伊人久久| 免费日韩在线观看| 伦理在线一区| 黄色成人在线免费| 免费黄色福利视频| 欧美亚洲大片| 欧美日韩一二区| 亚洲热在线视频| 亚洲1区在线观看| 精品国产乱码久久久久久老虎| 欧美激情 亚洲| 免费欧美激情| 日韩中文字幕网| 91视频免费在线看| 一区二区亚洲| 欧洲成人午夜免费大片| 无码一区二区三区在线观看| 老司机亚洲精品| 成人黄色网免费| 亚洲国产精品久久人人爱潘金莲| 成人国产精品免费| 久久精品国产美女| 阿v免费在线观看| 国产精品国产精品国产专区不蜜| 国产奶头好大揉着好爽视频| 成人三级小说| 日本乱码高清不卡字幕| 亚洲无在线观看| 欧美顶级毛片在线播放| 国产小视频国产精品| 国产精品酒店视频| 亚洲综合自拍| 日本精品在线视频| 亚洲天堂手机版| 99久久伊人精品| 一本一道久久a久久精品综合| 欧美性猛片xxxxx免费中国| 欧美日韩激情视频| 看看黄色一级片| 亚州精品视频| 久久国产精品影视| 成人免费视频国产免费| 国产jizzjizz一区二区| 日本一区二区三区视频在线观看| 国产乱色在线观看| 91福利精品第一导航| 中文字幕无码毛片免费看| 一区二区三区视频免费观看| 另类美女黄大片| 欧美超碰在线观看| 99天天综合性| 中文字幕乱码免费| 3d欧美精品动漫xxxx无尽| 日韩精品中午字幕| 亚欧精品视频一区二区三区| 在线视频精品| 91久久偷偷做嫩草影院| 91福利在线视频| 一本久道久久综合中文字幕| 中文字幕1区2区| 欧美成人milf| 国产99久久精品一区二区| 亚洲欧美强伦一区二区| 1000精品久久久久久久久| 99精品视频播放| 国内精品偷拍| 欧美激情第99页| 国产永久免费视频| 国产无人区一区二区三区| 拔插拔插海外华人免费| 日韩一二三区在线观看| www.亚洲一区| 亚洲天堂网视频| 欧美国产一区二区| 日本免费一级视频| 全国精品免费看| 91高潮精品免费porn| 好吊视频一区二区三区| 一区二区免费看| wwwxxx色| 国产精品多人| 国产精品美女久久久久av福利| 亚洲无线看天堂av| 欧美一区二区在线不卡| 日本a级片视频| 国产麻豆欧美日韩一区| 欧美少妇一区二区三区| 成人免费91| 久久这里有精品视频| 国产又大又长又粗| 亚洲精品你懂的| 日本中文字幕精品—区二区| 久久国产精品亚洲人一区二区三区| 国产成人aa精品一区在线播放| 青青草免费在线| 色94色欧美sute亚洲线路一ni| 全黄一级裸体片| 久久激情久久| 日产精品一线二线三线芒果| 午夜av成人| 日韩资源在线观看| 国产成人精品无码高潮| 一级女性全黄久久生活片免费| 18禁一区二区三区| 影音先锋亚洲精品| 久久亚洲综合网| 成人免费视频观看| zzjj国产精品一区二区| 国产成人麻豆精品午夜在线| 亚洲成人自拍偷拍| 中文字幕av网址| 日本在线观看不卡视频| 国产精品99久久久久久大便| 亚洲国产欧美国产第一区| 欧美激情在线播放| 午夜福利视频一区二区| 在线看日韩精品电影| 国产白丝一区二区三区| 国产麻豆精品一区二区| 国产精品一区二区免费在线观看| 精品久久综合| 91九色极品视频| 中文不卡1区2区3区| 日韩在线视频网站| 日本黄色三级视频| 欧美伊人精品成人久久综合97 | 欧亚乱熟女一区二区在线| 免费欧美日韩| 特级黄色录像片| 日韩高清影视在线观看| 国产精品久久久久久五月尺| 中文字幕在线播放网址| 亚洲精品动漫久久久久| 在线观看黄色网| 亚洲成av人片在www色猫咪| 亚洲ⅴ国产v天堂a无码二区| 高清在线不卡av| 亚洲黄色av网址| 亚洲精品1区| 亚洲永久一区二区三区在线| 久久中文字幕导航| 国产美女久久精品| 91丝袜在线| www.日韩视频| 久久久久久久影视| 欧美成人伊人久久综合网| 精品久久久久久久久久久国产字幕| 亚洲美女淫视频| 亚洲欧美va天堂人熟伦| 成a人片国产精品| 亚洲综合欧美激情| 国产精品日韩精品欧美精品| 国产日产欧美一区二区| av亚洲在线观看| 久久riav| 成人搞黄视频| 亚洲999一在线观看www| 成人国产精品| 日本国产一区二区三区| 国产精品69xx| 麻豆成人在线看| √天堂资源地址在线官网| 亚洲精品自拍偷拍| 丰满少妇一级片| 日韩午夜激情av| 一级黄色短视频| 在线看一区二区| 加勒比在线一区| 欧美性xxxx18| 久久久久久久极品| 亚洲成人你懂的| 久久久久久久久久久久久久免费看 | 久久国产婷婷国产香蕉| 成人免费观看毛片| av成人毛片| 国产 福利 在线| 夜夜嗨av一区二区三区网站四季av| av日韩在线看| 欧美三级网页| 日韩国产成人无码av毛片| 中文字幕日韩一区二区不卡 | 91中文字精品一区二区| 粉嫩一区二区三区在线观看| 成人av在线天堂| 91精品福利观看| 成人亚洲欧美一区二区三区| 亚洲伦理一区二区| 91亚洲精品在线观看| 激情久久免费视频| 91久久精品一区二区别| 一区二区三区在线免费看| 99一区二区| 97久久亚洲| 国产亚洲二区| 亚洲小说图片| 奇米精品在线| 日韩欧美伦理| 久久精品国产精品亚洲精品色 | 国产黄视频在线| 国产精品色网| 国产熟人av一二三区| 美国一区二区三区在线播放| 一级黄色片在线免费观看| 国产成人久久精品77777最新版本 国产成人鲁色资源国产91色综 | 精品小视频在线观看| 亚洲不卡一区二区三区| 国产精品国产三级国产专区52| 一本色道久久综合亚洲91| 日本成人一级片| 7777精品伊人久久久大香线蕉完整版| 国产美女自慰在线观看| 日韩久久久久久| 你懂得网站在线| 日韩中文字幕在线播放| 蜜臀av在线播放| 奇米一区二区三区四区久久| 97成人超碰| 97在线中文字幕| 香蕉久久夜色精品国产使用方法| 亚洲人久久久| 影音先锋日韩资源| 国产又黄又猛又粗又爽的视频| 韩国欧美国产1区| 先锋资源av在线| 欧美国产激情二区三区| 免费看一级一片| 色综合一个色综合亚洲| 国产又粗又黄视频| 日韩av最新在线| 午夜视频在线| 97免费中文视频在线观看| 福利一区和二区| 精品视频第一区| 亚洲国产一区二区在线观看| 午夜肉伦伦影院| 国产一区二区美女诱惑| a级大片在线观看| 亚洲第一综合色| 在线免费看毛片| 日韩成人黄色av| 先锋成人av| 国产精品永久免费| 美女视频亚洲色图| 色撸撸在线观看| 日韩在线播放一区二区| 男人添女人荫蒂国产| 国产精品女同一区二区三区| 欧美日韩乱国产| 日韩你懂的在线播放| 成人性爱视频在线观看| 97色在线视频| 欧美成年网站| 亚洲欧洲中文| 久久在线精品| 精品国产aⅴ一区二区三区东京热| 欧美国产综合一区二区| 国产一区二区99| 精品久久一二三区| 韩国av网站在线| 国产情人节一区| 精品国产99| 无码精品国产一区二区三区免费| 成人久久视频在线观看| 青娱乐在线视频免费观看| 欧美日韩亚洲综合在线 欧美亚洲特黄一级| 日本人妻丰满熟妇久久久久久| 另类少妇人与禽zozz0性伦| 日韩国产大片| 亚洲开发第一视频在线播放| 老司机精品视频网站| 亚洲激情视频小说| 欧美日韩亚洲高清| 欧美天堂在线视频| 欧美激情综合亚洲一二区| 国产精品视频一区二区三区| 在线视频精品一区| 蜜臀精品久久久久久蜜臀| 精品一区二区三区蜜桃在线| 欧洲日韩一区二区三区| 欧美zozo| 国产精品国产三级国产aⅴ浪潮| 精品影片在线观看的网站| 中国丰满人妻videoshd| 91婷婷韩国欧美一区二区| 99热只有这里有精品| 亚洲精品理论电影| 手机在线理论片| 免费精品视频一区| 日韩专区在线视频| 18精品爽国产三级网站| 欧美日本在线观看| 欧美69xxx| 亚洲xxx视频| 影音先锋国产精品| 精品无码在线视频| 一本大道av伊人久久综合| 欧美挠脚心网站| 国产精品中文久久久久久久| 国产精品videosex性欧美| 人妻体体内射精一区二区| 一区二区三区日韩精品| 熟妇人妻中文av无码| 欧美亚洲视频在线看网址| 国产麻豆精品久久| 亚洲高清免费在线观看| 亚洲视频一区二区免费在线观看| 99这里有精品视频| 久久频这里精品99香蕉| 精品一区在线| 亚洲欧美手机在线| 亚洲成av人片一区二区| 邻居大乳一区二区三区| 国产日韩在线视频| 好看的亚洲午夜视频在线| 搡老熟女老女人一区二区| 在线视频欧美区| 成人video亚洲精品| 精品久久久久亚洲| 日韩成人dvd| 九九九在线视频| 日韩精品极品在线观看播放免费视频 | 午夜精品福利一区二区三区蜜桃| 天天操天天舔天天干| 国产精品男人的天堂| 欧美日韩四区| av在线网站观看| 在线综合视频播放| 高清精品在线| 正在播放精油久久| 成人黄色av电影| 欧美成人一区二区视频| 久久99精品国产99久久6尤物 | 亚洲日本成人女熟在线观看| 欧美一区二区三区婷婷| 久久精品国产sm调教网站演员| 欧美激情一区二区在线| 亚洲精品人妻无码| 国产精品视频一| 一区二区福利| 青青草精品在线视频| 一区二区三区精品99久久|