前言

最近在学习 AI Agent 开发,用 PyCharm 通过 SSH 连接我的 Ubuntu 虚拟机,写了一个完全独立的 Agent 演示程序。过程中,我遇到了一个非常经典的问题:代码之前明明能跑,突然就报 No such file or directory 错误,折腾了很久才找到根源。本文就把这次踩坑经历和最终的解决方案分享出来,希望能帮到遇到同样问题的朋友。


一、我的开发环境

  • 本地 IDE:PyCharm(中文版)
  • 远程服务器:Ubuntu 26.04 LTS(虚拟机)
  • Python 环境:Conda 虚拟环境 ai_agent
  • 项目:一个无需任何外部库的纯 Python 实现的简单 Agent


二、那个让人崩溃的报错

我的代码本身是一个完全独立的 Agent,逻辑很简单,包含了计算、查时间、知识问答三个工具,用的都是 Python 标准库。

之前在 PyCharm 里通过 SSH 运行都好好的,突然就跑不起来了,报错信息如下:

bash

运行

/home/root/miniconda/envs/ai_agent/bin/python: can't open file '/home/main.py': [Errno 2] No such file or directory

我当时一脸问号:

  1. 代码没动过,为什么突然找不到文件了?
  2. PyCharm 右下角明明提示 “已上传 1 个文件”,文件去哪了?
  3. 为什么它会去 /home/main.py 找?这不是我项目的路径啊?


三、抽丝剥茧:问题根源分析

通过反复测试,我终于搞清楚了问题所在,是两个 “坑” 叠加了:

坑 1:PyCharm 的 SSH 临时目录是个 “定时炸弹”

PyCharm 通过 SSH 运行时,默认会把代码上传到虚拟机的 /tmp 临时目录下。

  • 问题/tmp 目录里的文件会被系统定期清理,SSH 会话超时也会被删掉。所以之前能跑,是因为文件还在;后来跑不了,是因为文件被删了。

坑 2:部署路径权限不足,文件根本没传上去

我在 PyCharm 里把部署路径设成了 /home/

  • 问题/home/ 目录需要管理员权限才能写入,我的普通用户 root 根本没有权限把文件传上去,所以 PyCharm 提示 “已上传” 是假的,文件实际上根本没传到服务器上。

这两个问题加在一起,就导致了 “以前能跑现在跑不了” 的玄学报错。


四、一劳永逸的解决方案

想要彻底解决这个问题,我们需要给 PyCharm 的项目找一个 “永久的家”,并改掉它的坏习惯。

步骤 1:在虚拟机里创建一个专属的固定目录

打开你的 Ubuntu 终端,执行以下命令,创建一个有权限、不会被清理的目录:

bash

运行

mkdir -p ~/pycharm_workspace

以后所有 PyCharm 项目都存这里,再也不用 /tmp 临时目录了。

步骤 2:在 PyCharm 里修改部署路径

  1. 打开 文件 → 设置 → 构建、执行、部署 → 部署
  2. 选中你的 SSH 连接,切换到 映射 标签页
  3. 按下面的方式修改:
    • 本地路径:你的电脑项目文件夹,比如 D:\demo1\project1
    • 服务器上的部署路径/home/root/pycharm_workspace/
    • Web 路径 URL:留空即可
  4. 点击 确定 保存。

步骤 3:手动上传文件到服务器

右键点击你的项目文件夹,选择 部署 → 上传到 xxx,把代码同步到虚拟机的固定目录里。

步骤 4:锁定运行配置,让 PyCharm 别再乱跑

  1. 点击右上角运行按钮旁边的下拉箭头 → 编辑配置
  2. 选中你的 main 配置,修改以下三项:
    • 脚本路径/home/root/pycharm_workspace/main.py
    • 工作目录/home/root/pycharm_workspace/
    • Python 解释器:确认是你的 ai_agent 虚拟环境,路径是 /home/root/miniconda/envs/ai_agent/bin/python
  3. 点击 应用 → 确定


五、我的 Agent 演示代码(附)

下面就是我这次运行的完整 Agent 代码,纯 Python 实现,无需任何外部库,直接复制就能跑。

python

运行

#!/usr/bin/env python3# -*- coding: utf-8 -*-"""

简单的Agent演示 - 完全独立版本

无需任何外部库,直接运行

"""

import refrom datetime import datetimefrom typing import Optional, List, Any

# ========== 定义工具函数 ==========

def calculator(expression: str) -> str:

    """执行数学计算"""

    try:

        # 安全的计算

        result = eval(expression, {"__builtins__": {}}, {})

        return f"✅ 计算结果: {result}"

    except Exception as e:

        return f"❌ 计算错误: {e}"

def get_current_time() -> str:

    """获取当前时间"""

    now = datetime.now()

    return f"�� {now.strftime('%Y-%m-%d %H:%M:%S')}"

def search_knowledge(query: str) -> str:

    """知识搜索"""

    knowledge_base = {

        "langchain": "LangChain是一个用于开发由语言模型驱动的应用程序的框架",

        "python": "Python是一种高级、解释型的编程语言,以其简洁易读的语法著称",

        "ai": "人工智能是计算机科学的一个分支,致力于创建能够执行通常需要人类智能的任务的系统",

        "机器学习": "机器学习是AI的一个子领域,让计算机通过数据学习而无需明确编程",

        "深度学习": "深度学习是机器学习的一个分支,使用多层神经网络",

        "北京": "北京是中国的首都,也是政治、文化中心",

        "上海": "上海是中国的经济中心和国际大都市",

        "天气": "抱歉,我暂时无法查询实时天气信息,建议查看天气预报应用",

    }

    query_lower = query.lower()

    for key, value in knowledge_base.items():

        if key in query_lower:

            return f"�� {value}"

    return f"❓ 关于'{query}'的搜索结果:暂无相关信息"

# ========== Agent类定义 ==========

class SimpleAgent:

    """简单但完整的Agent实现"""

    def __init__(self):

        self.tools = {

            "calculator": {

                "func": calculator,

                "description": "执行数学计算",

                "keywords": ["计算", "算", "加", "减", "乘", "除", "+", "-", "*", "/", "等于"]

            },

            "time": {

                "func": get_current_time,

                "description": "获取当前时间",

                "keywords": ["时间", "几点", "现在", "当前", "现在几点"]

            },

            "search": {

                "func": search_knowledge,

                "description": "搜索知识信息",

                "keywords": ["是什么", "什么是", "介绍", "信息", "知识", "告诉我"]

            }

        }

    def choose_tool(self, user_input: str):

        """根据用户输入选择合适的工具"""

        user_input_lower = user_input.lower()

        # 优先级:计算 > 时间 > 搜索

        if any(k in user_input_lower for k in self.tools["calculator"]["keywords"]):

            if re.search(r'\d+[\+\-\*/]\d+', user_input):

                return "calculator", self.tools["calculator"]["func"]

        if any(k in user_input_lower for k in self.tools["time"]["keywords"]):

            return "time", self.tools["time"]["func"]

        return "search", self.tools["search"]["func"]

    def extract_expression(self, user_input: str) -> str:

        """从用户输入中提取数学表达式"""

        patterns = [

            r'(\d+\s*[\+\-\*/]\s*\d+)',

            r'(\d+\s*[\+\-\*/]\s*\d+\s*[\+\-\*/]\s*\d+)',

        ]

        for pattern in patterns:

            match = re.search(pattern, user_input)

            if match:

                return match.group(1)

        numbers = re.findall(r'[\d+\-\*/]+', user_input)

        if numbers:

            return numbers[0].strip()

        return ""

    def process(self, user_input: str) -> str:

        """处理用户输入并返回结果"""

        print(f"�� Agent正在思考...")

        tool_name, tool_func = self.choose_tool(user_input)

        print(f"�� 选择工具: {tool_name}")

        try:

            if tool_name == "calculator":

                expression = self.extract_expression(user_input)

                if expression:

                    print(f"�� 计算表达式: {expression}")

                    result = tool_func(expression)

                else:

                    result = "❌ 无法识别计算表达式,请使用 + - * / 运算符"

            elif tool_name == "time":

                result = tool_func()

            else:

                result = tool_func(user_input)

            return result

        except Exception as e:

            return f"❌ 执行出错: {e}"

# ========== 演示函数 ==========

def simple_agent_demo():

    """运行简单的Agent演示"""

    print("=" * 60)

    print("简单Agent演示 - 完全独立版本(无需安装任何库)")

    print("=" * 60)

    print()

    agent = SimpleAgent()

    test_questions = [

        "现在几点了?",

        "帮我计算 15 + 27 等于多少",

        "什么是LangChain?",

        "介绍一下Python语言",

        "100 除以 4 加上 25 等于多少?",

        "北京和上海有什么信息?",

        "今天天气怎么样?",

        "1 + 2 * 3 等于多少",

    ]

    print("开始测试Agent:\n")

    for i, question in enumerate(test_questions, 1):

        print(f"�� 用户问题 {i}: {question}")

        print("-" * 40)

        result = agent.process(question)

        print(f"�� Agent回复: {result}")

        print()

        print("-" * 60)

        print()

    print("=" * 60)

    print("演示结束!")

    print()

if __name__ == "__main__":

    simple_agent_demo()


六、总结与避坑指南

这次经历让我明白,PyCharm 的远程开发虽然方便,但也要注意它的一些 “坏习惯”。为了避免以后再遇到类似问题,我总结了几条避坑指南:

  1. 拒绝临时目录:永远不要把项目同步到 /tmp 目录,一定要用固定目录。
  2. 注意权限问题:部署路径必须是你有权限写入的用户目录,比如 /home/你的用户名/xxx
  3. 运行配置写死路径:不要让 PyCharm 自动生成脚本路径,手动指定服务器上的固定路径。
  4. 养成好习惯:修改代码后,先右键上传,再运行,确保代码同步。

希望这篇分享能帮到和我一样遇到问题的朋友,也祝大家的 AI Agent 开发之路一路顺畅!


写在最后

如果你也在用 PyCharm 做远程开发,遇到了类似的问题,欢迎在评论区交流讨论。如果这篇文章帮到了你,别忘了点赞收藏哦!

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐