精品欧美一区二区三区在线观看 _久久久久国色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

?著作權歸作者所有,如需轉載,請注明出處,否則將追究法律責任
收藏
回復
舉報
回復
相關推薦
欧美日韩中文字幕一区二区| 久久激情久久| 欧美v日韩v国产v| 怡红院av亚洲一区二区三区h| 欧美套图亚洲一区| 免费看欧美女人艹b| 免费不卡欧美自拍视频| 日本japanese极品少妇| 久久亚洲人体| 五月婷婷激情综合| 亚洲精品免费在线看| 精品人妻午夜一区二区三区四区 | 天堂久久久久va久久久久| 日韩在线播放视频| 黄色国产在线视频| 日韩中文视频| 亚洲超碰精品一区二区| 亚洲欧洲日韩综合二区| 天堂网av在线播放| 久久国产精品一区二区| 久久久这里只有精品视频| 18精品爽国产三级网站| 久久动漫网址| 欧美一级免费观看| 在线观看国产一级片| 高清毛片在线观看| 国产精品国产成人国产三级| 国产一区二区视频在线免费观看| 亚洲视频在线观看免费视频| 亚洲免费综合| 欧美激情精品久久久久久蜜臀| 中文天堂资源在线| 亚洲人成亚洲精品| 亚洲国内精品在线| 中文在线字幕观看| 国产一区二区三区免费在线| 欧美羞羞免费网站| 日韩一级在线免费观看| a√中文在线观看| 亚洲乱码中文字幕| 日韩视频专区| 你懂的视频在线播放| youjizz国产精品| 99精品国产高清一区二区| 国产精品玖玖玖| 日韩精品电影在线| 欧亚精品中文字幕| 中文字字幕在线中文| 亚洲韩日在线| 性欧美激情精品| 久久久久久久蜜桃| 极品日韩av| 欧美激情国产日韩精品一区18| 外国一级黄色片| 日韩欧美国产精品综合嫩v| 伊人亚洲福利一区二区三区| 一级性生活大片| 久久91精品| 一区二区三区国产在线观看| 69精品无码成人久久久久久| 精品久久久久久久| 日韩专区在线观看| 国产精品国产精品88| 欧美国产一区二区三区激情无套| 中文字幕久精品免费视频| 阿v天堂2014| 日本在线电影一区二区三区| 色综合伊人色综合网站| 亚洲 欧美 变态 另类 综合| 欧美日一区二区三区在线观看国产免| 久久精品中文字幕| 久久久一二三区| 亚洲美女少妇无套啪啪呻吟| 欧美性做爰毛片| 日本丰满少妇做爰爽爽| 久久国产日韩欧美精品| www.一区二区三区| 天天干天天爽天天操| 国产亚洲精品资源在线26u| 日韩一区二区三区资源| 国产福利在线播放麻豆| 亚洲福利视频三区| 青青在线视频观看| 亚洲高清国产拍精品26u| 日韩视频一区二区三区在线播放| 亚洲中文字幕无码一区| 黑人操亚洲人| 欧美久久久精品| 久久黄色精品视频| 久久99精品国产麻豆不卡| 永久亚洲成a人片777777| 在线日韩视频| 视频一区视频二区国产精品 | 亚洲精品国产精品自产a区红杏吧 亚洲精品国产精品乱码不99按摩 亚洲精品国产精品久久清纯直播 亚洲精品国产精品国自产在线 | 欧美日韩国产v| 在线国产电影不卡| av噜噜在线观看| 精品伊人久久久| 最新国产精品亚洲| 不卡的免费av| 日韩成人精品在线观看| av资源站久久亚洲| a视频网址在线观看| 一区二区三区免费| 国产成人无码av在线播放dvd| www.久久草.com| 日韩高清有码在线| 欧美大片xxxx| 老司机久久99久久精品播放免费| 成人福利在线观看| 男女视频在线观看免费| 有坂深雪av一区二区精品| 欧美黄色一级片视频| 日韩高清一区| 中文字幕免费精品一区高清| 国产无遮挡又黄又爽在线观看| 老司机精品视频在线| 精品日韩欧美| 日本在线播放| 91久久精品一区二区| 日本成人在线免费| 999国产精品| 日本三级久久久| 精品人妻无码一区二区三区蜜桃一| 国产喂奶挤奶一区二区三区| aa视频在线播放| 精品视频一区二区三区在线观看| 国产香蕉精品视频一区二区三区| 精品少妇theporn| 久久99久久精品| 少妇精品久久久久久久久久| 日本蜜桃在线观看视频| 精品国产91乱码一区二区三区 | 综合色天天鬼久久鬼色| 黄色国产小视频| 亚州av一区| 亚洲2020天天堂在线观看| 国产99久久九九精品无码免费| 久久人人97超碰com| 女人喷潮完整视频| 欧美黄色影院| 性欧美xxxx视频在线观看| 欧美自拍第一页| 亚洲一级片在线观看| 韩国一区二区三区四区| 午夜精品国产| 91超碰在线电影| 欧美v亚洲v| 欧美sm极限捆绑bd| 久久婷婷一区二区| 国产91在线看| 欧美成人精品免费| 精品在线网站观看| 2019中文字幕全在线观看| 天天射天天操天天干| 欧美午夜片在线免费观看| 日本高清www| 久久婷婷av| 视频一区视频二区视频三区高| 激情开心成人网| 伊人伊成久久人综合网站| 中文字幕在线视频免费| 国产精品久久久久久久午夜片| 奇米影视四色在线| 亚洲草久电影| 国产精品日韩一区二区| 天天综合av| 一区二区av在线| 中文字幕一级片| 亚洲美女偷拍久久| 亚洲av成人精品一区二区三区 | 国产精品久线在线观看| 一二三av在线| 国产综合精品| 久久国产精品一区二区三区四区| 在线毛片观看| 中文精品99久久国产香蕉| 国产精品怡红院| 亚洲国产精品欧美一二99| 97伦伦午夜电影理伦片| 美国三级日本三级久久99| 视色,视色影院,视色影库,视色网| 亚洲日本va| 欧美主播福利视频| 免费黄色电影在线观看| 欧美大黄免费观看| www.久久久久久久| 亚洲天堂2014| 精品人妻一区二区三区香蕉| 青青草97国产精品免费观看无弹窗版 | 爽爽窝窝午夜精品一区二区| 国产精品视频免费观看www| 午夜影院免费在线| 亚洲午夜精品久久久久久性色| 国产免费一区二区三区最新不卡| 午夜日韩在线电影| 久久一级免费视频| 99在线精品视频| 一级做a免费视频| 中文一区在线| 久久观看最新视频| 亚洲の无码国产の无码步美| 伊人精品视频在线观看| 国产香蕉精品| 国产精品色婷婷视频| 91在线三级| 日韩网站免费观看| 神马电影在线观看| 91精品国产综合久久精品图片 | 亚洲欧洲日本专区| 国产又粗又大又爽视频| 一本大道久久精品懂色aⅴ| 欧美国产精品一二三| 欧美国产成人精品| 国产精品久久不卡| 国产凹凸在线观看一区二区| 一级黄色特级片| 久久精品盗摄| 无码中文字幕色专区| 久久久久电影| 神马影院一区二区| 久久97视频| 国产在线一区二区三区四区| 国产剧情一区二区在线观看| 国产精品国产三级国产aⅴ浪潮| 成人影院在线播放| 免费91在线视频| 国产在线观看91| 亚洲色图在线观看| 日韩精品123| 亚洲精品福利在线观看| 风流老熟女一区二区三区| 67194成人在线观看| 亚洲香蕉在线视频| 欧美羞羞免费网站| 欧美在线视频精品| 在线观看成人小视频| 国产精品一区二区三区四| 亚洲成在线观看| 精品少妇theporn| 亚洲午夜激情av| 久久精品一区二区三| 亚洲美女屁股眼交3| 欧美日韩精品亚洲精品| 亚洲另类在线视频| 精品一区二区三区四| 亚洲午夜精品网| 99精品视频99| 黑人精品xxx一区| 亚洲自拍一区在线观看| 在线观看91视频| 欧美超碰在线观看| 色偷偷一区二区三区| av首页在线观看| 欧美日韩在线免费视频| 一区二区日韩视频| 91精品国模一区二区三区| 国产成人三级在线播放| 欧美xingq一区二区| 亚洲一区二区三区四区五区六区| 日韩精品视频播放| 国产精品91一区二区| 久久精品亚洲天堂| 国产精品一区2区| 三上悠亚 电影| 成人av电影在线网| 欧美大片免费播放器| 久久综合99re88久久爱| 中文字幕在线观看免费高清| 亚洲国产精品99久久久久久久久 | 91一区在线观看| 美女100%无挡| 亚洲欧洲另类国产综合| 久久久久久久黄色| 欧美午夜激情小视频| 99久久久久久久久| 欧美精品三级在线观看| 性一交一乱一透一a级| 日韩高清中文字幕| 在线视频1区2区| 欧美高跟鞋交xxxxhd| 美女av在线免费看| 国产精品综合久久久| 亚洲一区二区三区免费| 欧美成熟毛茸茸复古| 日韩一区二区在线免费| youjizz.com在线观看| 性高湖久久久久久久久| 国产喷水theporn| 成人午夜免费av| 国产123在线| 一区二区免费在线| 久久久蜜桃一区二区| 欧美一区日韩一区| 你懂的免费在线观看| 欧美猛男性生活免费| 色综合一本到久久亚洲91| 91aaaa| 国产成人精品三级高清久久91| 欧美少妇一区二区三区| 久久国产精品久久w女人spa| 久久99欧美| 蜜桃传媒一区二区亚洲av | 欧美精品观看| 免费黄色日本网站| 国内精品国产三级国产a久久| 中文字幕在线永久| 亚洲品质自拍视频网站| 欧美一区二区三区不卡视频| 欧美不卡一区二区| 日本在线视频站| 国产精品久久久久久久裸模| 欧美成人在线免费| 日韩激情视频一区二区| 无码一区二区三区| 亚洲综合无码一区二区| 羞羞色院91蜜桃| 亚洲国产一区自拍| 黄色在线视频网站| 国产精品福利观看| 日韩影视在线观看| 蜜桃久久精品乱码一区二区| 亚洲精品传媒| 2025国产精品视频| 69精品国产久热在线观看| 宅男噜噜99国产精品观看免费| 国产精品美女久久久| 在线播放av网址| 亚洲人妖av一区二区| 中国女人一级一次看片| 亚洲视频在线观看免费| 精品众筹模特私拍视频| 亚洲aa中文字幕| 婷婷丁香综合| 在线观看国产一级片| 免费观看在线午夜影视| 日韩中文字幕区一区有砖一区| 免费看日本毛片| 国产成人亚洲综合a∨猫咪| 婷婷国产成人精品视频| 欧美亚洲日本国产| 国产精品一区在线看| 欧美诱惑福利视频| 日韩精品欧美大片| 欧美日韩一道本| 99re这里都是精品| 丰满少妇乱子伦精品看片| 国产精品入口麻豆九色| 第一页在线视频| 亚洲女爱视频在线| 国产乱人乱偷精品视频a人人澡| 色悠悠久久88| 国产精品亚洲欧美一级在线| 久久免费视频2| 国产乱码精品一区二区三区av| 国产精品视频一区二区三| 91精品国产一区二区三区香蕉| 九七久久人人| 97netav| 欧美特黄a级高清免费大片a级| wwwww在线观看| 午夜精品福利久久久| 天堂av网在线| 国产成人亚洲精品| 99国内精品久久久久久久| 亚洲一二三av| 亚洲韩国精品一区| 视频二区在线| 国产精品丝袜一区二区三区| 仙踪林久久久久久久999| 久久发布国产伦子伦精品| 调教+趴+乳夹+国产+精品| 精品福利视频导航大全| 国产主播精品在线| 激情综合在线| 人妻精品久久久久中文| 欧美日韩视频在线第一区| 中文字幕久久av| 国产一区一区| 亚洲精品第一区二区三区| 久久99久久99精品免视看婷婷 | 欧美成人午夜剧场免费观看| 97se亚洲| 国产又大又黄又粗的视频| 亚洲男人的天堂av| 十九岁完整版在线观看好看云免费| 国产精品美女www| 欧美日韩国产成人精品| 波多野结衣福利| 欧美狂野另类xxxxoooo| 国产免费拔擦拔擦8x高清在线人| 日本一区二区三区免费看 | 性活交片大全免费看| 色又黄又爽网站www久久| 国产一二区在线| 久久婷婷人人澡人人喊人人爽| 久久国产精品无码网站| 国产精品黄色大片| xxx成人少妇69| 亚洲黄页网站|