从玄学报错到丝滑运行:我的 PyCharm + Conda + Ubuntu AI Agent 踩坑全记录
文章摘要: 本文分享了作者在使用PyCharm进行SSH远程开发时遇到的"Nosuchfileordirectory"错误排查过程。问题根源在于PyCharm默认将代码上传到/tmp临时目录(会被系统定期清理)且/home目录权限不足。作者提供了完整的解决方案:1)创建固定工作目录~/pycharm_workspace;2)修改PyCharm部署路径;3)手动上传文件;4)锁定
前言
最近在学习 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
我当时一脸问号:
- 代码没动过,为什么突然找不到文件了?
- PyCharm 右下角明明提示 “已上传 1 个文件”,文件去哪了?
- 为什么它会去 /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 里修改部署路径
- 打开 文件 → 设置 → 构建、执行、部署 → 部署
- 选中你的 SSH 连接,切换到 映射 标签页
- 按下面的方式修改:
- 本地路径:你的电脑项目文件夹,比如 D:\demo1\project1
- 服务器上的部署路径:/home/root/pycharm_workspace/
- Web 路径 URL:留空即可
- 点击 确定 保存。
步骤 3:手动上传文件到服务器
右键点击你的项目文件夹,选择 部署 → 上传到 xxx,把代码同步到虚拟机的固定目录里。
步骤 4:锁定运行配置,让 PyCharm 别再乱跑
- 点击右上角运行按钮旁边的下拉箭头 → 编辑配置
- 选中你的 main 配置,修改以下三项:
- 脚本路径:/home/root/pycharm_workspace/main.py
- 工作目录:/home/root/pycharm_workspace/
- Python 解释器:确认是你的 ai_agent 虚拟环境,路径是 /home/root/miniconda/envs/ai_agent/bin/python
- 点击 应用 → 确定。
五、我的 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 的远程开发虽然方便,但也要注意它的一些 “坏习惯”。为了避免以后再遇到类似问题,我总结了几条避坑指南:
- 拒绝临时目录:永远不要把项目同步到 /tmp 目录,一定要用固定目录。
- 注意权限问题:部署路径必须是你有权限写入的用户目录,比如 /home/你的用户名/xxx。
- 运行配置写死路径:不要让 PyCharm 自动生成脚本路径,手动指定服务器上的固定路径。
- 养成好习惯:修改代码后,先右键上传,再运行,确保代码同步。
希望这篇分享能帮到和我一样遇到问题的朋友,也祝大家的 AI Agent 开发之路一路顺畅!
写在最后
如果你也在用 PyCharm 做远程开发,遇到了类似的问题,欢迎在评论区交流讨论。如果这篇文章帮到了你,别忘了点赞收藏哦!
更多推荐




所有评论(0)