建:用CoT與ReAct拆解OpenManus式任務(wù)規(guī)劃)
1. 從一次“卡住”的任務(wù)說起CoT 與 ReAct 在 Agent 里到底誰管什么如果你正在做 AI 智能體Agent開發(fā)大概率遇到過這種場(chǎng)景給智能體一個(gè)稍微復(fù)雜的任務(wù)比如“幫我整理一份本周技術(shù)熱點(diǎn)并生成摘要”它要么在第一步就停下來等你繼續(xù)輸入要么反復(fù)調(diào)用同一個(gè)搜索工具把同樣的關(guān)鍵詞查了五遍最后返回一堆重復(fù)內(nèi)容。這不是模型不夠聰明而是任務(wù)規(guī)劃層沒有把 CoTChain of Thought思維鏈和 ReActReasoning Acting推理與行動(dòng)的分工理清楚。CoT 解決的是“想清楚”的問題。它讓模型在給出最終答案前先把推理過程展開把復(fù)雜問題拆成可管理的子問題。ReAct 解決的是“做明白”的問題。它在推理的基礎(chǔ)上引入行動(dòng)讓智能體能夠調(diào)用外部工具、觀察返回結(jié)果、再根據(jù)結(jié)果調(diào)整下一步。兩者不是替代關(guān)系而是上下游關(guān)系CoT 負(fù)責(zé)生成推理路徑ReAct 負(fù)責(zé)把推理路徑落到工具調(diào)用鏈路里形成“思考—行動(dòng)—觀察”的閉環(huán)。OpenManus 這類開源智能體框架之所以值得參考是因?yàn)樗堰@條鏈路拆得足夠清晰。它的 BaseAgent 定義了執(zhí)行循環(huán)ReActAgent 把 step 拆成 think 和 actToolCallAgent 再把工具調(diào)用接進(jìn)來。你不需要照搬它的全部代碼但理解這個(gè)分層能幫你避開“把所有邏輯塞進(jìn)一個(gè) prompt”的坑。這篇內(nèi)容會(huì)圍繞一個(gè)可跟做的 Agent 配置展開從意圖解析到執(zhí)行反饋把 CoT 與 ReAct 的分工落到可復(fù)制的 JSON 配置和一次端到端驗(yàn)證上。適合已經(jīng)了解大模型 API 調(diào)用、想進(jìn)一步做任務(wù)型智能體的開發(fā)者。2. 前置準(zhǔn)備用 TaoToken 統(tǒng)一模型入口與工具調(diào)用鏈路在拆解 CoT 與 ReAct 之前先把模型調(diào)用入口固定下來。智能體開發(fā)最怕的是模型接口換一個(gè)、工具調(diào)用格式變一次整個(gè)鏈路就要重寫。我試過在多個(gè)項(xiàng)目里來回切換模型端點(diǎn)最后發(fā)現(xiàn)統(tǒng)一走一個(gè)兼容 OpenAI 接口的入口最省事。TaoToken 提供的就是這樣一個(gè)入口它的 API 地址是 https://taotoken.net/api兼容常見的 chat completions 和 tools 調(diào)用格式你可以在模型對(duì)話頁(yè)面先驗(yàn)證模型是否正常響應(yīng)再進(jìn)入編碼環(huán)節(jié)。為什么智能體場(chǎng)景特別需要統(tǒng)一入口因?yàn)?ReAct 模式下的每一輪 think 和 act 都會(huì)產(chǎn)生一次模型調(diào)用如果每次調(diào)用的端點(diǎn)、鑒權(quán)方式、工具描述格式不一致調(diào)試成本會(huì)成倍增加。TaoToken 的接口設(shè)計(jì)讓你可以用同一套 Base URL 和 Key 去驅(qū)動(dòng)不同模型工具調(diào)用的返回結(jié)構(gòu)也保持一致。這樣你在寫 ToolCallAgent 時(shí)不需要為每個(gè)模型寫適配層。具體操作上先到 API Keys 頁(yè)面生成一個(gè) Key然后在接入文檔里確認(rèn) tools 參數(shù)的寫法。如果你用的是 Claude Code 這類編碼工具做智能體原型可以在它的配置里把 Base URL 指向 https://taotoken.net/apiModel ID 填你實(shí)際要用的模型名。對(duì)于長(zhǎng)期跑編碼類 Agent 的場(chǎng)景Coding Plan 提供了更穩(wěn)定的調(diào)用額度適合把智能體掛在后臺(tái)持續(xù)執(zhí)行任務(wù)。這里要強(qiáng)調(diào)一點(diǎn)智能體的工具調(diào)用鏈路對(duì)模型返回格式很敏感。ReAct 要求模型在 think 階段輸出“我要調(diào)用哪個(gè)工具、參數(shù)是什么”在 act 階段執(zhí)行后把 observation 拼回上下文。如果模型返回的 tool_calls 結(jié)構(gòu)不標(biāo)準(zhǔn)整個(gè)循環(huán)就會(huì)斷掉。TaoToken 的兼容層會(huì)把不同模型的工具調(diào)用統(tǒng)一成 OpenAI 風(fēng)格的 tool_calls 數(shù)組你在解析時(shí)只需要處理一種格式。這是把 CoT 和 ReAct 串起來的前提。3. 可復(fù)制配置把 CoT 提示詞與 ReAct 工具鏈寫進(jìn) settings下面這份配置可以直接復(fù)制到你的項(xiàng)目里路徑建議放在config/agent_settings.json。它把 CoT 的系統(tǒng)提示詞、ReAct 的循環(huán)參數(shù)、工具定義三部分分開方便你單獨(dú)調(diào)整。注意 Model ID 和 Base URL 要和你實(shí)際使用的入口一致。{ agent: { name: cot_react_agent, max_steps: 12, duplicate_threshold: 2, system_prompt: You are an assistant focused on Chain of Thought reasoning. For each question, follow these steps: 1. Break down the problem into smaller parts. 2. Think step by step and show your reasoning. 3. Synthesize conclusions. 4. Provide a concise answer. Your response format: Thinking: [detailed reasoning] Action: [tool name and arguments] , next_step_prompt: Based on the observation, decide the next action. If the task is complete, call the terminate tool. }, llm: { base_url: https://taotoken.net/api, api_key: sk-your-key-here, model_id: gpt-4o-mini, temperature: 0.2 }, tools: [ { name: web_search, description: Search the web for current information, parameters: { type: object, properties: { query: { type: string, description: search keywords } }, required: [query] } }, { name: python_execute, description: Execute Python code in a sandbox and return stdout, parameters: { type: object, properties: { code: { type: string, description: Python code to run } }, required: [code] } }, { name: terminate, description: Terminate the interaction when the task is complete, parameters: { type: object, properties: { status: { type: string, enum: [success, failure] } }, required: [status] } } ] }這份配置里system_prompt承擔(dān) CoT 的角色強(qiáng)制模型先輸出 Thinking 再輸出 Action。next_step_prompt承擔(dān) ReAct 的循環(huán)推進(jìn)每一輪 observation 回來后用它提醒模型決定下一步。max_steps和duplicate_threshold是防止無限循環(huán)的保險(xiǎn)絲當(dāng)同一條 assistant 消息重復(fù)出現(xiàn)超過閾值時(shí)觸發(fā) stuck 處理往上下文里注入“換策略”的提示。如果你用的是 Claude Code 或 Cline 這類工具做 MCP 接入配置片段要寫成它們認(rèn)識(shí)的格式。以 Cline 的 MCP 配置為例Base URL、Key、Model ID 三件套要寫全{ mcpServers: { taotoken_agent: { command: npx, args: [-y, taotoken/mcp-server], env: { BASE_URL: https://taotoken.net/api, API_KEY: sk-your-key-here, MODEL_ID: gpt-4o-mini } } } }Codex 的 auth.json 則把憑證單獨(dú)存放Base URL 和 Model ID 寫在 config 里。無論哪種工具核心都是讓工具調(diào)用鏈路指向同一個(gè)入口這樣 CoT 生成的推理路徑和 ReAct 執(zhí)行的工具調(diào)用才能在同一套上下文里流轉(zhuǎn)。4. 端到端驗(yàn)證一次“搜索并摘要”任務(wù)的完整執(zhí)行反饋配置寫好后用一個(gè)具體任務(wù)驗(yàn)證閉環(huán)。任務(wù)描述“搜索最近三天關(guān)于 AI Agent 的技術(shù)文章提取三篇用 Python 統(tǒng)計(jì)每篇標(biāo)題的詞頻最后輸出摘要?!边@個(gè)任務(wù)同時(shí)需要 CoT 拆解步驟和 ReAct 調(diào)用搜索與代碼執(zhí)行工具。啟動(dòng)智能體后第一輪 think 的輸出應(yīng)該類似Thinking: 任務(wù)需要三步。第一步用 web_search 找文章第二步用 python_execute 統(tǒng)計(jì)詞頻第三步匯總摘要。先執(zhí)行搜索。 Action: web_search Arguments: {query: AI Agent 技術(shù)文章 最近三天}執(zhí)行 web_search 后observation 返回搜索結(jié)果列表。第二輪 think 根據(jù) observation 決定提取哪三篇然后調(diào)用 python_execute。這里要注意CoT 的推理過程會(huì)體現(xiàn)在 Thinking 字段里而 ReAct 的行動(dòng)體現(xiàn)在 Action 字段。如果模型只輸出了 Thinking 沒有 Action說明 system_prompt 里的格式約束不夠強(qiáng)可以在 next_step_prompt 里加一句“必須輸出 Action 字段否則任務(wù)無法推進(jìn)”。第三輪 python_execute 返回詞頻統(tǒng)計(jì)結(jié)果第四輪 think 判斷任務(wù)完成調(diào)用 terminate 工具。整個(gè)循環(huán)的 step 數(shù)控制在 4 到 6 之間。如果超過 8 步還沒結(jié)束檢查 duplicate_threshold 是否觸發(fā)或者模型是否在重復(fù)調(diào)用同一個(gè)工具。實(shí)測(cè)下來把 temperature 設(shè)在 0.2 左右工具調(diào)用的穩(wěn)定性明顯好于 0.7 以上。驗(yàn)證成功的標(biāo)志是最終輸出里包含三篇文章標(biāo)題、詞頻統(tǒng)計(jì)結(jié)果和一段摘要并且 terminate 的 status 是 success。如果中途出現(xiàn)reading choices報(bào)錯(cuò)通常是模型返回的 tool_calls 結(jié)構(gòu)里 choices 字段為空檢查 Base URL 是否指向了兼容層以及 tools 參數(shù)是否傳入了正確的 JSON Schema。5. 常見報(bào)錯(cuò)排查401、local proxy failed 與 OAuth 問題智能體鏈路跑不通時(shí)報(bào)錯(cuò)往往集中在幾個(gè)固定位置。下面按真實(shí)遇到的順序排列。401 Unauthorized 最常見。先確認(rèn) API Key 是否復(fù)制完整有沒有多余空格。然后檢查 Base URL 是否寫成了https://taotoken.net/api注意不要漏掉/api路徑。如果用的是環(huán)境變量確認(rèn)變量名和代碼里讀取的一致。有些工具會(huì)把 Key 放在 header 的Authorization: Bearer里有些放在x-api-key接入文檔里有說明按文檔來。local proxy failed通常出現(xiàn)在工具調(diào)用返回階段。這不是網(wǎng)絡(luò)問題而是模型返回的 tool_calls 里 arguments 不是合法 JSON導(dǎo)致本地解析失敗。解決辦法是在 act 階段加一層 try-catch把原始返回打出來看。如果 arguments 里出現(xiàn)了單引號(hào)或未轉(zhuǎn)義字符可以在 system_prompt 里強(qiáng)調(diào)“arguments 必須是合法 JSON字符串用雙引號(hào)”。reading choices報(bào)錯(cuò)說明你拿到的響應(yīng)結(jié)構(gòu)里沒有 choices 數(shù)組或者 choices 為空。這多半是模型端點(diǎn)返回了錯(cuò)誤信息但被當(dāng)成了正常響應(yīng)。檢查 HTTP 狀態(tài)碼如果是 200 但 body 里是 error 字段說明鑒權(quán)或參數(shù)有問題。另外確認(rèn) model_id 是否拼寫正確有些模型名帶版本號(hào)少一個(gè)字符就會(huì)走到默認(rèn)模型。OAuth 相關(guān)報(bào)錯(cuò)一般出現(xiàn)在 Claude Code 或 Codex 這類工具的登錄環(huán)節(jié)。如果你用的是 API Key 模式不需要走 OAuth直接在配置里填 Key 即可。如果工具強(qiáng)制要求 OAuth 而你又想用 API Key檢查是否有auth_type之類的配置項(xiàng)可以切換。CC Switch 這類工具在切換配置時(shí)要確保 Base URL、Key、Model ID 三件套同時(shí)更新只改其中一個(gè)會(huì)導(dǎo)致鑒權(quán)失敗。還有一個(gè)容易忽略的點(diǎn)工具定義里的parameters如果 JSON Schema 寫錯(cuò)模型可能返回空的 tool_calls。比如required數(shù)組里的字段名和properties里的不一致或者type寫成了str而不是string。每次改完工具定義先用模型對(duì)話頁(yè)面發(fā)一條簡(jiǎn)單請(qǐng)求確認(rèn)模型能正確識(shí)別工具。6. 把 CoT 與 ReAct 的分工固定下來后續(xù)擴(kuò)展才不亂走到這里你已經(jīng)有了一個(gè)能跑通“搜索—統(tǒng)計(jì)—摘要”的智能體?;仡^看CoT 負(fù)責(zé)的是每一輪 think 里的推理展開它決定了任務(wù)被拆成幾步、每步的目標(biāo)是什么。ReAct 負(fù)責(zé)的是 think 與 act 的交替循環(huán)它決定了工具什么時(shí)候被調(diào)用、observation 怎么拼回上下文。兩者在 OpenManus 式的分層里各司其職BaseAgent 管循環(huán)ReActAgent 管 think/act 拆分ToolCallAgent 管工具執(zhí)行。后續(xù)如果你想加新工具只需要在 tools 數(shù)組里追加定義不需要改 CoT 的提示詞。如果想換模型改 llm 配置里的 model_id 即可ReAct 的循環(huán)邏輯不受影響。這種分工帶來的好處是調(diào)試時(shí)你能快速定位問題出在推理層還是執(zhí)行層。推理層的問題表現(xiàn)為步驟拆解不合理執(zhí)行層的問題表現(xiàn)為工具調(diào)用失敗或 observation 解析錯(cuò)誤。對(duì)于需要長(zhǎng)期運(yùn)行的編碼類 Agent可以把這套配置掛到 Coding Plan 的穩(wěn)定調(diào)用上避免頻繁的額度中斷。驗(yàn)證模型是否支持工具調(diào)用時(shí)模型對(duì)話頁(yè)面是最快的入口。接入文檔里有完整的 tools 參數(shù)示例和錯(cuò)誤碼說明遇到不確定的返回結(jié)構(gòu)先對(duì)照文檔確認(rèn)格式。把這套鏈路跑順之后再往里面加記憶系統(tǒng)或知識(shí)庫(kù)檢索就不會(huì)因?yàn)榛A(chǔ)循環(huán)不穩(wěn)而反復(fù)返工。