当 DeepSeek 接管操作系统:智能体(Agent)真能让程序员提前退休?

“DeepSeek R1” 刚上线时,就在全球范围内刮起了一股新的智能对话风潮。它看起来“好像什么都知道”,但在使用中,人们也会碰到重复 Debug、测试琐碎、对话失控等常见问题。想象一下,如果 DeepSeek 不仅会回答问题,还能像一位开发者那样主动编写代码、编译测试、排查故障,并给出最终的总结报告——那将是多么理想的场景。

正因如此,我对“Agent 智能体”的概念产生了兴趣,开始加入相关的探索和研究。在社区里,“Agent”早已是一个热门话题,简单来说,Agent 的目标就是让大模型从“聊天式交互”进化到“帮助执行实际开发和操作”的高级阶段。

image.png

一、为什么要打造 Agent?

在我的 DEMO 项目中,我尝试给 DeepSeek 一个更“真实”的工作环境,让它能直接用到电脑上的一些资源(比如文件系统、编译器、Shell 命令等),从而充分发挥大模型的潜力。可这样一来,新的问题也随之出现,包括但不限于:

  • 安全风险:当 Agent 有了较高的权限,就有可能在无意或恶意的情况下执行危险操作。因此,访问控制和审计成为首要课题。
  • 误读与幻觉(Hallucination):如果上下文信息过于复杂,或模型没理解清楚,就有可能读错指令,甚至“编故事”,在关键任务中会带来严重后果。
  • 远程 API 不稳定:如果推理过程依赖外部服务,一旦网络波动或服务故障,Agent 的核心功能就可能瘫痪,需要额外的重试和容错方案。
  • Prompt 编写困难:软指导(Prompt)是让 Agent 发挥创造力的关键,但写得不好就会导致输出混乱,甚至陷入无限循环。
  • 格式约束与结果校验:如果 Agent 的输出格式不符合要求,就会影响后续流程。针对每一步结果进行自动校验也并非易事。
  • 扩展性与工程维护:要让 Agent 支持更多的领域和场景,就得有更健壮的模型和更完善的状态管理,这对代码架构提出了相当的要求。

关于这些新问题的几点思考与应对思路

其实,“为什么要打造 Agent”从来不是为了让人类开发者“退出舞台”,而是希望以自动化的方式分担那些琐碎、重复、低产出的工作,让人类可以更专注于创造性的部分。与此同时,这些新问题也提醒我们,Agent 并非“唤醒就能自由工作”的魔法师,它更像是一个有超强“潜力”的实习生,需要配套的工作规范与安全限制,才能在实际开发和运维中放心使用。

  • 权限与监控:通过权限沙盒、审计日志等机制,将 Agent 的权限精细化管控,不放大安全风险。
  • Prompt 策略:为 Agent 设计好提示语的结构与流程,辅以简明、稳定的状态管理,让对话在可控边界内展开,避免死循环或产生危险命令。
  • 模型与上下文管理:根据任务重要性选择模型规模与上下文策略,既不过度依赖外部服务,也避免一次丢给 Agent 大量不必要的信息,从而降低“编故事”的概率。
  • 持续迭代与落地:对于工程级别的 Agent,需要在架构、测试、监控、上线等环节持续投入,并围绕扩展性和可维护性做专门设计。

只有在充分重视这些问题的情况下,Agent 才能真正释放大模型的潜能,帮助开发者摆脱机械繁琐的任务,向更高层次的创造性工作进阶。

二、我在测试不同模型时的实践与心得

1. Agent 就像个小程序员,但也会“偷懒”和“犯错”

  • 不管模型大小如何,大模型在功能上确实像个非常聪明的开发者,可以帮你写代码、调试、测试——可有时也会忽视提示,或者在同一个问题上反复纠缠。
  • 这时候就需要我们在“软提示”(Prompt)和“硬编码流程”之间找到平衡。Prompt 提供灵活度和创造力,而状态机或其它逻辑约束则帮助避免死循环或危险行为。

2. 本地 GPU 部署:2080Ti + 32B 模型

  • 我尝试在一块 2080Ti (22G 魔改版)显卡上本地部署了一个 32B(320 亿参数)的模型,比如  deepseek-r1:32b-q4-8k  或类似版本(iq4-10k  等)。
  • 为了让大模型能在有限显存上跑起来,需要用到低比特量化(Q4、Q6、INT4 等),牺牲一定精度来换取显存与算力的平衡。
  • 本地部署的好处是可以离线跑,不担心网络延迟和第三方服务故障;但受限于显存和硬件算力,推理速度、上下文长度都需要在效率和效果之间做权衡。

3. 远程调用:多种 API、多种模型参数与上下文配置

  • 我也在配置文件里尝试了各种远程模型,包括:
  • deepseek-ai/DeepSeek-R1deepseek-ai/DeepSeek-R1-Distill-Qwen-32Bdeepseek-ai/DeepSeek-R1-Distill-Llama-70B-free  等。
  • Qwen 系列模型,如  Qwen2.5-7B-InstructQwen2.5-72B-Instruct-128K
  • 量化版本如  qwen2.5-32b-iq4-10k:latest  或  phi-4:q6-24k
  • 以及类似  gpt-4o  这样的 API 接口版本。
  • 这些模型的参数规模从 7B(70 亿)到 70B(700 亿)不等,所能支持的上下文长度也从 2K、8K、32K 到 128K 各有差异。
  • 远程服务虽然部署了更强的硬件和更大参数量模型,但一旦网络波动或服务本身不稳定,就可能导致 Agent 推理卡顿或超时,需要在代码中增加重试和断路保护。

4. 上下文不是越多越好

  • 尽管大模型往往宣传“上下文窗口很大”,但是如果给出的背景或指令太复杂,模型出现误读或“编故事”的几率也会上升。
  • 我测试过 32k、8k、128k 等不同上下文模型,都发现上下文过多时,出现失误或反常输出的概率也会上升。

5. 大框架未必是最佳实践

  • 我最初尝试了 langchain,但因其不支持流式输出,又重写了一套支持流式输出的 LLM 请求机制。
  • 同时,我采用状态机逻辑来管理 Agent 的流程,每次请求都相对独立,结果是几乎没用到 langchain 其他功能。
  • 由此也开始思考:或许直接基于 OpenAI API 或类似的低层接口,从零搭建“简易框架”就够用了。很多“通用大框架”虽然概念丰富,但实际工程里未必完全适配。

三、为什么说 LLM 不需要大而全的“万能框架”?

其实,LLM 的应用往往面向细分场景,在不同业务部门或技术领域都存在大量个性化需求。一个“大而全”的通用框架看似可以“一次性打包所有功能”,但往往在实际落地时会出现过度耦合、配置复杂度高、模块臃肿等问题,不见得能满足所有场景,反而拖慢开发效率。

因此,“细颗粒度、灵活组合”的思路才更能激发大模型的潜力:让它专注在当前场景需要的功能上,然后用最小可行架构将其封装到业务流中。最简单的方式,就是在 LLM 之上构建一个带决策机制的状态机流程编排:为每一个可预期的步骤和异常处理定义好状态转移逻辑,再通过 Prompt 或 API 调用触发对应环节。这种结构清晰、维护简单、可随时扩展,正是许多实际项目快速迭代的实践经验。而且对于团队而言,不同阶段或场景所需的“插件”也能更灵活地接入,不必被一个庞大的框架牵着走。

四、初步 DEMO 展示

经过一周左右的探索,我基于 DeepSeek 做了两个 DEMO,用来展示如何解决或部分缓解上述问题。这些 DEMO 仅作为学习和讨论用,离实用工具还有相当距离。

1. Python -> C 自动转换 DEMO

Python 代码编写简单、灵活,但性能不足。如果能“一键”把 Python 代码转成对等功能的 C 程序,并自动完成编译和测试,最后在 Python 里通过接口调用这个 C 库,将显著提升开发效率和部署速度。
在这个 DEMO 中,我尝试了如下流程:

  1. 解析指定的 Python 脚本;
  2. 调用 DeepSeek 生成对应的 C 代码;
  3. 自动编译生成的 C 代码;
  4. 运行测试并输出性能或结果报告;
  5. 将 C 库再次封装给 Python 使用。

目前只实现了简单的函数级转换。如果遇到第三方库或更复杂的逻辑,还需要更深入的兼容适配。但它为自动化移植与测试提供了一个雏形,一旦与日常开发结合,可减少大量繁琐重复的工作。

具体流程如下:

image.png

  1. 初始化阶段(INIT)
    流程从初始状态开始,系统准备好必要的环境和文件,进入代码生成阶段。
  2. 代码生成(CODE_GEN)
    在该阶段,流水线调用 LLM(大语言模型)生成对应的 C 代码,并将生成的 C 代码写入到文件中。此步骤决定了后续操作的基础,因此生成的代码质量至关重要。
  3. 测试脚本生成(TEST_GEN)
    随后,系统利用 LLM 生成测试脚本,该脚本用于对生成的 C 代码进行功能验证。测试脚本同样经过清洗和格式化,确保测试环境能正确加载并执行。
  4. 编译与测试(COMPILE_TEST)
    系统保存原始 Python 输入代码后,调用编译器对生成的 C 代码进行编译,并执行测试。此阶段的输出为验证代码正确性的关键依据。
  5. 最终报告生成(FINAL_REPORT)
    根据编译和测试的结果,流水线再次调用 LLM 生成最终评估报告。解析报告后,系统会检查报告中 “correctness” 字段是否为  True,从而决定是否进入完成状态或进行重试。
  6. 重试机制(RETRY)
    如果最终报告表明转换结果不符合预期,系统将增加重试次数,记录之前的尝试信息(包括 C 代码、测试脚本、编译测试输出和评估报告),并回到代码生成阶段重新执行转换。这个机制确保了在出现错误时可以多次修正,争取达到正确转换的效果。
  7. 完成(COMPLETED)
    当生成的 C 代码通过所有测试和评估,且最终报告确认正确性后,系统构造最终返回结果,流程进入完成状态,整个转换过程结束。

2. 文件漫游(File System Explorer) DEMO

在这个场景下,Agent 拥有一定的文件系统访问权限(如执行  lspwdcat  等指令)。它可以自动定位并浏览文件,自发记录笔记、总结内容,并尽量避免对同一个文件进行重复操作或重复总结。
如果工作流程中常要检索海量文件并做周期性的分析或汇总,这样的 Agent 能帮忙显著降低人工操作量,提高效率。它展示了 Agent 的“主动决策”和“资源利用”能力,具备一定的自我迭代和记录机制。

Agent 首先会从初始状态(BotState.INIT)开始,获取当前工作目录,并执行一系列基础命令,以探索项目文件结构并查看部分文件内容。这个过程中,Agent 的操作步骤和决策逻辑大致如下:

  1. 初始阶段(BotState.INIT):
    Agent 获取工作目录以及项目的初始状态。此时,系统会输出相关日志,记录当前工作目录和文件结构信息,为后续操作提供上下文数据。
  2. 决策下一步(BotState.DECIDE_NEXT):
    在决策阶段,Agent 根据当前操作结果和日志输出,决定下一步是继续执行命令、重新生成笔记,还是直接结束整个流程。决策结果同样会记录日志,帮助理解 Agent 的思考过程。
  3. 执行基础命令(BotState.EXEC_COMMAND):
    接下来,Agent 会执行如  lscatcd  等命令,以获取目录列表和文件内容。这些操作会生成对应的日志输出,直观展示 Agent 如何探索项目文件结构以及查看关键文件内容。
  4. 笔记写入(BotState.WRITE_NOTE):
    根据用户输入或执行结果,Agent 可能需要生成和保存笔记,以记录操作过程中获得的重要信息。如果笔记写入成功,则会进入决策阶段;如果写入过程中出现错误且重试次数未达上限,Agent 会进行重试。
  5. 流程结束(BotState.COMPLETED):
    当所有操作完成,且决策结果为“complete”时,Agent 进入结束状态,整个流程随之结束。

image.png

五、DEMO 运行示例及结果

以下是一些运行的过程,以便更直观地展示两个 DEMO 的实际运行过程和输出。

1. Python -> C 自动转换 DEMO 运行过程

本次 DEMO 展示了从 Python 代码自动转换为 C 代码的完整流水线,整个过程由多个状态依次推进,并在必要时进行重试以确保转换效果。本次测试使用的模型是  DeepSeek-V3 ,推理服务器是硅基流动,通过这个链接你也可以免费领取到 20 万 token。

https://cloud.siliconflow.cn/...

本地测试使用过相对较好的的模型是  qwen2.5:32b-iq410k  上下文,这里我发现使用 32b-q4 的 DeepSeek R1 效果并不好,经常会出现输出错别字,在修改代码时还会出现“知错不改”的现象,就是明明知道哪里该改,但是就是只在要改地方写注释(我要改了,我真的要改了!)但是还是不改(= =)。

因为涉及到错误修复的流程,所以上下文长度很重要,ollama 默认的 2k 上下文是很难成功的(虽然有一次跑了 40 多分钟重试了 70 多次硬是试出来了)。我一开始使用的是  qwen2.5:32b-q4,后来为了增加上下文使用了更小的  iq4  量化,综合效果看,iq4-10k  是明显优于  q4-2k  的。

1.1. 输入的 Python 代码

输入的测试 py 代码是一个手动实现的矩阵乘法,我测试了多个模型都不能一次性做对,主要是下表索引和 c 的动态内存申请的过程有一定的复杂度,测试脚本也有一定难度,但是多次重试之后是能够成功生成的。

def mat_mult(a, b): # 手动实现矩阵乘法
iflen(a[0]) != len(b):
     return"矩阵维度不匹配"
 res = [[0for _ inrange(len(b[0]))] for _ inrange(len(a))]
for i inrange(len(a)):
     for j inrange(len(b[0])):
         for k inrange(len(b)):
             res[i][j] += a[i][k] * b[k][j]
return res
1.2. Agent 执行过程日志

DeepSeek-V3 总共重试了 3 次,最后解决了存在的 bug。

另外可以看到因为 API 服务器的负载过大,多次请求没有响应,但是进行重试之后最后还是稳定地运行完了。

这里值得注意的是,Agent 会存在偷跑行为,也就是给测试代码放水,比如检测的时候如果 py 和 c 输出的都是空内容也判对,针对这些问题有针对性地用这些 prompt 进行了围堵。

4. 必须捕获c和py的打印输出并判断输出一致性
5. 不得假设C代码的正确性,只能通过调用C库来验证
6. 必须调用功能验证函数
7. 功能验证必须判断输出值是否为空

执行过程的日志,为了避免过于繁琐,把输出的代码隐去了,最后会单独放出修改过的代码。实际运行中是可以流式输出推理过程和代码的这一点原生 LangChain 是做不到的,我在代码里重新写了 LLM 调用的实现。

[DEBUG1] 16:04:10 发现已存在目录,已备份至: backup/output_bck_20250208_160410
[DEBUG1] 16:04:10 输出目录已创建: output
[DEBUG2] 16:04:10 正在加载提示模板...
[DEBUG2] 16:04:11 已初始化7个处理链
[DEBUG2] 16:04:11 已加载的链: test_script_gen, result_report_gen, c_code_gen, next_action_decision, history_builder_chain, note_generation, sa_chain
[DEBUG2] 16:04:11 开始处理Python代码
[DEBUG2] 16:04:11 def mat_mult(a, b): # 手动实现矩阵乘法
[DEBUG2] 16:04:11     if len(a[0]) != len(b):
[DEBUG2] 16:04:11         return"矩阵维度不匹配"
[DEBUG2] 16:04:11     res = [[0 for _ in range(len(b[0]))] for _ in range(len(a))]
[DEBUG2] 16:04:11     for i in range(len(a)):
[DEBUG2] 16:04:11         for j in range(len(b[0])):
[DEBUG2] 16:04:11             for k in range(len(b)):
[DEBUG2] 16:04:11                 res[i][j] += a[i][k] * b[k][j]
[DEBUG2] 16:04:11     return res
[DEBUG2] 16:04:11 
[DEBUG1] 16:04:11 初始化
[DEBUG1] 16:04:11 开始C代码生成...
[DEBUG2] 16:04:40 结果已保存至: output/c_code.json
[DEBUG2] 16:04:40 清洗后C代码长度: 491 chars
[DEBUG2] 16:04:40 写入C文件到: output/temp_py2c.c
[DEBUG1] 16:04:40 开始测试脚本生成...
[DEBUG2] 16:09:50 结果已保存至: output/test_script.json
[DEBUG2] 16:09:50 清洗后测试脚本长度: 2905 chars
[DEBUG2] 16:09:50 代码已保存至: output/input.py
[DEBUG1] 16:09:50 开始编译测试流程
[DEBUG2] 16:09:50 待编译代码长度: 491 chars
[DEBUG2] 16:09:50 执行编译命令: gcc -O3 -shared -fPIC output/temp_py2c.c -o output/libpy2c.so
[DEBUG1] 16:09:50 编译完成 [0.3s]
[DEBUG2] 16:09:50 编译器退出码: 0
[DEBUG1] 16:09:50 开始执行测试脚本: output/temp_test.py
[DEBUG1] 16:09:50 测试完成 [0.0s]
[DEBUG2] 16:09:50 测试退出码: 1
[DEBUG2] 16:09:50 测试输出摘要:
[DEBUG2] 16:09:50 
[DEBUG1] 16:09:50 生成最终评估报告...
result_report_gen 输出流: ```json
{
"speedup": 0.0,
"correctness": false,
"keylog": "IndexError: list index out of range",
"info": "测试失败,原因是矩阵a的维度不正确,导致在访问a[0]时出现索引越界错误。可能的原因是输入的矩阵a为空或未正确初始化。建议检查输入矩阵的初始化过程,确保矩阵a和b的维度符合矩阵乘法的要求。"
}
``
[DEBUG2] 16:11:01 结果已保存至: output/final_report.json
[DEBUG1] 16:11:01 测试未通过,重试次数: 1
[DEBUG1] 16:11:01 开始C代码生成...
流式请求发生错误: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None}
[DEBUG1] 16:14:03 链执行失败: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None} (第 1 次重试,共 10 次)
[DEBUG2] 16:14:40 结果已保存至: output/c_code.json
[DEBUG2] 16:14:40 清洗后C代码长度: 591 chars
[DEBUG2] 16:14:40 写入C文件到: output/temp_py2c.c
[DEBUG1] 16:14:40 开始测试脚本生成...
[DEBUG2] 16:19:13 结果已保存至: output/test_script.json
[DEBUG2] 16:19:13 清洗后测试脚本长度: 2884 chars
[DEBUG2] 16:19:13 代码已保存至: output/input.py
[DEBUG1] 16:19:13 开始编译测试流程
[DEBUG2] 16:19:13 待编译代码长度: 591 chars
[DEBUG2] 16:19:13 执行编译命令: gcc -O3 -shared -fPIC output/temp_py2c.c -o output/libpy2c.so
[DEBUG1] 16:19:13 编译完成 [0.1s]
[DEBUG2] 16:19:13 编译器退出码: 0
[DEBUG1] 16:19:13 开始执行测试脚本: output/temp_test.py
[DEBUG1] 16:19:13 测试完成 [0.0s]
[DEBUG2] 16:19:13 测试退出码: 1
[DEBUG2] 16:19:13 测试输出摘要:
[DEBUG2] 16:19:13 
[DEBUG1] 16:19:13 生成最终评估报告...
result_report_gen 输出流: ```json
{
"speedup": 0.0,
"correctness": false,
"keylog": "TypeError: incompatible types, LP_c_int_Array_1 instance instead of LP_c_int instance",
"info": "测试失败,原因是类型不匹配错误。在将Python数组转换为C语言二维数组时,出现了类型不兼容的问题。可能的原因是C语言数组的指针类型与Python的ctypes库不匹配。建议检查to_c_matrix函数中的数组创建逻辑,确保类型转换正确。"
}
``
[DEBUG2] 16:20:02 结果已保存至: output/final_report.json
[DEBUG1] 16:20:02 测试未通过,重试次数: 2
[DEBUG1] 16:20:02 开始C代码生成...
[DEBUG2] 16:21:05 结果已保存至: output/c_code.json
[DEBUG2] 16:21:05 清洗后C代码长度: 591 chars
[DEBUG2] 16:21:05 写入C文件到: output/temp_py2c.c
[DEBUG1] 16:21:05 开始测试脚本生成...
[DEBUG2] 16:26:56 结果已保存至: output/test_script.json
[DEBUG2] 16:26:56 清洗后测试脚本长度: 2929 chars
[DEBUG2] 16:26:56 代码已保存至: output/input.py
[DEBUG1] 16:26:56 开始编译测试流程
[DEBUG2] 16:26:56 待编译代码长度: 591 chars
[DEBUG2] 16:26:56 执行编译命令: gcc -O3 -shared -fPIC output/temp_py2c.c -o output/libpy2c.so
[DEBUG1] 16:26:56 编译完成 [0.1s]
[DEBUG2] 16:26:56 编译器退出码: 0
[DEBUG1] 16:26:56 开始执行测试脚本: output/temp_test.py
[DEBUG1] 16:26:56 测试完成 [0.0s]
[DEBUG2] 16:26:56 测试退出码: 1
[DEBUG2] 16:26:56 测试输出摘要:
[DEBUG2] 16:26:56 
[DEBUG1] 16:26:56 生成最终评估报告...

result_report_gen 输出流: 
流式请求发生错误: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None}
[DEBUG1] 16:29:58 链执行失败: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None} (第 1 次重试,共 10 次)

result_report_gen 输出流: 
流式请求发生错误: Request timed out.
[DEBUG1] 16:32:10 链执行失败: Request timed out. (第 2 次重试,共 10 次)

result_report_gen 输出流: 
流式请求发生错误: Request timed out.
[DEBUG1] 16:32:29 链执行失败: Request timed out. (第 3 次重试,共 10 次)

result_report_gen 输出流: 
流式请求发生错误: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None}
[DEBUG1] 16:33:48 链执行失败: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None} (第 4 次重试,共 10 次)

result_report_gen 输出流: ```json
{
"speedup": 0.0,
"correctness": false,
"keylog": "IndexError: list index out of range",
"info": "测试失败,原因是矩阵a的维度不正确,导致在访问a[0]时出现索引越界错误。可能的原因是输入矩阵a为空或未正确初始化。建议检查输入矩阵的初始化过程,确保矩阵a和b的维度符合乘法要求。"
}
``

[DEBUG2] 16:35:30 结果已保存至: output/final_report.json
[DEBUG1] 16:35:30 测试未通过,重试次数: 3
[DEBUG1] 16:35:30 开始C代码生成...
[DEBUG2] 16:37:12 结果已保存至: output/c_code.json
[DEBUG2] 16:37:12 清洗后C代码长度: 591 chars
[DEBUG2] 16:37:12 写入C文件到: output/temp_py2c.c
[DEBUG1] 16:37:12 开始测试脚本生成...

test_script_gen 输出流: 
流式请求发生错误: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None}
[DEBUG1] 16:40:14 链执行失败: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None} (第 1 次重试,共 10 次)

test_script_gen 输出流: 
流式请求发生错误: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None}
[DEBUG1] 16:43:19 链执行失败: Error code: 504 - {'code': 50501, 'message': 'Model service timeout. Please try again later.', 'data': None} (第 2 次重试,共 10 次)
[DEBUG2] 16:46:52 结果已保存至: output/test_script.json
[DEBUG2] 16:46:52 清洗后测试脚本长度: 2908 chars
[DEBUG2] 16:46:52 代码已保存至: output/input.py
[DEBUG1] 16:46:52 开始编译测试流程
[DEBUG2] 16:46:52 待编译代码长度: 591 chars
[DEBUG2] 16:46:52 执行编译命令: gcc -O3 -shared -fPIC output/temp_py2c.c -o output/libpy2c.so
[DEBUG1] 16:46:52 编译完成 [0.1s]
[DEBUG2] 16:46:52 编译器退出码: 0
[DEBUG1] 16:46:52 开始执行测试脚本: output/temp_test.py
[DEBUG1] 16:46:52 测试完成 [0.0s]
[DEBUG2] 16:46:52 测试退出码: 0
[DEBUG2] 16:46:52 测试输出摘要:
[DEBUG2] 16:46:52 python time: 0.03890491
[DEBUG2] 16:46:52 c time: 0.00087452
[DEBUG2] 16:46:52 speedup: 44.48718648
[DEBUG2] 16:46:52 
[DEBUG1] 16:46:52 生成最终评估报告...

result_report_gen 输出流: ```json
{
"speedup": 44.5,
"correctness": true,
"keylog": "python time: 0.03890491\nc time: 0.00087452\nspeedup: 44.48718648\n",
"info": "测试通过,C代码的执行速度比Python快44.5倍,矩阵乘法实现正确,没有发现错误。"
}
``

[DEBUG2] 16:47:28 结果已保存至: output/final_report.json

测试结果:
状态: passed
重试次数: 3
总耗时: 0 时43 分17 秒
加速比信息: 44.5
关键日志: python time: 0.03890491
c time: 0.00087452
speedup: 44.48718648

测试报告: 测试通过,C代码的执行速度比Python快44.5倍,矩阵乘法实现正确,没有发现错误。
1.3. 自动转换出的 C 代码
#include <stdint.h>
#include <stddef.h>

int32_tmat_mult(int32_t** a, size_t a_rows, size_t a_cols, int32_t** b, size_t b_rows, size_t b_cols, int32_t** res) {
if (a_rows == 0 || a_cols == 0 || b_rows == 0 || b_cols == 0) {
     return-1; // 空矩阵
 }
if (a_cols != b_rows) {
     return-1; // 矩阵维度不匹配
 }

for (size_t i = 0; i < a_rows; i++) {
     for (size_t j = 0; j < b_cols; j++) {
         res[i][j] = 0;
         for (size_t k = 0; k < a_cols; k++) {
             res[i][j] += a[i][k] * b[k][j];
         }
     }
 }

return0; // 成功
}
1.4. 测试脚本
import ctypes, time
frominputimport *

# Load C library
lib = ctypes.CDLL('./output/libpy2c.so')

# Define argument types for the C function
lib.mat_mult.argtypes = [
 ctypes.POINTER(ctypes.POINTER(ctypes.c_int32)), ctypes.c_size_t, ctypes.c_size_t,
 ctypes.POINTER(ctypes.POINTER(ctypes.c_int32)), ctypes.c_size_t, ctypes.c_size_t,
 ctypes.POINTER(ctypes.POINTER(ctypes.c_int32))
]
lib.mat_mult.restype = ctypes.c_int32

defcreate_2d_array(rows, cols):
 array = (ctypes.POINTER(ctypes.c_int32) * rows)()
for i inrange(rows):
     array[i] = (ctypes.c_int32 * cols)()
return array

defto_c_matrix(matrix):
 rows = len(matrix)
 cols = len(matrix[0]) if rows > 0else0
 c_matrix = create_2d_array(rows, cols)
for i inrange(rows):
     for j inrange(cols):
         c_matrix[i][j] = matrix[i][j]
return c_matrix

deffrom_c_matrix(c_matrix, rows, cols):
 matrix = [[0for _ inrange(cols)] for _ inrange(rows)]
for i inrange(rows):
     for j inrange(cols):
         matrix[i][j] = c_matrix[i][j]
return matrix

deftest_mat_mult(a, b):
 a_rows, a_cols = len(a), len(a[0]) iflen(a) > 0else0
 b_rows, b_cols = len(b), len(b[0]) iflen(b) > 0else0
 res_rows, res_cols = a_rows, b_cols

# Python implementation
 py_res = mat_mult(a, b)

# C implementation
 c_a = to_c_matrix(a)
 c_b = to_c_matrix(b)
 c_res = create_2d_array(res_rows, res_cols)
 c_ret = lib.mat_mult(c_a, a_rows, a_cols, c_b, b_rows, b_cols, c_res)
 c_res_matrix = from_c_matrix(c_res, res_rows, res_cols)

# Check if the output is empty
assert py_res isnotNone, "Python output is empty"
assert c_ret != -1, "C output is empty"

# Check consistency
assert py_res == c_res_matrix, f"Output mismatch: Python {py_res}, C {c_res_matrix}"

# Test cases
test_cases = [
 ([[1]], [[1]]),  # n=1
 ([[1, 2], [3, 4]], [[5, 6], [7, 8]]),  # n=2
 ([[1, 2, 3], [4, 5, 6]], [[7, 8], [9, 10], [11, 12]]),  # n=3
 ([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25]],
  [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25]])  # n=5
]

for a, b in test_cases:
 test_mat_mult(a, b)

# Performance comparison
a = [[i + j for j inrange(10)] for i inrange(10)]
b = [[i + j for j inrange(10)] for i inrange(10)]

# Python performance
start = time.time()
for _ inrange(1000):
 mat_mult(a, b)
py_time_total = time.time() - start

# C performance
c_a = to_c_matrix(a)
c_b = to_c_matrix(b)
c_res = create_2d_array(10, 10)
start = time.time()
for _ inrange(1000):
 lib.mat_mult(c_a, 10, 10, c_b, 10, 10, c_res)
c_time_total = time.time() - start

# Output performance results
print('python time: %.8f' % py_time_total)
print('c time: %.8f' % c_time_total)
print('speedup: %.8f' % (py_time_total / c_time_total))
1.5. 测试报告输出
测试结果:
状态: passed
重试次数: 3
总耗时: 0 时43 分17 秒
加速比信息: 44.5
关键日志: python time: 0.03890491
c time: 0.00087452
speedup: 44.48718648

测试报告: 测试通过,C代码的执行速度比Python快44.5倍,矩阵乘法实现正确,没有发现错误。

2. 文件漫游(File System Explorer) DEMO 运行过程

在本次演示中,Agent 首先会获取工作目录并执行一系列基础命令,以探索项目文件结构并查看部分文件内容。为了更直观地了解整个过程,我们不仅罗列操作步骤,还配合展示部分对应的日志输出,以体现 Agent 的思路和决策方式。

本次测试用的模型是 DeepSeek-R1-70b 蒸馏版本的网络 API,感谢  knox.chat  提供的免费 70b 模型的 Token。

实际上用 32b-q4 的 qwen 效果也不错,反而 32b-q4 的 DeepSeek-R1 效果不如 qianwen,32b 容易陷入无限 think 循环和输出错别字(比如多一个下划线或者多个空格),目前还不清楚原因。

我也用 DeepSeek-R1 满血版做过测试,但是服务器响应太慢,实际体验反而不如 DeepSeek-R1-70b。

2.1 列出当前目录内容
  • 操作目的: 获取根目录下的文件和子目录,确定后续要浏览的文件或需要进入的子目录。
  • 执行命令ls

相关日志示例

plaintext复制编辑[DEBUG2] 18:31:20 执行命令: ls
[DEBUG1] 18:31:20 system_state: {... 'last_command': 'ls'}

从日志可以看到,Agent 发出了  ls  命令后,系统状态随之更新,记录了最新一次执行的命令。通过输出结果,Agent 便能知道项目根目录下有哪些文件与目录,为下一步浏览做准备。

2.2 查看主文件  main.py
  • 操作目的: 读取主程序逻辑,了解其中定义的函数(如  python2C()romingbot())及其功能,为后续处理与分析做参考。
  • 执行命令cat main.py

相关日志示例

bash复制编辑[DEBUG2] 18:31:29 执行命令: cat main.py
[DEBUG1] 18:31:29 system_state: {... 'last_command': 'cat main.py'}

next_action_decision 输出流: <think>
好的... 因为 main.py 可能是主入口文件,所以先 cat main.py。
</think>

可以看出,Agent 首先根据  ls  的结果发现有  main.py,并将其视为主入口文件。随后执行  cat main.py  命令查看文件内容,并在内部进行“思考”(<think>  区域),确认这是它想要获取的关键信息。

2.3 进入子目录  core
  • 操作目的: 进一步探索项目核心逻辑所在的位置,查看子目录下的相关文件。
  • 执行命令 :
  • cd core
  • ls

相关日志示例

python复制编辑[DEBUG2] 18:32:28 执行命令: cd core
[DEBUG2] 18:32:36 执行命令: ls

当 Agent 发现目录  core  可能存放更核心的实现文件后,便执行了  cd core  进入该目录,并再次使用  ls  命令查看此处的所有文件列表。

2.4 查看并分析核心文件

在  core  目录下,Agent 针对关键文件执行了“查看内容—生成笔记—更新总结”的三步流程。下面以  pipelinebase.py  与  pipeline.py  为例,展示其中的操作和对应日志。

  1. 查看  pipelinebase.py

日志示例

plaintext复制编辑[DEBUG2] 18:34:16 执行命令: cat pipelinebase.py
[DEBUG1] 18:34:24 开始笔记生成
note_generation 输出流: <think>
正在撰写结构化的笔记...
</think>
[DEBUG2] 18:35:59 结果已保存至: output/new_note.json
...

这里可以看到,当 Agent 成功读取  pipelinebase.py  后,进入了“笔记生成”阶段,把文件要点记录为结构化信息,并保存到指定位置。

  • 操作目的: 了解基础流水线相关代码,掌握通用工具方法和基类实现细节。
  • 执行命令cat pipelinebase.py

2. 查看pipeline.py

日志示例

plaintext复制编辑[DEBUG2] 18:35:21 执行命令: cat pipeline.py
summary_generation 输出流: <think>
生成摘要并合并至 summaries...
</think>
...

与前一个文件类似,Agent 也会在确认提取了新信息后,执行自动化的内容总结与合并摘要操作。

  • 操作目的: 了解 Python 到 C 代码转换的核心流水线,实现细节包括状态机流程、代码生成与编译测试等。
  • 执行命令cat pipeline.py
2.5 DeepSeek 决策和思考的流程(部分)
[DEBUG2] 18:31:20 正在加载提示模板...
[DEBUG2] 18:31:20 已初始化7个处理链
[DEBUG2] 18:31:20 已加载的链: test_script_gen, result_report_gen, c_code_gen, next_action_decision, history_builder_chain, note_generation, sa_chain
[DEBUG1] 18:31:20 工作目录已初始化: /home/ubuntu/agent_demo
[DEBUG1] 18:31:20 初始化探索机器人
[DEBUG2] 18:31:20 执行命令: ls
[DEBUG1] 18:31:20 system_state: {'current_path': '/home/ubuntu/agent_demo', 'note_count': 0, 'note_word_count': 0, 'start_time': '2025-02-08T18:31:20.363208', 'executed_commands': deque(['ls'], maxlen=10), 'summaries': '', 'last_command': 'ls'}

next_action_decision 输出流: <think>
好的,我现在需要根据系统状态和决策规则来决定下一步的行动。首先,系统当前的路径是‘/home/ubuntu/agent_demo’,最近执行的命令是‘ls’,并且输出显示了当前目录的文件和子目录。

根据决策规则,首先检查最近命令是否失败。这里‘ls’成功了,所以不需要尝试其他命令。接下来,规则3指出只能使用cd、ls、cat,所以我要在这三个命令中选择。

规则5提到要优先查看文件,而不是子目录。当前目录有几个文件:input.py、main.py、requirements.txt、config.py。这些都是代码文件,适合用cat查看。子目录有core、utils、prompts、workspace、chains,可能在后面再处理。

规则6说如果子目录可能有重要信息,建议cd进去,但规则5优先级更高,所以先处理文件。现在,我应该选择一个文件来cat。通常,main.py是项目的主文件,可能包含主要逻辑,所以先看main.py。

因此,下一步行动应该是执行cat main.py,并进行总结。这样可以获取更多信息,帮助后续决策。
</think>

{
    "reasoning": "最近命令ls成功,显示了当前目录的文件和子目录。根据规则5,优先查看文件。当前目录有input.py、main.py、requirements.txt、config.py等文件,这些都是代码文件,适合用cat查看。选择main.py,因为它通常是项目的主文件,可能包含重要信息。",
    "action": "execute",
    "next_command": "cat main.py"
}
``

[DEBUG2] 18:31:29 结果已保存至: output/next_action_decision.json
[DEBUG2] 18:31:29 执行命令: cat main.py
[DEBUG1] 18:31:29 system_state: {'current_path': '/home/ubuntu/agent_demo', 'note_count': 0, 'note_word_count': 0, 'start_time': '2025-02-08T18:31:20.363208', 'executed_commands': deque(['ls', 'cat main.py'], maxlen=10), 'summaries': '', 'last_command': 'cat main.py'}

next_action_decision 输出流: <think>
好的,我现在需要根据系统状态和决策规则来决定下一步行动。首先,系统当前路径是‘/home/ubuntu/agent_demo’,最近执行的命令是‘cat main.py’,并且输出成功。根据规则4,如果最近命令是cat且成功,且内容与summaries不重复,应该进行总结。summaries当前为空,所以需要总结main.py的内容。

main.py文件中定义了两个函数:python2C()和romingbot()。python2C()函数使用Python2CPipeline处理输入代码,执行编译并输出结果。romingbot()函数则使用ExplorationBotPipeline执行‘ls’命令。主程序中调用了python2C()函数,而romingbot()被注释了。

因此,总结时应简要描述这两个函数的作用及其调用情况。接下来,根据规则8,优先查看文件,当前目录下可能还有其他文件需要查看,比如input.py或其他代码文件。因此,下一步可以考虑cat input.py,但需要先确认该文件是否存在。

总结完成后,action应为“write_note”,并填写相应的总结内容。同时,下一步的命令可以是‘cat input.py’,但根据输出要求,next_command在action为execute时才填写,否则为空。因此,这里action为“write_note”,next_command为空。
</think>

{
    "reasoning": "最近命令是cat main.py,成功执行。根据规则4,应进行总结。main.py文件包含两个函数:python2C()和romingbot()。python2C()用于将Python代码转换为C代码并执行,romingbot()用于执行ls命令。主程序调用了python2C()函数。",
    "action": "write_note",
    "next_command": ""
}
``

[DEBUG2] 18:31:40 结果已保存至: output/next_action_decision.json
[DEBUG1] 18:31:40 开始笔记生成
[DEBUG1] 18:31:40 system_state: {'current_path': '/home/ubuntu/agent_demo', 'note_count': 0, 'note_word_count': 0, 'start_time': '2025-02-08T18:31:20.363208', 'executed_commands': deque(['ls', 'cat main.py', 'write_note'], maxlen=10), 'summaries': '', 'last_command': 'write_note', 'last_reasoning': '最近命令是cat main.py,成功执行。根据规则4,应进行总结。main.py文件包含两个函数:python2C()和romingbot()。python2C()用于将Python代码转换为C代码并执行,romingbot()用于执行ls命令。主程序调用了python2C()函数。'}

note_generation 输出流: <think>
好,我现在需要根据用户提供的代码和系统状态生成一个结构化的笔记。首先,我要理解用户的代码内容。代码中有两个函数,python2C()和romingbot(),以及主程序部分调用了python2C()。

python2C()函数看起来是用来将Python代码转换为C代码并执行的。它使用了Python2CPipeline类,读取input.py文件,执行pipeline,然后输出结果,包括编译状态、重试次数、总耗时、加速比信息、关键日志和测试报告。这个函数的主要目的是测试Python到C的转换过程,并提供详细的执行结果。

romingbot()函数则使用了ExplorationBotPipeline类,传入了一个路径'../agent_demo',并执行了'ls'命令。这可能是一个用于文件系统探索的机器人,执行基本的文件操作。

主程序部分调用了python2C()函数,说明当前的执行重点是Python到C的转换测试,而romingbot()函数被注释掉了,可能暂时不使用。

接下来,系统状态显示了当前路径、笔记数量、已执行的命令等信息。其中,已执行的命令包括'ls'、'cat main.py'和'write_note',最近一次命令是'write_note',用于生成笔记。系统摘要中提到,main.py文件包含两个函数,主程序调用了python2C()。

根据生成要求,我需要使用Markdown格式,内容不少于1000字,不输出系统状态,必须用中文,summaries要避免重复,不能直接输出原文,必须概括总结,禁止输出文件路径,二级标题不与一级标题重复,跳过许可证和版权信息,代码用代码块包裹。

首先,标题应该简短,不包含文件名,比如“Python到C代码转换与探索机器人功能实现”。

内容部分需要分为几个部分。首先是概述,简要介绍整个脚本的功能和结构。然后是详细功能说明,分为Python到C转换功能和探索机器人功能。接着是实现细节,包括代码结构和关键实现步骤。最后是测试与结果展示,说明如何测试这两个功能模块。

在写作过程中,要避免重复summaries中的内容,进行概括总结。例如,summaries中提到main.py包含两个函数,主程序调用了python2C(),在笔记中可以进一步扩展,说明每个函数的具体功能和实现细节。

需要注意的是,不能直接输出文件路径,所以在描述代码时,要避免提及具体的路径,如'../agent_demo'。代码块需要用```包裹,并说明代码的作用。

最后,确保内容达到1000字以上,结构清晰,逻辑连贯。使用适当的二级标题,使内容易于阅读和理解。

现在,根据以上思考,我可以开始撰写结构化的笔记了。
</think>

{
    "title": "Python到C代码转换与探索机器人功能实现",
    "content": "本文档概述了一个用于将Python代码转换为C代码并执行的脚本,以及一个用于文件系统探索的机器人功能的实现。脚本通过两个主要函数实现其核心功能:python2C()和romingbot()。主程序执行python2C()函数以进行代码转换和测试。\n\n### Python到C代码转换功能\n\n该功能通过Python2CPipeline类实现,主要步骤包括读取输入Python代码、执行转换流程、编译并运行生成的C代码。转换过程中会记录编译状态、重试次数、总耗时等信息,并生成详细的测试报告,包括加速比和关键日志。\n\n### 探索机器人功能\n\nromingbot()函数使用ExplorationBotPipeline类,用于执行基本的文件系统操作,如目录列表查询。该功能可扩展为更复杂的文件操作,目前示例中执行'ls'命令以展示目录内容。\n\n### 实现细节\n\n代码结构清晰,主函数调用python2C()执行转换测试。转换过程中,读取输入文件,执行pipeline,处理结果并格式化输出。romingbot()函数初始化pipeline并执行指定命令。\n\n### 测试与结果展示\n\n测试结果包括编译状态、重试次数、总耗时、加速比、关键日志和测试报告。这些信息帮助评估转换的效率和效果。探索机器人部分可通过执行不同命令扩展功能。",
    "tags": ["代码转换", "机器人", "测试报告"]
}
``

[DEBUG2] 18:32:09 结果已保存至: output/new_note.json

summary_generation 输出流: <think>
好的,我现在需要根据用户提供的笔记内容生成一个摘要,并将其与之前的摘要合并,确保总长度不超过200字。首先,我要仔细阅读用户提供的笔记内容,理解其中的主要信息。

笔记内容主要分为三个部分:概述、Python到C代码转换功能、探索机器人功能,以及实现细节和测试结果展示。概述部分提到了两个主要功能:代码转换和文件系统探索。转换功能通过python2C()函数实现,使用Python2CPipeline类,处理输入代码,记录状态和生成报告。探索机器人功能由romingbot()函数实现,使用ExplorationBotPipeline类,执行基本文件操作,如'ls'命令。

接下来,我需要将这些内容浓缩成一个简洁的摘要,确保涵盖关键点:代码转换、测试报告、探索机器人功能及其扩展性。同时,要与之前的摘要合并,但用户没有提供之前的摘要内容,所以我可能需要假设之前的摘要已经涵盖了部分内容,或者直接生成一个全新的摘要。

根据生成要求,摘要需要高度概括,避免使用代码或特殊字符,并且控制在200字以内。因此,我需要用简洁的语言概括已记录的内容,确保不重复,并突出主要功能和测试结果。

现在,我会组织语言,确保每个主要部分都有所涵盖,同时保持流畅和简洁。例如,提到代码转换脚本、转换流程、测试报告,探索机器人功能及其扩展性,以及测试结果的展示。

最后,检查字数,确保不超过限制,并且格式正确,输出为JSON格式的summary字段。
</think>

{
    "summary": "已经记录了Python代码转换为C代码的脚本实现,包括转换流程、测试报告生成和探索机器人功能的基础实现。转换功能通过python2C()函数实现,记录编译状态、耗时等信息并生成报告。探索机器人功能可执行文件系统操作,如目录查询,并具备扩展潜力。测试结果展示了转换效率和效果,机器人功能可通过命令扩展。"
}
``

[DEBUG2] 18:32:21 结果已保存至: output/summary_generation.json
[DEBUG1] 18:32:21 system_state: {'current_path': '/home/ubuntu/agent_demo', 'note_count': 1, 'note_word_count': 1, 'start_time': '2025-02-08T18:31:20.363208', 'executed_commands': deque(['ls', 'cat main.py', 'write_note'], maxlen=10), 'summaries': '已经记录了Python代码转换为C代码的脚本实现,包括转换流程、测试报告生成和探索机器人功能的基础实现。转换功能通过python2C()函数实现,记录编译状态、耗时等信息并生成报告。探索机器人功能可执行文件系统操作,如目录查询,并具备扩展潜力。测试结果展示了转换效率和效果,机器人功能可通过命令扩展。', 'last_command': 'write_note'}

next_action_decision 输出流: <think>
好的,我现在需要根据系统状态和决策规则来决定下一步的行动。首先,最近执行的命令是write_note,输出显示笔记已经保存到notes.md,并列出了当前目录的文件和子目录。系统状态中的summaries已经包含了对代码转换和机器人功能的描述,所以根据规则4,不需要再次总结。

接下来,查看决策规则。规则6指出,如果子目录可能有重要信息,建议cd进去查看。当前目录下有core、utils、prompts、workspace和chains五个子目录,这些看起来都可能包含重要的代码或配置文件,特别是core和utils可能包含转换脚本的核心实现。

规则8提到要优先查看文件,但当前目录的文件如input.py、config.py可能已经被处理过,或者可能不如子目录的内容重要。因此,应该优先探索子目录,特别是core,因为它可能包含主要的功能实现。

所以,下一步应该是执行cd core,进入core子目录查看里面的内容,以便进一步了解代码结构和实现细节。
</think>

{
    "reasoning": "最近命令write_note成功,summaries已经包含了相关信息。当前目录有多个子目录,特别是core和utils可能包含重要代码。根据规则6,建议cd进入子目录查看。",
    "action": "execute",
    "next_command": "cd core"
}
``

[DEBUG2] 18:32:28 结果已保存至: output/next_action_decision.json
[DEBUG2] 18:32:28 执行命令: cd core
[DEBUG1] 18:32:28 system_state: {'current_path': '/home/ubuntu/agent_demo/core', 'note_count': 1, 'note_word_count': 1, 'start_time': '2025-02-08T18:31:20.363208', 'executed_commands': deque(['ls', 'cat main.py', 'write_note', 'cd core'], maxlen=10), 'summaries': '已经记录了Python代码转换为C代码的脚本实现,包括转换流程、测试报告生成和探索机器人功能的基础实现。转换功能通过python2C()函数实现,记录编译状态、耗时等信息并生成报告。探索机器人功能可执行文件系统操作,如目录查询,并具备扩展潜力。测试结果展示了转换效率和效果,机器人功能可通过命令扩展。', 'last_command': 'cd core'}

next_action_decision 输出流: 
流式请求发生错误: Connection error.
[DEBUG1] 18:32:45 链执行失败: Connection error. (第 1 次重试,共 10 次)

next_action_decision 输出流: 
流式请求发生错误: Request timed out.
[DEBUG1] 18:33:04 链执行失败: Request timed out. (第 2 次重试,共 10 次)

next_action_decision 输出流: 
流式请求发生错误: Request timed out.
[DEBUG1] 18:33:23 链执行失败: Request timed out. (第 3 次重试,共 10 次)

next_action_decision 输出流: <think>
好的,我现在需要根据系统状态和决策规则来决定下一步行动。首先,系统当前路径是‘/home/ubuntu/agent_demo/core’,最近执行的命令是‘cd core’,输出显示目录切换成功,当前目录有三个文件:piplinebase.py、pipeline.py和romingbot.py。

根据决策规则,首先检查最近命令是否成功。这里‘cd core’成功了,所以不需要考虑规则1。接下来,规则3指出只能执行cd、ls、cat命令,而我打算执行ls来查看目录详细信息,这符合规则3。

规则6提到如果子目录可能有重要信息,建议cd进入查看,但这里当前目录有三个文件,没有子目录,所以暂时不需要cd。规则7说如果目录为空则cd..,但这里有文件,所以也不适用。规则8建议优先查看文件,所以我应该先查看这些文件。

接下来,我应该先执行ls命令,以获取更多关于这些文件的信息,比如大小、修改时间等,这有助于决定下一步是否需要cat查看文件内容。因此,下一步行动应该是执行ls命令。
</think>

{
    "reasoning": "最近命令'cd core'成功,当前目录有三个Python文件。根据规则8,优先查看文件。执行ls命令以获取文件详细信息,帮助决定下一步是否查看文件内容。",
    "action": "execute",
    "next_command": "ls"
}
``

...

六、后续展望

这两个 DEMO 还在非常初级的阶段,很多功能都很粗糙。比如:

  • Python -> C 转换只实现了单函数层面,若要支持第三方库、类、异常处理等情况,得再做大量适配。
  • 文件漫游 Agent 还不支持多个智能体并行协作,也没深入探索文件层级结构的全局摘要或与 RAG(Retrieval-Augmented Generation)的结合。
  • 真正实现多人协作、多进程或多线程并行,甚至跨文件夹的语义搜索和“总结记忆”,才可能打造出一个多维度的智能助理。
  • 目前文件漫游 Agent 还不能读取过长的文件。

总之,Agent 这个概念想做的事儿很多,但当前只是“把想法跑起来”的第一步。离真正落地还有不少距离:安全、扩展、可靠性、可维护性等都需要更深入的研究和实践。希望这些初步的经验分享,能给大家带来一些启发,也欢迎一起讨论如何让 Agent 在日常开发中更好地发挥作用。

附件 1 - 文件漫游 Agent 对自己的源码的漫游笔记(部分)

4. factory.py - LLM 链式调用与工厂实现

[引用]

该代码实现了一个支持流式输出的 LLM 链式调用框架,主要包含两个核心类:VerboseChain 和 ChainFactory。VerboseChain 类用于通过 OpenAI API 调用模型,支持流式响应处理和日志记录。ChainFactory 类则负责加载和管理多个处理链,提供便捷的方式初始化和获取链式调用实例。

VerboseChain 类

概述

VerboseChain 类是框架的核心,负责实际的模型调用和响应处理。它支持从文件或字符串创建提示模板,并提供了流式输出的处理逻辑。

初始化

该类通过构造函数初始化,接受 prompt、output_key 和 name 参数。构造函数中初始化 OpenAI 客户端,加载模板,并设置模型参数如 max_tokens 和 temperature。

方法

  1. from_prompt_file:从文件路径加载提示模板,返回 VerboseChain 实例。
  2. from_prompt_string:从字符串加载提示模板,返回 VerboseChain 实例。
  3. invoke:执行模型调用,处理流式响应,返回处理后的结果。

流式处理

invoke 方法通过启用 stream 参数,接收分块响应,并实时打印和存储内容。处理完所有块后,清理响应内容中的思考标签,返回最终结果。

ChainFactory 类

概述

ChainFactory 类作为 LLM 链的工厂,负责加载和管理多个处理链。它自动扫描指定目录下的提示模板文件,初始化并存储各个链式调用实例。

初始化

构造函数接受 prompts_dir 参数,扫描该目录下的所有.txt 文件,加载并初始化每个文件对应的 VerboseChain 实例,存储在 chains 字典中。

方法

  1. get_chains:返回所有初始化好的链式调用实例。
实现细节
  1. 日志记录:通过 debug_log 函数记录关键步骤的日志,方便调试和监控。
  2. 正则处理:在 invoke 方法中使用正则表达式清理响应内容中的<思考>标签。
  3. 错误处理:在流式处理中捕获异常并打印错误信息。
  4. 扩展参数:支持通过 extra_body 传递额外的模型参数,如 return_reasoning。
示例
## 创建工厂并加载所有提示模板  
factory = ChainFactory(prompts_dir="prompts")

## 获取所有链

chains = factory.get_chains()

## 使用特定链进行调用

response = chains["my_chain"].invoke(inputs)
总结

该框架通过模块化设计,支持灵活的提示管理和流式响应处理,适用于需要详细日志记录和多链式调用场景。通过 ChainFactory 简化了链的管理和加载过程,而 VerboseChain 则提供了强大的模型调用和响应处理能力。

5. pipeline.py - Python 到 C 代码转换流水线实现

Time: 2025-02-08 13:49

Path: D:\work\agent_demo\core\pipeline.py

Tags:  代码转换`流水线`自动化

该代码实现了一个将 Python 代码转换为 C 代码的完整流水线,涵盖了从代码生成到测试和编译的多个阶段。流水线通过状态机的方式管理各个阶段,确保每个步骤按顺序执行,并在必要时进行重试。

结构与组件

流水线由多个关键组件构成,包括代码生成器、测试生成器、编译器和报告解析器。这些组件协同工作,以确保转换过程的准确性和可靠性。

执行流程

流水线的执行分为几个关键阶段:

  1. 初始化:设置初始状态并准备输出目录。
  2. C 代码生成:利用 LLM 生成 C 代码,并对生成的代码进行清洗和保存。
  3. 测试脚本生成:生成用于测试的 Python 脚本,并保存以备后用。
  4. 编译与测试:编译生成的 C 代码并执行测试,记录测试结果。
  5. 最终报告:根据测试结果生成评估报告,判断转换的正确性。如果报告指出存在问题,流水线会进入重试状态,重新执行转换过程。
错误处理与重试机制

流水线在每个关键步骤后进行检查,确保生成的文件和测试结果符合预期。如果在任何阶段检测到错误,流水线会记录错误信息,并在必要时触发重试机制,以确保最终输出的正确性和可靠性。

6. piplinebase.py - 流水线基础类

[引用]

该文件定义了一个基础流水线类 PipelineBase,提供了执行 LLM 链、保存输出、解码中文 Unicode 和清洗代码等功能。

类概述

PipelineBase 类作为基础流水线类,主要用于提供常用的工具方法,包括 LLM 链的执行、结果保存、中文字符解码和代码清洗等功能。该类在初始化时设置了重试次数、历史记录和开始时间等属性。

方法说明

1. LLM_invoke 方法

  • 功能:执行单个 LLM 链并保存结果
  • 参数:prompt_template(VerboseChain 类型)、inputs(字典)、output_file(文件名,选项)
  • 返回值:结果字典
  • 特点:支持最多 10 次重试,每次失败后等待 3 秒
  • 备注:结果保存为 JSON 格式,文件名默认为链的名称

2. _save_output 方法

  • 功能:保存输出到文件
  • 参数:content(字符串内容)、filename(文件名)
  • 特点:仅解码中文字符的 Unicode 转义,使用 utf-8 编码保存
  • 备注:文件路径由 OutputManager 管理

3. _save_code 方法

  • 功能:保存代码文件
  • 参数:code(代码字符串)、filename(文件名)
  • 备注:直接将代码写入文件

4. _decode_chinese_unicode 方法

  • 功能:解码中文字符的 Unicode 转义
  • 参数:content(字符串)
  • 返回值:解码后的字符串
  • 特点:仅处理中文字符的 Unicode 转义,保留其他转义符

5. _clean_code 方法

  • 功能:清洗代码块
  • 参数:code(代码字符串)、lang(语言标识)
  • 返回值:清洗后的代码字符串
  • 特点:支持多种代码块格式,包括标准三反引号块和无标记块
  • 备注:处理语言标识、去除反引号、清理空白

6. _post_process 方法

  • 功能:统一的后续处理
  • 参数:code(代码字符串)
  • 返回值:处理后的代码字符串
  • 处理内容:清理每行末尾空白,保留换行结构
代码示例
## 示例:执行LLM链并保存结果  
result = pipeline.LLM_invoke(prompt_template, inputs)
# 示例:保存代码文件  
pipeline._save_code(code, 'example.py')
总结

PipelineBase 类提供了基础的流水线功能,涵盖了 LLM 链的执行、结果保存、中文字符处理和代码清洗等方面。通过这些方法,可以方便地管理和处理 LLM 链的输出,确保结果的正确性和可读性。

7. romingbot.py - 文件系统探索机器人功能概述

[引用]

文件系统探索机器人旨在通过执行基本的文件系统命令(如 cd、ls、cat、pwd)来探索和记录指定目录下的文件和文件夹。该机器人能够记录执行的命令、生成笔记并进行总结,提供结构化的输出结果。以下是对该机器人功能的详细说明。

核心功能
  1. 文件系统命令执行
  • 支持 cd 命令:切换目录
  • 支持 ls 命令:列出目录内容
  • 支持 cat 命令:查看文件内容
  • 支持 pwd 命令:显示当前工作目录
  1. 状态管理
  • 记录当前路径
  • 统计笔记数量和字数
  • 记录开始时间
  • 记录最近执行的命令(最多 10 条)
  • 生成总结
  1. 笔记生成
  • 自动生成 Markdown 格式的笔记
  • 支持多级标题
  • 自动生成内容摘要
  • 支持代码块格式

4. 扩展性

  • 通过 ChainFactory 和 PromptFactory 实现功能扩展
  • 支持多种状态切换(初始化、空闲、执行命令、写笔记、决定下一步、完成)
实现细节

1. 初始化流程

  • 创建必要的目录结构
  • 初始化状态字典
  • 准备笔记目录
  • 重命名现有的 notes.md 文件以避免覆盖

2. 命令处理流程

  • 根据用户输入切换状态
  • 执行相应的命令处理逻辑
  • 记录命令执行结果
  • 更新状态字典

3. 笔记写入流程

  • 根据用户输入和系统状态生成笔记内容
  • 使用 LLM(大语言模型)进行内容生成
  • 格式化输出为 Markdown

4. 状态管理

  • 使用枚举定义机器人状态
  • 通过状态字典记录系统的运行状态
  • 提供灵活的状态切换机制
状态管理

机器人在运行过程中会经历以下几个状态:

1. 初始化状态(INIT)

  • 系统初始化
  • 创建必要的目录和文件
  • 准备开始执行任务

2. 空闲状态(IDLE)

  • 等待用户输入
  • 可以接受新的命令

3. 执行命令状态(EXEC_COMMAND)

  • 处理用户输入的命令
  • 执行相应的操作
  • 记录命令执行结果

4. 写笔记状态(WRITE_NOTE)

  • 根据执行结果生成笔记
  • 格式化笔记内容
  • 保存笔记到指定目录

5. 决定下一步状态(DECIDE_NEXT)

  • 根据当前状态和执行结果决定下一步操作
  • 切换到新的状态

6. 完成状态(COMPLETED)

  • 任务完成
  • 返回最终的状态字典
命令处理

1. cd 命令

  • 切换当前工作目录
  • 更新 current_dir 属性
  • 记录执行的 cd 命令

2. ls 命令

  • 列出当前目录下的文件和文件夹
  • 支持带参数的 ls 命令(如 ls *.txt)
  • 格式化输出结果

3. cat 命令

  • 查看指定文件的内容
  • 支持逐行显示文件内容
  • 处理文件不存在或权限不足的情况

4. pwd 命令

  • 显示当前工作目录
  • 使用 shell 命令执行 pwd
  • 获取并返回当前路径
笔记生成

1. 笔记格式

  • 使用 Markdown 格式
  • 包含标题、内容和标签
  • 支持多级标题
  • 支持代码块

2. 内容生成

  • 根据执行结果生成内容
  • 使用 LLM 进行内容摘要和总结
  • 避免重复内容
  • 跳过许可证和版权信息

3. 保存笔记

  • 将笔记保存到指定目录
  • 自动生成文件名(包含时间戳)
  • 确保文件不被覆盖
扩展性与维护性

1. 功能扩展

  • 通过 ChainFactory 和 PromptFactory 实现功能扩展
  • 支持添加新的命令处理逻辑
  • 支持添加新的笔记生成模板

2. 状态扩展

  • 支持添加新的机器人状态
  • 支持添加新的状态切换逻辑

3. 日志记录

  • 使用 debug_log 记录运行日志
  • 支持不同级别的日志输出
  • 方便调试和维护
未来改进

1. 增加命令支持

  • 支持更多的文件系统命令(如 mkdir、rm、cp 等)
  • 增强命令处理的灵活性

2. 优化笔记生成

  • 提高笔记内容的质量和准确性
  • 支持多种笔记生成模板
  • 增强 LLM 的使用效果

3. 增强错误处理

  • 提供更详细的错误信息
  • 支持错误_recovery 机制
  • 提高系统的健壮性

4. 用户界面优化

  • 提供更友好的用户界面
  • 支持交互式操作
  • 提高用户体验
总结

文件系统探索机器人是一个功能强大且灵活的工具,能够帮助用户高效地探索和记录文件系统中的内容。通过支持多种文件系统命令、生成结构化笔记、管理系统状态等功能,该机器人在文件系统探索和文档生成方面具有广阔的应用前景。未来可以通过扩展命令支持、优化笔记生成、增强错误处理和优化用户界面等方式进一步提升其功能和用户体验。

项目使用到的所有代码均已开源,欢迎各位大佬一起交流

https://github.com/pikasTech/...

Image

END

原文:裸机思维

专栏推荐文章

如果你喜欢我的思维,欢迎订阅裸机思维欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。
推荐阅读
关注数
1491
内容数
124
探讨嵌入式系统开发的相关思维、方法、技巧。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息