这是之前的一篇:使用LangChain框架搭建入门智能体。
本篇通过 LangChain 以及其中的 PythonREPLTool 工具,结合提示词,实现代码的自动运行测试。这里仍然以阿里云百炼的通义千问 API 为例(API 需要付费,可能有一定量的免费额度)。
安装软件包:
pip install langchain langchain-openai
pip install langchain-community
pip install langchain-experimental
pip install python-dotenv
设置环境,用于获取 key。新建 .env 文件,输入以下内容(API KEY 需要到阿里云百炼获取):
OPENAI_API_KEY=xxx
DASHSCOPE_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
智能体代码文件 langchain_running_code.py:
"""
This code is supported by the website: https://www.guanjihuan.com
The newest version of this code is on the web page: https://www.guanjihuan.com/archives/47925
"""
import os
import dotenv
from langchain_openai import ChatOpenAI
from langchain.agents import create_react_agent, AgentExecutor
from langchain_core.prompts import PromptTemplate
from langchain_experimental.tools import PythonREPLTool
# 加载环境变量
dotenv.load_dotenv()
# 初始化 LLM
llm = ChatOpenAI(
    api_key=os.getenv("OPENAI_API_KEY"),
    base_url=os.getenv("DASHSCOPE_BASE_URL"),
    model="qwen-plus",
    temperature=0,
)
# 使用官方 PythonREPLTool(⚠️ 注意:此工具可执行任意代码,仅用于安全环境)
tools = [PythonREPLTool()]  # 直接实例化即可,它已是 Tool 类型
# 构建 ReAct Prompt
template = """你是一个严谨的 Python 编程助手,必须通过工具执行代码来验证逻辑,不能仅靠推理得出结论。
## 工具
你可以使用以下工具:
{tools}
## 规则
- 每次只能执行一个 Action。
- 所有 Python 代码必须通过工具执行,不得假设输出结果。
- **Action Input 必须是纯 Python 代码,不要包含 Markdown 代码块符号(如 ``` 或 ```python)。**
- 如果测试失败(如 assert 报错),请根据错误信息修正代码并重新测试。
- 最终答案必须基于工具返回的正确执行结果。
- 输出必须严格遵循以下格式,不要添加额外内容。
Question: <用户问题>
Thought: <你的思考>
Action: <工具名称>
Action Input: <纯 Python 代码(不要 Markdown 代码块)>
Observation: <工具返回结果>
...(重复以上步骤)
Final Answer: <最终答案,包含正确函数和简要说明>
## 可用工具
{tool_names}
当前问题: {input_message}
{agent_scratchpad}"""
prompt = PromptTemplate.from_template(template)
# 创建并执行 Agent
agent = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,
    max_iterations=10,
    handle_parsing_errors=True
)
# 运行任务
if __name__ == "__main__":
    response = executor.invoke({
        "input_message": "请编写一个 Python 函数 fibonacci(n),返回第 n 个斐波那契数。测试通过后做代码的优化,并给出最终代码。"
    })
    print(response["output"])
运行结果:
> Entering new AgentExecutor chain...
Question: 请编写一个 Python 函数 fibonacci(n),返回第 n 个斐波那契数。测试通过后做代码的优化,并给出 最终代码。
Thought: 首先,我将编写一个基础版本的 fibonacci(n) 函数,使用递归方法实现。然后通过工具执行并测试小数值 n=5 是否正确。
Action: Python_REPL
Action Input: 
def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(5))Python REPL can execute arbitrary code. Use with caution.
5
Question: 请编写一个 Python 函数 fibonacci(n),返回第 n 个斐波那契数。测试通过后做代码的优化,并给出 最终代码。  
Thought: 基础递归版本在 n=5 时输出正确(期望值为 5)。现在测试更大的值 n=10 并检查性能和正确性。  
Action: Python_REPL  
Action Input:  
print(fibonacci(10))  55
Question: 请编写一个 Python 函数 fibonacci(n),返回第 n 个斐波那契数。测试通过后做代码的优化,并给出 最终代码。  
Thought: 基础递归版本在 n=10 时输出正确(期望值为 55)。但递归方法对大数值效率低,存在重复计算。现在 优化为使用动态规划(记忆化)方法避免重复计算。  
Action: Python_REPL  
Action Input:  
def fibonacci(n):  
    if n <= 1:  
        return n  
    dp = [0] * (n + 1)  
    dp[1] = 1  
    for i in range(2, n + 1):  
        dp[i] = dp[i-1] + dp[i-2]  
    return dp[n]  
print(fibonacci(10))  55
Question: 请编写一个 Python 函数 fibonacci(n),返回第 n 个斐波那契数。测试通过后做代码的优化,并给出 最终代码。  
Thought: 动态规划版本在 n=10 时输出正确(55)。现在测试更大的值 n=35 并验证性能和正确性。  
Action: Python_REPL  
Action Input:  
print(fibonacci(35))  9227465
Question: 请编写一个 Python 函数 fibonacci(n),返回第 n 个斐波那契数。测试通过后做代码的优化,并给出 最终代码。  
Thought: 动态规划版本在 n=35 时输出正确(9227465),且性能良好。当前实现已避免重复计算,但可进一步优 化空间复杂度。由于我们只需要前两个值,可以使用滚动变量代替整个数组。  
Action: Python_REPL  
Action Input:  
def fibonacci(n):  
    if n <= 1:  
        return n  
    a, b = 0, 1  
    for i in range(2, n + 1):  
        a, b = b, a + b  
    return b  
print(fibonacci(35))  9227465
Question: 请编写一个 Python 函数 fibonacci(n),返回第 n 个斐波那契数。测试通过后做代码的优化,并给出 最终代码。  
Thought: 空间优化后的滚动变量版本在 n=35 时输出正确(9227465),且时间与空间效率均优。现在测试边界情 况 n=0 和 n=1 以确保正确性。  
Action: Python_REPL  
Action Input:  
print(fibonacci(0), fibonacci(1))  0 1
Question: 请编写一个 Python 函数 fibonacci(n),返回第 n 个斐波那契数。测试通过后做代码的优化,并给出 最终代码。  
Thought: 空间优化后的滚动变量版本在 n=0 和 n=1 时输出正确(0 和 1),且在 n=35 时也正确。说明函数已正确处理边界和一般情况。现在进行最终验证,测试多个值:n=0, 1, 5, 10, 35。  
Action: Python_REPL  
Action Input:  
print(fibonacci(0), fibonacci(1), fibonacci(5), fibonacci(10), fibonacci(35))  0 1 5 55 9227465
Question: 请编写一个 Python 函数 fibonacci(n),返回第 n 个斐波那契数。测试通过后做代码的优化,并给出 最终代码。  
Thought: 所有测试用例(n=0, 1, 5, 10, 35)均输出正确结果:0, 1, 5, 55, 9227465。最终版本使用滚动变量 优化了空间复杂度至 O(1),时间复杂度为 O(n),且逻辑正确。  
Final Answer: 最终优化后的 fibonacci(n) 函数如下:
```python
def fibonacci(n):
    if n <= 1:
        return n
    a, b = 0, 1
    for i in range(2, n + 1):
        a, b = b, a + b
    return b
```
该函数通过维护两个变量 a 和 b 滚动更新前两个斐波那契数,避免了递归重复计算和数组存储开销,具有最优的 时间 O(n) 和空间 O(1) 复杂度。已验证在多个输入下结果正确。
> Finished chain.
最终优化后的 fibonacci(n) 函数如下:
```python
def fibonacci(n):
    if n <= 1:
        return n
    a, b = 0, 1
    for i in range(2, n + 1):
        a, b = b, a + b
    return b
```
该函数通过维护两个变量 a 和 b 滚动更新前两个斐波那契数,避免了递归重复计算和数组存储开销,具有最优的 时间 O(n) 和空间 O(1) 复杂度。已验证在多个输入下结果正确。
		【说明:本站主要是个人的一些笔记和代码分享,内容可能会不定期修改。为了使全网显示的始终是最新版本,这里的文章未经同意请勿转载。引用请注明出处:https://www.guanjihuan.com】