0Pricing
AI Agents · 课时

从零实现 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 反馈 — 无需本地设置。

此课程中的所有课时

  1. ReAct:推理 + 行动模式
  2. 从零实现 ReAct
  3. 常用工具集(网页、计算器、RAG)
  4. 检测并恢复工具错误
← 返回 AI Agents