Agent四大核心模式:从理论到工程实践
第一章 Agent为什么需要推理模式
1.1 LLM的局限
大语言模型在单轮对话中表现惊艳,但面对复杂任务时,直接回答的模式会暴露出明显的短板:
直接回答
↓
复杂任务效果下降
具体表现为四个"不会":
- 不会拆解任务 ------ 面对"分析特斯拉投资价值"这种复合问题,模型倾向于给出笼统的概括,而不是系统性地分解
- 不会主动获取信息 ------ 模型只知道训练数据中的内容,不会主动搜索、查证、对比
- 不会验证答案 ------ 模型对自己的输出缺乏有效的自我检查机制,错误答案往往说得同样自信
- 不会持续优化 ------ 一次输出即为最终结果,没有迭代改进的意识
这些问题并非模型"不够聪明",而是单步推理的固有局限。人类的认知过程天然包含分解、交互、反思等环节,Agent推理模式正是将这些认知策略系统化地赋予AI。
1.2 Agent能力演进
从2022年至今,Agent推理模式经历了一条清晰的演进路径:
CoT (2022)
↓
ReAct (2023)
↓
Plan (2023)
↓
Reflection (2023-2024)
每种模式解决一个核心问题:
| 模式 | 解决什么问题 | 核心贡献 |
|---|---|---|
| CoT | 怎么思考 | 将隐式推理显式化,让模型展示思维过程 |
| ReAct | 怎么行动 | 让模型与外部世界交互,获取真实信息 |
| Plan | 怎么组织复杂任务 | 任务分解与编排,支持依赖管理和并行执行 |
| Reflection | 怎么提升质量 | 自我评估与迭代改进,持续优化输出 |
这四种模式并非相互替代,而是层层叠加。 CoT提供了推理的基础范式,ReAct在其上增加了行动能力,Plan解决了多任务编排问题,Reflection则为整个流程加上了质量保证层。
第二章 CoT:让模型学会思考
2.1 理论基础
Chain-of-Thought(思维链)由Google Research在2022年提出,论文标题为:
Chain-of-Thought Prompting Elicits Reasoning in Large Language Models (Wei et al., NeurIPS 2022)
论文的核心洞见可以用一句话概括:
Answer(直接给答案)
↓
Reasoning + Answer(展示推理过程 + 答案)
实验证明,在数学推理(GSM8K)、常识推理(CSQA)、符号推理等任务上,CoT prompting相比标准提示有显著提升。关键发现是:模型规模越大,CoT的增益越明显 ------ 这暗示了CoT并非简单的提示技巧,而是激发了LLM内在的推理能力。
2.2 为什么有效
CoT有效的根本原因在于Transformer架构的特性。当模型被要求逐步推理时:
- 中间计算步骤被显式地放入上下文,后续的token生成可以基于之前的推理结果
- 注意力机制可以在推理步骤之间建立联系,形成逻辑链条
- 每一步的输出都成为下一步的输入,将串行推理问题转化为条件生成问题
以简单的乘法为例:
# 直接回答
23 × 47 = 1081
# CoT回答
23 × 40 = 920
23 × 7 = 161
920 + 161 = 1081
直接回答时,模型需要在一次前向传播中"心算"出1081 ------ 这对Transformer来说是一个隐式的多步计算。而CoT将计算过程展开,每一步都是一个简单的运算,每一步的中间结果都可以被后续步骤利用。
本质上,CoT将推理的计算负担从"模型内部隐式计算"转移到了"上下文中的显式展开"。
2.3 CoT经典变体
Zero-shot CoT
最简单的变体,只需在提示末尾加上一句:
Let's think step by step.
Kojima et al. (NeurIPS 2022) 发现,即使是零样本场景,加上这一句话就能大幅提升推理准确率。这是性价比最高的CoT用法。
Few-shot CoT
提供2-3个包含完整推理过程的示例,让模型模仿示例中的推理模式。适用于对推理格式有特定要求的场景。
Self-Consistency(自洽性)
Wang et al. (ICLR 2023) 提出的Self-Consistency比简单的置信度评分更加主流和可靠:
CoT × N(采样N条推理路径)
↓
多数投票(选择最一致的答案)
核心思想是:对同一个问题采样多条推理路径,然后对最终答案进行多数投票。多条推理路径指向同一个答案,比单条路径的置信度更可靠。
这一方法在你的工程代码中可以通过以下方式实现:
python
# 多次采样 + 投票
results = []
for _ in range(n_samples):
result = await chain_of_thought(query, config=config)
results.append(result.final_answer)
final_answer = majority_vote(results)
2.4 工程实现
聊完理论,我们来看工程实现。以下代码来自实际生产系统。
Prompt构造
python
def build_chain_of_thought_prompt(query: str, config: ChainOfThoughtConfig) -> str:
if config.prompt_template:
return config.prompt_template.replace("{query}", query)
prompt = f"""请逐步解决这个问题:
问题:{query}
请系统地思考:
1. 首先,识别问题的核心
2. 将问题分解为步骤
3. 对每个步骤进行清晰的推理
4. 展示你的思考过程并解释原因
5. 得出最终答案
使用 "→" 标记每个推理步骤。
以 "因此:" 开头给出最终答案。"""
return prompt
推理步骤提取
python
def parse_reasoning_steps(response: str, delimiter: str) -> List[str]:
lines = response.split("\n")
steps = []
for line in lines:
line = line.strip()
if (line.startswith("→") or
line.startswith("Step") or
re.match(r"^\d+\.", line) or
line.startswith("•")):
steps.append(line)
if not steps:
segments = response.split(". ")
for segment in segments:
segment = segment.strip()
if len(segment) > 20:
steps.append(segment)
if len(steps) >= 5:
break
return steps
结果组织
python
@dataclass
class ChainOfThoughtResult:
final_answer: str = ""
reasoning_steps: List[str] = field(default_factory=list)
total_tokens: int = 0
confidence: float = 0.0
step_durations: List[float] = field(default_factory=list)
完整流程:构建提示 → 执行推理 → 解析步骤 → 提取答案 → 格式化输出。
2.5 开源项目实践
Claude Code
Claude Code在执行复杂代码修改任务时,会先在内部进行规划性推理,明确:
- 需要修改哪些文件
- 每处修改的目的
- 修改之间的依赖关系
然后再逐步执行。这正是CoT思想在编程Agent中的应用。
OpenHands
OpenHands 在任务执行前会生成reasoning trace,展示Agent对任务的理解和计划步骤,用户可以看到Agent"在想什么"。
2.6 优缺点
优势:
- 推理过程透明,便于理解和验证
- 显著提升复杂推理任务的准确率
- 实现简单,Zero-shot CoT只需一句话
局限:
- Token消耗增加(推理步骤需要额外的上下文)
- 响应时间变长(串行生成推理步骤)
- 推理更长 ≠ 推理更正确:模型可能生成看似合理但实际错误的推理链,长的推理步骤可能只是在"圆谎"而不是真的在推理
- 对于简单问题,CoT可能是过度设计
第三章 ReAct:让模型学会行动
3.1 理论基础
ReAct由Yao et al. (ICLR 2023)在论文 ReAct: Synergizing Reasoning and Acting in Language Models 中提出。
论文的核心贡献是将推理(Reasoning)和行动(Acting)交织在一起,让模型不再是"空想家",而是能够与外部世界交互的"实干家"。
3.2 ReAct核心循环
ReAct的基础循环极其简洁:
Thought(思考)
↓
Action(行动)
↓
Observation(观察)
↓
Thought(思考下一步)
↓
...直到任务完成
每一次迭代包含三个阶段:
| 阶段 | 做什么 | 产出 |
|---|---|---|
| Reason | 分析当前状态,决定下一步行动 | 行动计划 |
| Act | 执行行动(搜索、调用API、运行代码等) | 行动结果 |
| Observe | 记录结果,更新对问题的认知 | 新的状态 |
3.3 为什么比CoT更强
CoT的致命弱点是:它只能基于模型内部的参数化知识进行推理。如果模型不知道某个事实,再长的推理链也无法弥补。
# CoT面对的问题
模型:我应该搜索最新的数据...
模型:但我没办法搜索。
模型:基于我的训练数据(截止2023年)...
用户:我需要的是2025年的数据!
而ReAct解决了这个问题:
CoT = 只思考(think only)
ReAct = 思考 + 获取真实信息(think + act on real information)
外部工具给了Agent获取真实世界信息的能力,这是从"知识问答系统"到"任务执行Agent"的关键跃迁。
3.4 工程实现
主循环
python
def react_loop(
query: str,
base_context: Dict[str, Any],
session_id: str,
history: List[str],
config: ReactConfig,
execute_agent_fn=None,
publish_event_fn=None,
record_token_fn=None,
) -> ReactLoopResult:
循环状态通过三个列表管理:
python
observations: List[str] = []
thoughts: List[str] = []
actions: List[str] = []
Reason阶段
推理Agent专门负责分析当前状态并决定下一步:
python
reason_query = (
f"REASON (1-2 sentences) about the single next action for: {query}\n"
f"Constraints:\n"
f"- State exactly what to do, why it's needed, and expected outcome.\n"
f"- If external information is required, say 'search'.\n"
f"Context: Previous observations: {recent_obs}"
)
reason_result = execute_agent_fn(
query=reason_query,
agent_id=f"reasoner-{iteration}",
context=reason_context
)
Action阶段
行动Agent根据推理结果执行具体的工具调用:
python
action_query = (
f"ACT on this plan: {reason_result.response}\n"
f"Constraints:\n"
f"- Execute the next step with available tools.\n"
f"- Keep actions atomic."
)
action_result = execute_agent_fn(
query=action_query,
agent_id=f"actor-{iteration}",
context=action_context,
suggested_tools=suggested_tools
)
Observe阶段
行动结果被记录为观察:
python
observation = f"Action result: {truncated_action}"
observations.append(observation)
# 滑动窗口管理,防止上下文溢出
if len(observations) > config.max_observations:
observations = [summary] + observations[-(config.max_observations - 1):]
停止条件
智能停止机制包含三种判定:
python
def should_stop_react_loop(observations, thoughts, agent_results, iteration) -> bool:
# 条件1: 找到高置信度解决方案
if has_high_confidence_solution(observations, thoughts):
return True
# 条件2: 连续两次迭代结果相似(收敛)
if len(observations) >= 2:
if are_similar(observations[-1], observations[-2]):
return True
# 条件3: 没有新的信息增量(引用数停滞)
if citation_count_stable(agent_results, observations):
return True
return False
这三种条件的组合有效避免了无限循环。
3.5 与原始ReAct的区别
这是一个重要的区分,必须明确:
| 维度 | 论文中的ReAct | 本文实现 |
|---|---|---|
| 架构 | 单Agent循环 | 多Agent协作(reasoner + actor + synthesizer) |
| 工具调用 | 预定义的有限动作空间 | 动态工具注册 |
| 停止条件 | 动作空间中的"finish"动作 | 多条件启发式判断 |
| 最终输出 | 循环中直接产生 | 独立的Synthesis阶段 |
论文中的ReAct是一个端到端的单模型循环,而工程实现中将其拆分为reasoner和actor两个Agent的协作。这种拆分的原因是:
- 专业化:推理和行动需要不同的prompt engineering策略
- 可控性:可以独立调整每个Agent的模型层级和预算
- 可观测性:每个阶段的输出都独立可见,便于调试
3.6 OpenHands中的ReAct
OpenHands 是ReAct模式在实际项目中的典范:
Thought: 我需要修改utils.py中的日期格式化函数
Action: 读取 utils.py
Observation: [文件内容显示在第45-52行]
Thought: 发现使用了过时的datetime.strftime,应替换为isoformat
Action: 修改第48行代码
Observation: 修改成功
Thought: 需要运行测试验证
Action: 运行 pytest tests/test_utils.py
Observation: 3个测试通过
这个流程清晰地展示了ReAct在代码修改场景中的应用:先观察、再推理、后行动、再验证。
第四章 Plan与DAG工作流
4.1 理论基础
Plan模式的理论基础来自Wang et al. (ACL 2023)的 Plan-and-Solve Prompting。
核心思想:
Plan First(先规划)
Execute Later(后执行)
与CoT的直接逐步推理不同,Plan模式强调在动手之前先有一个完整的蓝图。这对应人类解决问题的策略:先想清楚要做什么,再一步步做。
4.2 Planner
以"分析特斯拉投资价值"为例,Planner会将其分解为:
财报分析 ← 获取最新季度的财务数据
竞争分析 ← 对比蔚来、比亚迪、Rivian
风险分析 ← 政策风险、供应链风险、技术路线风险
估值分析 ← 基于DCF和可比公司的估值区间
每个子任务可以指定:
- 任务类型(research / analysis / synthesis)
- 建议的工具(web_search / python_executor)
- 建议的角色(财务分析师 / 行业研究员)
- 依赖关系
python
@dataclass
class Subtask:
id: str
description: str
task_type: str = ""
suggested_tools: List[str] = field(default_factory=list)
suggested_persona: str = ""
dependencies: List[str] = field(default_factory=list) # DAG的边
produces: List[str] = field(default_factory=list) # 产出数据
consumes: List[str] = field(default_factory=list) # 消费数据
4.3 Plan ≠ DAG
这是理解本章的关键区分:
Plan = 任务规划(做什么、按什么顺序做)
DAG = 任务执行图(如何编排执行、管理依赖)
Plan回答的问题是:"这个复杂任务应该拆成哪些子任务?"
DAG回答的问题是:"这些子任务应该怎么执行?哪些可以并行?哪些必须等前面的完成?"
二者的关系是:Plan定义了DAG的节点,DAG描述了Plan的执行拓扑。
在没有依赖关系时,Plan可以退化为简单的任务列表,执行方式可以是纯并行。在有复杂依赖关系时,DAG的价值才充分体现。
4.4 三种执行模式
工程实现中支持三种执行模式,对应不同复杂度的任务:
Parallel(并行)
所有子任务同时执行,适用于没有依赖关系的场景:
python
async def _execute_parallel(self, decomp, input, base_context, ...):
semaphore = asyncio.Semaphore(config.max_concurrency)
async def execute_single(task):
async with semaphore:
return await self._execute_single_agent(task, ...)
task_results = await asyncio.gather(
*[execute_single(task) for task in tasks],
return_exceptions=True
)
Sequential(顺序)
子任务按顺序执行,前序结果传递给后续任务:
python
async def _execute_sequential(self, decomp, input, base_context, ...):
for task in tasks:
if config.pass_previous_results and results:
accumulated_context["previous_results"] = [
{"task_id": r.agent_id, "response": r.response}
for r in results
]
result = await self._execute_single_agent(task, ...)
Hybrid(混合)
结合并行和顺序,按拓扑层级执行:
python
async def _execute_hybrid_tasks(self, tasks, ...):
in_degree = {t.id: len(t.dependencies) for t in tasks}
while len(results) < len(tasks):
ready_tasks = [
task_map[tid]
for tid, degree in in_degree.items()
if degree == 0 and tid not in results
]
# 当前层级并行执行
layer_results = await asyncio.gather(
*[execute_task(task) for task in ready_tasks]
)
# 更新下游任务的入度
for task_id, result in layer_results:
for dependent_id in dependents.get(task_id, []):
in_degree[dependent_id] -= 1
这是BFS拓扑排序的应用 ------ 每一层的任务并行执行,层与层之间顺序执行。
4.5 DAG验证:拓扑排序与Kahn算法
在执行之前,必须验证依赖图无环。Kahn算法是标准解法:
python
def _validate_dag_dependencies(self, decomp: DecompositionResult) -> bool:
# 构建邻接表和入度表
adj: Dict[str, List[str]] = {}
in_degree: Dict[str, int] = {}
for subtask in decomp.subtasks:
adj[subtask.id] = []
in_degree[subtask.id] = 0
for subtask in decomp.subtasks:
for dep in subtask.dependencies:
adj[dep].append(subtask.id)
in_degree[subtask.id] += 1
# Kahn算法
queue = [node for node, degree in in_degree.items() if degree == 0]
visited_count = 0
while queue:
node = queue.pop(0)
visited_count += 1
for neighbor in adj[node]:
in_degree[neighbor] -= 1
if in_degree[neighbor] == 0:
queue.append(neighbor)
# 访问节点数 ≠ 总节点数 → 有环
return visited_count == len(decomp.subtasks)
算法复杂度O(V+E)。如果检测到循环依赖,任务会直接拒绝执行,防止无限等待。
4.6 LangGraph实践
LangGraph 将DAG工作流的概念产品化。它允许开发者用Graph API定义Agent的执行流程:
- Node = 一个处理步骤(LLM调用、工具调用等)
- Edge = 步骤之间的流转(包括条件边)
LangGraph的StateGraph本质上就是一个支持条件分支的DAG,其运行时调度逻辑与本文的Hybrid模式高度相似。
4.7 Temporal实践
Temporal 是本文工程实现的底层编排引擎。它在DAG工作流中提供了:
- 持久化执行:工作流状态持久化,支持故障恢复
- 重试策略:每个Activity可以配置独立的重试策略
- 超时控制:workflow级别和activity级别的超时
- 信号机制:支持暂停/恢复/取消工作流
第五章 Reflection:让Agent学会自我优化
5.1 理论基础
Reflection模式的理论基础来自Shinn et al. (NeurIPS 2023)的 Reflexion: Language Agents with Verbal Reinforcement Learning。
核心流程:
Generate(生成初始答案)
↓
Critique(评估答案质量,指出问题)
↓
Revise(基于评估结果修改答案)
↓
Repeat until satisfied(重复直到质量达标)
不同于传统的RL需要数值奖励信号,Reflexion使用**语言反馈(verbal feedback)**作为改进信号。这使得Agent可以在没有显式奖励模型的情况下进行自我改进。
5.2 Reflection的三种流派
Self-Reflection(自我反思)
同一个模型
↓
生成答案
↓
反思自己的答案
↓
改进
最简单实现,但依赖模型自身的评估能力。问题是:一个会产生错误的模型,往往也不擅长发现自己的错误。
Verifier(验证器模式)
生成器(Generator)→ 生成答案
↓
验证器(Verifier)→ 独立评估,打分,指出问题
↓
修正器(Reviser)→ 根据反馈修正答案
通过角色分离提高评估的客观性。生成器和验证器可以使用不同的模型,甚至验证器可以使用更强大的模型。
Reward Model(奖励模型思路)
借鉴RLHF的思路,训练专门的奖励模型来评估输出质量:
答案 → Reward Model → 数值评分
↓
反馈给Generator
这是最工程化的方案,但需要额外的训练数据和模型。
5.3 工程实现
主反思循环
python
async def reflect_on_result(
query: str,
initial_result: str,
agent_results: List[AgentExecutionResult],
base_context: Dict[str, Any],
config: ReflectionConfig,
options: ReflectionOptions,
) -> Tuple[str, float, int, Optional[Exception]]:
核心循环逻辑:
python
while retry_count < config.max_retries:
# 评估当前结果
eval_result = await _evaluate_result(query, final_result, ...)
# 分数达标,直接返回
if eval_result.score >= config.confidence_threshold:
return final_result, eval_result.score, total_tokens, None
# 分数不达标,注入反馈重新生成
retry_count += 1
reflection_context["reflection_feedback"] = eval_result.feedback
reflection_context["previous_response"] = final_result
improved_synthesis = await _synthesize_with_feedback(
query, agent_results, context=reflection_context
)
final_result = improved_synthesis.final_result
Evaluate
python
async def _evaluate_result(query, response, criteria, timeout_ms):
eval_input = EvaluateResultInput(
query=query,
response=response,
criteria=criteria,
)
eval_result = await asyncio.wait_for(
_call_evaluate_activity(eval_input),
timeout=timeout_ms / 1000.0,
)
return eval_result
Feedback注入
python
reflection_context["reflection_feedback"] = eval_result.feedback
reflection_context["previous_response"] = final_result
reflection_context["improvement_needed"] = True
reflection_context["identified_issues"] = eval_result.issues
reflection_context["improvement_suggestions"] = eval_result.suggestions
Re-Synthesis
python
async def _synthesize_with_feedback(query, agent_results, context, parent_workflow_id):
synthesis_input = SynthesisInput(
query=query,
agent_results=agent_results,
context=context, # 包含反思反馈
)
return await _call_synthesis_activity(synthesis_input)
5.4 Reflection的局限
这是必须正视的问题:
LLM并不一定擅长评价自己的输出。
具体表现为:
- 过度自信:错误答案可能被评高分,因为模型缺乏识别自身错误的能力
- 循环改进失效:反馈和改进都在同一个错误范式内,导致"换汤不换药"
- 评估标准模糊:LLM评估缺乏客观锚点,容易受到表面特征(长度、格式)的影响
实际案例:
答案:量子计算是一种利用量子比特进行计算的技术。
评分:0.85 ← 模型认为质量不错
实际:回答过于笼统,遗漏了叠加态、纠缠等核心概念
因此,工程上建议:
- 评估阈值不要设置过高(0.7-0.8即可)
- 限制最大重试次数(2-3次),避免过度优化
- 对于关键场景,引入人工评估或规则校验作为补充
5.5 实际项目中的Reflection
OpenHands
Agent在修改代码后,会自动运行测试并检查结果。如果测试失败,Agent会分析错误信息并再次修改代码。这是一个闭环的Reflection过程。
Claude Code
在代码修改完成后,Claude Code会自我检查:
- 修改是否符合预期
- 是否引入了新的问题
- 是否有遗漏的边界情况
Cursor Agent
Cursor的Agent模式在生成代码后,会自动进行lint检查和类型检查,根据检查结果修正代码。
这些实际案例说明:Reflection最有价值的应用场景是"有客观验证手段的场景" ------ 测试、lint、类型检查等提供了独立于LLM判断的质量信号。
第六章 四种模式如何组合
这是全篇最值钱的一章。四种模式不是互斥的,而是可以按需组合。
6.1 决策树
需要解决的问题?
│
├─ 简单逻辑/数学问题
│ └─ CoT(Zero-shot即可)
│
├─ 需要外部信息/工具
│ └─ ReAct(思考 + 行动)
│
├─ 复杂多步骤任务
│ ├─ 无依赖关系 → Plan(并行模式)
│ └─ 有依赖关系 → Plan(Hybrid模式)+ ReAct Worker
│
└─ 对输出质量要求高
└─ 叠加 Reflection
6.2 组合模式
简单问题:CoT
User Query → CoT Prompt → Step-by-step Reasoning → Answer
适用:数学计算、逻辑推理、概念解释。
需要工具:ReAct
User Query →Reason → Act → Observe → Reason → ... → Synthesis → Answer
适用:研究型问题、需要实时数据的任务、代码调试。
复杂任务:Plan + ReAct
User Query
│
▼
Planner(分解任务)
│
├── Subtask 1 ── ReAct Worker ── Result 1
├── Subtask 2 ── ReAct Worker ── Result 2
└── Subtask 3 ── ReAct Worker ── Result 3
│
▼
Synthesis(综合结果)
│
▼
Answer
适用:市场调研、技术方案设计、多维度分析。
高质量输出:Plan + ReAct + Reflection
User Query
│
▼
Planner
│
▼
ReAct Workers(并行/混合执行)
│
▼
Synthesis
│
▼
Reflection(评估 → 反馈 → 改进)
│
▼
Final Answer
适用:正式报告、代码审查、生产级内容生成。
6.3 最终架构图
User Query
│
▼
┌──────────────────┐
│ Planner │ ← Plan: 任务分解
│ (复杂任务时启用) │
└──────┬───────────┘
│
▼
┌───────────────────────┐
│ ReAct Workers │ ← ReAct: 思考-行动-观察
│ ┌─────┐ ┌─────┐ │
│ │ W1 │ │ W2 │ ... │ ← DAG编排
│ └──┬──┘ └──┬──┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────┐ │
│ │ Synthesis │ │
│ └──────┬───────┘ │
└─────────┼────────────┘
│
▼
┌──────────────────┐
│ Reflection │ ← Reflection: 质量保证
│ (评估 → 反馈 → 改进)│
└────────┬─────────┘
│
▼
Final Answer
6.4 设计原则总结
- 按需组合,不要过度设计 ------ 简单问题不需要Plan + Reflection全家桶
- Plan定义What,DAG定义How ------ 规划和执行是两个独立关注点
- ReAct是通用执行单元 ------ 无论是单个任务还是Plan中的子任务,都可以用ReAct执行
- Reflection依赖客观验证 ------ 纯LLM自我评估有盲区,尽量结合测试、lint等外部信号
- CoT是所有模式的基础 ------ 无论哪种模式,内部的推理环节都可以受益于CoT
理论参考:
- Chain-of-Thought Prompting Elicits Reasoning in Large Language Models (Wei et al., NeurIPS 2022)
- ReAct: Synergizing Reasoning and Acting in Language Models (Yao et al., ICLR 2023)
- Self-Consistency Improves Chain of Thought Reasoning in Language Models (Wang et al., ICLR 2023)
- Plan-and-Solve Prompting (Wang et al., ACL 2023)
- Reflexion: Language Agents with Verbal Reinforcement Learning (Shinn et al., NeurIPS 2023)