01-tool-react-over-text.yml 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. id: tool-react-over-text
  2. module: A
  3. week: 2
  4. title: "工具调用范式①:react-over-text(把工具调用当散文手写 JSON)"
  5. concept:
  6. textbook: |
  7. ReAct(Yao et al., 2022)让 LLM 在 Thought → Action → Observation 之间交替:
  8. 模型先"想"(Thought),再发一个"动作"(Action),环境执行后把结果(Observation)
  9. 回灌,如此循环直到给出答案。
  10. 最朴素的工程实现是 **react-over-text**:不依赖模型原生的工具调用能力,而是要求
  11. 模型把 Action 以一段约定格式的文本写出来(通常是一段 JSON),平台再用正则把这段
  12. 文本"抠"出来、自己去执行。模型在这里并不"调用"工具,它只是在"描述"一个调用。
  13. key_point: >
  14. react-over-text 把工具调用降格成"生成文本 → 正则解析 JSON",是 0 执行 /
  15. 格式飘移 / path-vs-file_path 不一致的总根源。它适合做 fallback,不该当主车道。
  16. code:
  17. - file: lambdagent/src/lambdagent/fromconfig/compiler.py
  18. symbol: _compile_react
  19. lines: "878-933"
  20. note: >
  21. 文本车道主入口。顶部做门控分叉:react.nativeToolCalls 关闭时(默认),
  22. 返回基于 ConversationLam 的文本 ReAct 循环,模型输出靠正则解析。
  23. - file: lambdagent/src/lambdagent/conversation.py
  24. symbol: ConversationLam
  25. lines: "60-126"
  26. note: >
  27. 文本车道的"思考"算子。每步把历史 + 最新 observation 拼成 prompt 发给 provider,
  28. 拿回纯文本,再交给上层正则解析出 action。靠 max_input_chars 兜住上下文膨胀。
  29. formal:
  30. term: "Loop(ConversationLam ∘ action_parser, cond, max_steps)"
  31. effect: "IO[tool] ⊕ Partial"
  32. note: >
  33. action_parser 是一个**部分函数**:模型文本不合约定时解析失败(返回空动作或抛错)。
  34. 这个"部分性(Partial)"正是范式②原生 FC 要从类型上消除的东西——FC 让工具调用
  35. 成为结构化、类型受控的对象,而非一段可能解析失败的散文。
  36. live_demo:
  37. run: agentexample/research67/workspace/run_20260520_004928
  38. highlight: >
  39. 999 步 react_step,工具调用全部以文本形式嵌在每步 output 里(看 "[Step N] X done")。
  40. 这是 react-over-text 在长任务里空转/重做的典型形态:步数巨大,真正落盘寥寥。
  41. related:
  42. - tool-native-fc
  43. - tool-claude-code-native
  44. takeaway: |
  45. 对照三栏后学生应能说清:
  46. 1. 概念上,react-over-text 仍是合法的 ReAct,只是 Action 用文本承载;
  47. 2. 代码上,它落在 _compile_react 的"非 nativeToolCalls"分支 + ConversationLam;
  48. 3. 形式上,它引入了一个部分函数 action_parser,把"解析失败"这一失效模式带进了系统。
  49. 这就是"为什么需要形式化"的第一个实证:范式②用类型把这个失效模式提前消除。