从零实现 ReAct
不使用 LangChain 编写一个 100 行的 Python 实现:解析行动行、运行工具,并循环直到得到最终答案。
从零实现 ReAct 是 CoddyKit 上的免费 AI Agents 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Agents 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Agents 课程共包含 4 节课。
本课时的部分内容尚未翻译,以英文显示。
亲自构建循环
您可以用约 100 行 Python 编写 ReAct,无需任何框架。亲自完成一次后,您就能直观理解框架抽象掉了哪些内容。
Step 1: Define Tools
import json, math
def calculator(expression: str) -> str:
try:
return str(eval(expression, {'__builtins__': {}}, vars(math)))
except Exception as e:
return f'Error: {e}'
def search_wikipedia(query: str) -> str:
# placeholder — call a real search API
return f'Wikipedia summary for: {query}'
TOOLS = {
'calculator': calculator,
'search_wikipedia': search_wikipedia,
}
print(calculator('2 + 2 * sqrt(16)'))
print(search_wikipedia('agents'))
Step 2: Tool Schemas
schemas = [
{'type': 'function', 'function': {
'name': 'calculator',
'description': 'Evaluate a math expression like 2 + 2 * sqrt(16)',
'parameters': {'type': 'object', 'properties': {'expression': {'type': 'string'}}, 'required': ['expression']}
}},
{'type': 'function', 'function': {
'name': 'search_wikipedia',
'description': 'Search Wikipedia and return a summary',
'parameters': {'type': 'object', 'properties': {'query': {'type': 'string'}}, 'required': ['query']}
}}
]
import json
print(json.dumps(schemas, indent=2))
Step 3: System Prompt
system = '''
You are a research assistant. Use the available tools when needed.
Think step by step. If you have enough information, give a final answer.
'''
print(system.strip())
Step 4: The Loop
from openai import OpenAI
client = OpenAI()
def react(question, max_steps=10):
messages = [
{'role': 'system', 'content': system},
{'role': 'user', 'content': question}
]
for step in range(max_steps):
r = client.chat.completions.create(
model='gpt-4o-mini',
messages=messages,
tools=schemas,
)
msg = r.choices[0].message
messages.append(msg)
if not msg.tool_calls:
return msg.content
for tc in msg.tool_calls:
args = json.loads(tc.function.arguments)
try:
result = TOOLS[tc.function.name](**args)
except Exception as e:
result = f'Tool error: {e}'
messages.append({'role': 'tool', 'tool_call_id': tc.id, 'content': str(result)})
return 'Step limit reached.'Step 5: Run It
answer = react('What is the population of Tokyo times the square root of pi?')
print(answer)第 6 步:添加日志记录
记录每一步,以便调试:
def react_verbose(question, max_steps=10):
messages = [...]
for step in range(max_steps):
r = client.chat.completions.create(model='gpt-4o-mini', messages=messages, tools=schemas)
msg = r.choices[0].message
print(f'[step {step}] thought: {msg.content}')
if msg.tool_calls:
for tc in msg.tool_calls:
print(f'[step {step}] action: {tc.function.name}({tc.function.arguments})')
...第 7 步:将步骤计数器作为工具
有些代理会在系统提示词中包含步骤计数,让模型知道何时应该收敛:
system = f'You have at most {MAX_STEPS} steps. Step {current_step}/{MAX_STEPS}. ...'第 8 步:最终答案格式
如果您需要结构化输出,可以强制执行一次最终工具调用:
tools.append({'type': 'function', 'function': {
'name': 'final_answer',
'description': 'Submit the final answer to the user.',
'parameters': {'type': 'object', 'properties': {'answer': {'type': 'string'}}, 'required': ['answer']}
}})
# Loop terminates when final_answer is called.第 9 步:工具错误
始终将错误作为工具结果返回,以便代理恢复:
try:
result = TOOLS[name](**args)
except Exception as e:
result = f'TOOL ERROR: {type(e).__name__}: {e}'
# Model sees the error and can try a different approach.第 10 步:并行工具调用
如果 msg.tool_calls 包含多个条目,请并行运行它们:
import asyncio
async def run_tools(tool_calls):
async def run_one(tc):
args = json.loads(tc.function.arguments)
return tc.id, TOOLS[tc.function.name](**args)
return await asyncio.gather(*[run_one(tc) for tc in tool_calls])第 11 步:限制对话长度
即使在 MAX_STEPS 之内,消息列表也可能急剧膨胀。请在轮次之间按令牌数量进行裁剪:
if total_tokens(messages) > 6000:
messages = trim_messages(messages)第 12 步:生产环境强化
在生产环境中,请添加:工具调用超时、每个工具的配额、API 失败时采用退避策略的重试,以及完整的追踪日志。但上面的循环就是您的骨架。
工具错误处理
工具引发异常时,您应该怎么做?
回顾
约 80 行代码即可实现 ReAct:消息列表 + while 循环 + 分发字典。框架增加了完善功能,但核心就是这些。
常见问题解答
「从零实现 ReAct」课时是免费的吗?
是的 — 「从零实现 ReAct」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Agents 课程的其余内容,请升级到 CoddyKit PRO。 AI Agents 课程共包含 4 节课。
「从零实现 ReAct」这节课中我会学到什么?
不使用 LangChain 编写一个 100 行的 Python 实现:解析行动行、运行工具,并循环直到得到最终答案。 你通过在浏览器中直接运行的动手代码来练习 AI Agents,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 AI Agents 需要有经验吗?
无需任何先前经验。CoddyKit 上的 AI Agents 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「从零实现 ReAct」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 AI Agents 课中编写并运行代码吗?
能。每节 AI Agents 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。