从模型到落地:AI 认知架构全景与编排实战(含 RAG、Dify/LangChain、沙箱与提示词)

139 阅读45分钟

agent的全景认知和一个node沙盒小工具


一、AI 认知模型全景视图

┌─────────────────────────────────────────────────────────────┐
│  应用层 (Application)                                        │
│  Manus · ClawBot  · 垂直领域 Agent              │
├─────────────────────────────────────────────────────────────┤
│  编排层 (Orchestration)                                      │
│  Dify(低代码) · LangChain(编程框架) · LangGraph(状态机)        │
├─────────────────────────────────────────────────────────────┤
│  记忆层 (Memory)                                             │
│  Vector DB · RAG · 上下文压缩 · 长期记忆机制 · Milvus          │
├─────────────────────────────────────────────────────────────┤
│  模型层 (Foundation Model)                                   │
│  GPT-4o · Claude · DeepSeek · 多模态大模型                    │
└─────────────────────────────────────────────────────────────┘

未来的 AI 应用不是「大模型单打独斗」,而是「记忆 + 规划 + 工具」的认知架构竞争。

我们该在未来的 AI 时代中何去何从?我认为是借助 AI 的能力,去实现类似于 ClawBot 这种 AI 应用,解决模型到落地的最后一公里问题。


二、认识模型:从 DeepSeek 的开放平台开始

这里会给大家介绍两个平台:

  1. DeepSeek 开放平台api-docs.deepseek.com/zh-cn/参数较少,适合初步认知。
  2. 阿里云百炼阿里云百炼控制台 类似 OpenAI,模型丰富、支持自定义调试,文档详细,适合高自定义、多 Agent 协作等场景。

一般会有 Base API(用于访问模型),需要填入生成的 API Key(密钥)。根据所用框架或编排工具,选择对应的模型名,如 DeepSeek 的 Chat 模型Reasoner 模型,各有侧重点。

1770002384080.png

除此之外,一般还会有**温度(Temperature)**设置,可以理解为模型的「创意开关」或「发散程度调节器」,核心是概率分布的尖锐度。

温度越低,模型越像「严谨的老师」;温度越高,模型越像「喝醉的诗人」。

温度值特征典型应用输出特点
0 - 0.3确定性/保守代码生成、数学计算、知识问答、JSON事实准确、逻辑严谨,可能机械、缺乏变化
0.4 - 0.7平衡通用对话、写作辅助、商业文案正确性与自然流畅度兼顾
0.8 - 1.2创造性创意写作、头脑风暴、诗歌、角色扮演词汇丰富、想象力强,可能跑题
> 1.5混乱/发散艺术实验、随机灵感、对抗性测试可能荒诞、跳跃、非逻辑

三、现代模型进化的四大共同趋势

  1. Agentic 能力(自主代理)所有模型都在强化工具调用链、多步骤规划、环境交互能力。Gartner 将 Agentic AI 列为 2025 年顶级战略技术趋势,预计年增长率 40%(来源)。
  2. 推理架构的显性化不再隐藏思考过程,而是提供「思考模式」(Thinking/Deep Think)开关,让用户在速度与深度间权衡,代表从模式匹配到结构化推理的范式转移。
  3. 上下文窗口的军备竞赛从 256K(Kimi)到 400K(GPT-5)再到 1M(Claude),目标都是实现**「整本书/整个代码库」的一次性处理**,降低对 RAG 精度的依赖。
  4. 垂直专业化与成本分层 同一模型家族内部分化出标准版(推理)、Mini 版(成本)、Nano 版(延迟),通过自动路由为用户匹配最优性价比。

以上是结合当前模型更新汇总的结论:主流模型主要在工具调用、推理架构、上下文、成本四个方向优化。

下文将围绕 AI 工具调用展开:为什么各大模型厂商都重视它,以及它由哪些解决方案组成。

对于生产级模型落地(而非简单 API 调用),记忆层和编排层是概念上必须经过的两大关卡。即使没有显式使用 Milvus 或 LangChain,系统也必然要实现这两层的等效功能(哪怕用代码硬编码)。这两者都是编码层面具有代表性的工具,我们可以不直接用,但需要理解其思想。


四、记忆层:解决「模型天生健忘」的硬伤

基础大模型是**无状态(Stateless)**的——每次 API 请求独立,不会记得 5 分钟前的对话,更无法记住上周的业务数据。

落地时必须处理的问题:

  • 上下文稀缺:即便 GPT-5 支持 400K tokens,全量塞进上下文既贵又慢,且无法跨会话保持。
  • 知识过时:模型训练数据有截止日期,需要 RAG 接入实时知识库。
  • 个性化缺失:没有记忆层,每次对话从零开始,无法「越用越懂你」。

大量上下文会带来:一、干扰多,结论不精确;二、token 消耗大、分析时间更长;三、难以对企业内部资源做有效整合。

落地形态对比:

简单玩具生产级落地
直接塞历史消息到 messages 参数向量数据库(Milvus/Pinecone)存储海量文档
用全局变量存临时状态长期记忆机制(如 MemGPT)管理记忆优先级
不管 token 消耗上下文压缩(RAG 重排序、摘要机制)控制成本

本质:记忆层是让模型从「考试机器」变成「业务专家」的基础设施。没有它,模型只能回答通用问题,无法处理企业私有知识或保持连续性。我们下面主要来讲rag模式 还有history管理方案 这个则是在各个编排工具内各有内置的方案 我们在此不做深入研究


4.1 什么是 RAG(Retrieval Augmented Generation)

RAG(检索增强生成)结合了信息检索与文本生成,在大模型生成答案时利用外部知识库中的相关信息。效果由三个核心阶段决定:

引用:阿里云 RAG 检索说明

  1. 建立索引:知识的解析、切片与向量化。
  2. 检索召回:根据用户查询(Prompt),从向量存储中匹配并召回相关知识片段。
  3. 生成答案:大模型根据召回片段与用户查询,生成最终答案。

1770003943187.png

在 LangChain 官网,RAG 架构分为三种模式,层层递进。


4.2 RAG 流程一:建立索引(Indexing)

  1. **Loader(加载)**通过文档加载器加载文档,主要完成读取文件。
  2. Split(拆分)文本拆分器将大型 Document 拆成更小的块,便于索引和放入模型有限的上下文窗口。若文档超过约 42000 字符,对多数模型过长;即使能塞进上下文,极长输入下也难定位关键信息,因此需要先切块再嵌入与存储。
  3. 存储 通过向量存储嵌入模型将切分后的内容向量化并存入(如 Milvus),便于检索。

文本如何变成向量? 通过 Embeddings 模型将文本转为向量,再写入 Milvus 等向量数据库,供 AI 检索。

示例:

Dimension of embeddings: 1536
Input: 风急天高猿啸哀, embedding is: [-0.0016666285653348784, 0.008690492014557004, ...]
Input: 渚清沙白鸟飞回, embedding is: [0.018255604113922633, 0.030631669725945727, ...]
Input: 无边落木萧萧下, embedding is: [-0.01270165436681136, 0.011355212676752505, ...]
Input: 不尽长江滚滚来, embedding is: [0.003449439128962428, 0.02667092110022496, ...]

4.3 RAG 流程二:检索与生成 —— Agent 调用向量数据库

检索的本质:语义匹配

当用户问:「公司的年假怎么休?

  • 传统搜索:在数据库里找包含「年假」关键词的文档(可能漏掉「带薪休假」「年休假」等同义表达)。
  • 向量检索
    • 把问题转成向量(Embedding),如 [0.023, -0.151, 0.892, ...](768 维或 1536 维)。
    • 在 Milvus 中计算余弦相似度,找到向量距离最近的文本块。
    • 返回 Top 5 最相关段落(即使没出现「年假」二字,语义相关也能找到)。
把检索封装成「工具」(Tool)

Agent 默认没有查库能力,需要把检索包装成**工具(Tool)**才能调用。在提示词中说明:当问题属于某类时,使用向量数据库做相似度搜索,返回相关片段;Agent 整合搜索结果后,由大模型生成答案。向量库也可在此阶段加筛选条件,在百万级数据场景下很有用。

完成上述两步,即得到一个基础的 RAG 检索流程,在 LangChain 官网称为 2-Step RAG(两步检索增强生成)

此外还有两种进阶方式:

  1. **Agentic RAG(智能体检索增强生成)**由大模型判断是否需要文档/数据库查询、网络 API 等外部调用,再决定调用哪些工具。

  2. Hybrid RAG(混合检索增强生成)在标准模式基础上加入多重校验

    • 对问题做评估(可调用 Agent/工具),若判断问题不合理则改写后重查;
    • 对检索结果用 Agent 评估,不合标准则重新检索;
    • 由 AI 自行判断错误并从对应节点重新开始。

4.4 三种 RAG 模式概览

方案 A:标准模式(2-Step RAG)

「先查资料,再回答」——简单直接。

工作流程:

  1. 用户提问:「今年的差旅报销标准是什么?」
  2. 系统自动在知识库找到《财务制度》第 3 章相关内容。
  3. AI 基于该内容生成回答,并标注来源。

核心价值:

  • :固定流程,一次检索 + 一次生成,响应在 2 秒内。
  • 省成本:步骤简单,调用 AI 次数少。
  • :结果可预测,不会「乱翻书」。

方案 B:智能模式(Agentic RAG)

「让 AI 自己决定要不要查资料」。

工作流程:

  1. 用户复杂提问:「对比我们公司和竞争对手在华东区的定价策略差异,并给出建议。」
  2. AI 自主分析:「需要分三步:先查内部定价表(工具1),再查竞品公开信息(工具2),最后做对比分析。」
  3. AI 按需调用多个工具,层层推进,最终生成报告。

核心价值:

  • 灵活:复杂问题能「见招拆招」。
  • 多工具协作:可查文档、计算器、数据库、实时网页等。
  • 类人思维:先收集信息再下结论。

方案 C:质控模式(Hybrid RAG)

「查完还要验,错了就重来」——带质检的严谨方案。

工作流程:在标准模式基础上加入三重校验

  1. 问题优化:用户问得模糊?先改写成更精准的问题(如把「那个谁」改为「张三」)。
  2. 检索验证:查到内容是否相关?若不相关,自动换关键词重查。
  3. 答案核查:生成回答是否符合事实?若有矛盾,重新生成或标注「存疑」。

核心价值:

  • 风险可控:每步有校验,减少用错误信息作答。
  • 自我修正:发现答非所问或信息不足时,可自主优化流程。
  • 审计友好:全程可追溯,知道参考了哪些资料、为何这样答。

五、编排层

模型和记忆都有了,还要有人决定:什么时候调模型、什么时候查库、什么时候调工具、顺序怎么排——这一层就是编排层。好比上文的rag的生成 什么时候去查询向量数据库 如何对问题进行分析 如何评估搜寻的结果是否满意 我们需要借助编排工具去实现 ,当然 在下一层的manus 或者 clawbot (openclaw),他们并没有使用这里编排工具的一种,而是自己搭建的编排工具

5.1 主流编排工具对比(GitHub Stars 与优缺点)

以下为当前较主流的四类编排工具,兼顾可视化/低代码编码/框架两种路线,便于按团队习惯选型。

工具类型GitHub Stars优点缺点
Dify可视化 / 低代码平台128k工作流 + RAG + Agent 一体;可视化画布、Prompt IDE;50+ 内置工具;Docker 一键部署、多模型支持;LLMOps 与观测完善自托管需自行维护;企业级能力依赖商业版;偏「平台」思维,深度定制要理解其抽象
LangChain编程框架(Python/JS)126k生态最大、文档与社区成熟;可编程、灵活度高;与 LangGraph、LangSmith 等配套;模型/向量库/工具集成丰富学习曲线陡;版本迭代快、API 易变;偏开发者,无开箱即用的可视化编排
AutoGen多智能体编程框架54.2k多智能体对话与协作原生支持;微软背书;支持 MCP、AgentTool 等;提供 AutoGen Studio 可做低代码原型官方建议新人关注 Microsoft Agent Framework;维护重心可能向新框架倾斜;纯代码编排需一定 Python 能力
Coze Studio可视化 Agent 开发平台19.7k脱胎于字节 Coze,一站式可视化;插件、知识库、工作流、API/SDK 齐全;Go 后端 + React/TS 前端,DDD 架构,便于二次开发相对较新,生态小于 Dify/LangChain;需自建并配置模型;公有云能力与商业版有差异

选型参考:要快速搭 Demo、少写代码优先看 Dify 或 Coze Studio;要全代码控制、对接自有系统优先 LangChain / LangGraph;要做多 Agent 协作、研究向可看 AutoGen 或 LangGraph。


5.2 重点了解:Dify 与 LangChain

下文主要围绕 DifyLangChain 两种编排方式展开,并举例说明各自适用场景。得益于 MCP 等协议的发展,两者并非互斥,而是形成很好的互补关系

  • 简单到中等复杂度的 AI 应用:适合用 Dify(可视化、少写代码、快速上线)。
  • 高度复杂、强定制的应用:适合用 LangChain(全代码控制、深度集成业务、自定义链与 Agent)。

编排工具会不断更新、被更好的替代,但编排逻辑AI 相关概念(记忆、分类、流式、并行、Agent 汇总等)是通用的——这些思想可以套用在 Dify 上,也值得长期学习。


5.3 Dify 简介:能帮我们做什么?

Dify 是低代码/可视化编排工具。借用官网描述:

Dify 是一个用于构建 AI 工作流的开源平台。通过在可视化画布上编排 AI 模型、连接数据源、定义处理流程,直接将你的领域知识转化为可运行的软件。

能力概览:支持本地化部署;可使用插件能力对接外部 API/数据库;通过模板节点输出结构化数据(如 JSON),便于前端或下游系统处理。了解这些,就能快速搭建以下几类场景。


5.4 Dify 场景示例

  1. 表单预填用户进入表单页时,调用插件查询近几次提交或用户偏好,经模板节点输出预填数据(如 JSON),前端解析后填充表单。要点:插件查数据 + 模板节点出结构化结果,方便对接。
  2. 文本片段补全根据前文内容补全后续文本。创建 Chatflow 并开启流式输出,用代码节点做后处理使输出更可控;用问题分类器节点将请求路由到最合适的场景;启用记忆,在分类与补全时带入对话历史,提高多轮准确性。实际可做成「每输入一段或停顿一段时间再触发补全」,以平衡体验与成本。
  3. 长文本汇总助手 文本量大时,用多个输入节点对长文分块、并发处理,最后汇聚到一个 Agent 节点做汇总。并发能缩短总耗时(整体处理速度/吞吐提升),并可能因分块聚焦而提高汇总质量。

以上示例体现了 Dify 中插件、模板、流式、分类、记忆、并行与汇聚等编排思想,这些概念在 LangChain 等框架中同样存在,只是实现方式从「画布拖拽」变成了「代码编排」。


5.5 LangChain 简介

LangChain 是编程优先的 AI 应用编排框架(支持 Python / JavaScript),通过代码组装模型、提示词、工具、记忆与向量库等组件,构建可复用的链(Chain)与智能体(Agent)。借用官网定位:

LangChain 是构建 LLM 应用的平台。它通过统一的接口连接模型、嵌入、向量存储、检索与工具等,让开发者快速从原型迭代到生产,并随技术演进保持可扩展。

与 Dify 的对比:Dify 用画布和节点完成编排,LangChain 用代码定义每一步——链式调用、条件分支、工具选择、多轮记忆等都由你显式控制,适合需要深度定制、对接自有系统或实现复杂 Agent 逻辑的场景。

核心概念速览

  • Chain:把提示词、模型、解析等步骤串成一条流水线(如 RAG 链:检索 → 拼上下文 → 调用模型 → 解析输出)。
  • Agent:由模型根据当前输入决定「下一步调用哪个工具、传什么参数」,多步推理与工具调用循环进行。
  • Tool:可被 Agent 调用的能力单元(查库、调 API、执行代码等),在 LangChain 中通常封装为函数并绑定到模型。
  • Memory:在对话或链式调用中持久化/读取历史(如缓冲记忆、摘要记忆),供多轮对话或长流程使用。

下面列举 LangChain 的实际使用场景及简要实现思路。

  1. API 文档分析,生成 Mock 接口Chain 串联:解析文档(如 OpenAPI/Swagger)→ 提取路径、参数、响应结构 → 用 LLM 生成对应 Mock 数据或 Mock 服务代码;可配合模板和校验步骤,保证输出格式稳定。
  2. 低代码平台 AI 生成自定义组件Agent + Tool:把「读设计稿/需求描述」「查组件库 API」「写代码」「执行预览」封装成 Tool,由模型按需调用;多轮时可启用 Memory 记住已选组件和约束,保证风格一致。
  3. 自动化运维部署、仓库管理Agent + Tool:将执行命令、读仓库状态、发 MR、查流水线等封装为 Tool,由 Agent 根据自然语言指令选择并执行;复杂流程可用 LangGraph 做有状态编排,或与现有 CI/CD 脚本对接。

延伸:以上场景都是「代码里显式定义每一步」,适合对可控性、可测试性和与现有系统集成要求高的场景。若需要快速出 Demo 或给业务方拖拽式配置,可先用 Dify 搭主流程,再用 LangChain(或通过 MCP 暴露的能力)承接复杂逻辑与自动化,二者形成互补。


六、AI 集成应用与 ClawBot 简介

前文提到的模型层、记忆层、编排层是「能力层」,最终要落到用户能直接使用的应用上。本节说明什么是 AI 集成应用,并以 ClawBot / OpenClaw 为例,说明它们与各层的关系、做了哪些创新,以及自研框架与 Dify/LangChain 等流行框架的异同。更详细的介绍可参考:知乎 · ClawBot 相关讨论

6.1 什么是 AI 集成应用

AI 集成应用指的是:把模型层(推理)、记忆层(RAG/长期记忆)、编排层(何时调模型、何时查库、何时调工具)以及工具能力(填表、发邮件、跑脚本、控制设备等)打包成终端用户可直接使用的产品——例如聊天机器人、个人助理、垂直领域 Agent 等。用户不关心底层用的是哪家模型、哪套向量库,只关心「能对话、能办事、能记住我」。

与分层的关系可以简单理解为:

层次作用与「AI 集成应用」的关系
模型层提供推理与生成能力应用通过 API 调用模型,得到回复或决策
记忆层存储与检索知识、对话历史、用户偏好应用把「要记住什么」「要查什么」交给记忆层,再拼进上下文
编排层决定调用顺序、分支、工具选择应用要么使用现成编排工具(如 Dify、LangChain),要么自研编排逻辑(如 ClawBot)
应用层面向最终用户的产品形态AI 集成应用就站在这一层,整合下层能力,并通过 IM、Web、API 等渠道交付给用户

因此:AI 集成应用 = 在应用层,对模型层、记忆层、编排层(及工具)做整合后的可交付产品。ClawBot / OpenClaw 正是这一类产品——它们没有直接采用前文提到的 Dify 或 LangChain,而是自研了编排与技能体系,从而更贴合「个人助理 + 多渠道 + 本地优先」的定位。

6.2 ClawBot / OpenClaw 简介

ClawBot(后曾用名 Moltbot,开源版本常称 OpenClaw)是一类个人 AI 助手型集成应用,典型特点包括:

  • 可执行实际操作:不限于聊天,能运行命令、填表格、发邮件、控制浏览器与智能家居等,充当「数字个人助理」。
  • 多渠道集成:接入 WhatsApp、Telegram、iMessage、Slack、Discord 等,在用户日常使用的通讯工具里与用户交互,实现「像和真人对话一样」的使用方式。
  • 对话记忆:能记住较长时间的对话内容,并支持主动提醒等能力,依赖自研或集成的记忆机制。
  • 技能系统:通过 AgentSkills 兼容的技能(或类似插件)扩展能力,用户可从 ClawdHub 等技能库发现、安装、更新技能,形成可扩展生态。

这类产品把「模型 + 记忆 + 编排 + 工具」全部收口在一个应用里,用户看到的是「一个助理」,背后则是模型层、记忆层、编排层的协同。

6.3 与模型层、记忆层、编排层的关系

ClawBot / OpenClaw 作为应用层产品,与各层的关系可以概括为:

  • 模型层:通过接入 OpenAI、Claude、DeepSeek 等厂商的 API,获得推理与生成能力;应用负责组请求、解析回复。
  • 记忆层:采用自研记忆方案(例如用 Markdown 文本文件 存储 AGENTS.md、SOUL.md、MEMORY.md、每日记忆日志等),实现长期记忆与人格/行为设定;部分能力在概念上与 RAG/向量库类似,但实现方式更轻量、本地化。
  • 编排层并未使用 Dify、LangChain 等现成编排平台,而是自研编排与调度——例如通过 Gateway 控制平面统一管理消息通道、工具调用与事件触发,相当于「自建了一个小型编排引擎」,以便深度贴合 IM 接入、设备控制、技能加载等需求。

也就是说:他们站在应用层,自己实现了「何时调模型、何时查记忆、何时调哪个技能/工具」的逻辑,从而在架构上与「用 Dify 画布」或「用 LangChain 写链」形成差异:更垂直、更产品化,而不是通用编排平台。

6.4 他们做了什么创新

从公开资料与社区讨论中,可以归纳出以下几类创新点:

方向说明
插件化 / 技能生态从单体演进为插件化架构,模型提供商、技能等解耦为独立模块;通过 ClawdHub 等技能注册表,用户可发现、安装、更新技能,社区可贡献新能力,形成「应用 + 技能市场」的形态。
Gateway 控制平面消息通道、工具调用、事件触发由统一 Gateway 管理,类似「总控/接线员」,便于对接多种 IM 与设备,并统一做鉴权、限流、路由。
本地优先与记忆形态本地优先策略,敏感数据可只存本地;记忆采用 Markdown 文件(如 AGENTS.md、MEMORY.md、每日日志),用户和开发者可直接查看、编辑,透明且可版本管理。
多渠道 + 7×24 待命深度集成 IM,用户在常用聊天工具里即可与 AI 交互;结合自动化与记忆,实现「随时发消息、随时执行任务」的助理体验。
自动化执行深度不限于「聊天 + 查知识」,而是真正执行操作:填表、发邮件、跑脚本、控制浏览器与智能家居等,把「工具调用」做成产品级能力。

这些创新集中在应用形态、编排自研、记忆形态、技能生态、渠道与执行深度上,与「只接一个模型 API」或「只用通用编排平台」的路线有明显区别。

6.5 自研框架与流行框架的异同

维度ClawBot / OpenClaw 自研路线Dify / LangChain 等流行框架
编排自研:Gateway + 自建调度逻辑,不依赖 Dify/LangChain通用编排:Dify 画布、LangChain 链/Agent,可复用于多种应用
定位应用层产品:直接面向终端用户(个人助理、IM 内使用)能力层/中间层:提供编排与集成能力,由业务再封装成应用
记忆自研:Markdown 文件、本地优先,强调可控与可读通用方案:多与向量库/RAG 集成,Dify/LangChain 均支持多种记忆与检索
扩展技能/插件:ClawdHub、AgentSkills 兼容技能,围绕「一个应用」扩展Tool/插件/工作流:Dify 插件与工作流节点、LangChain Tool,围绕「编排能力」扩展
渠道与部署深度集成 IM、本地优先、设备控制等,产品形态固定渠道无关:多为 API/SDK,由接入方决定 Web/IM/内部系统等
底层逻辑相同:仍是「模型 + 记忆 + 工具调用」的认知架构,只是编排与记忆的实现方式自研相同:同样依赖模型 API、记忆/检索、工具调用,只是以通用框架形式提供

小结:ClawBot / OpenClaw 是应用层的 AI 集成应用,在模型层、记忆层、编排层之上做整合;创新点在于自研编排与技能体系、Gateway 控制平面、本地优先的记忆形态、以及多渠道 IM 与深度自动化执行;与 Dify/LangChain 的异同——底层思想一致(模型+记忆+工具),但不自建在现成编排平台上,而是自研框架以更好贴合「个人助理 + 多渠道 + 本地 + 技能生态」的产品目标。


七、沙箱插件功能实现

本节介绍 CLI 中「AI 沙箱」插件的功能与实现思路,便于对内分享。实现基于 LangChainToolAgent 调用LangChain Tools 概念),用自然语言驱动「生成代码 → 沙箱执行」的闭环。

7.1 沙箱的概念:为什么需要沙箱

沙箱(Sandbox) 在这里指:在一个隔离的运行时环境里执行由 AI 生成的代码,而不是直接在宿主进程里执行。

  • 为什么要隔离:用户说「生成一个 index.html」或「把当前目录下所有 .txt 里的空格改成下划线」时,我们会让模型生成一段 JavaScript 代码,再由程序执行。若这段代码直接在宿主 Node 进程里跑,一旦模型生成 require('child_process').execSync('rm -rf /') 或访问敏感环境变量,就会对真实系统造成风险。沙箱的作用是限制执行环境:只暴露我们允许的 API(如 createFilereadFilelistDir),不暴露完整的 requireprocess.env 等,从而把「AI 生成的代码」和「真实系统」隔开。
  • 本项目的沙箱实现:使用 vm2 库,把一段「沙箱全局对象」(包含 __workspacefspathcreateFilereadFile 等)注入到 VM 里,模型生成的代码只能访问这些对象;执行时用 IIFE 包裹代码以便支持顶层 return,执行结果或异常由宿主捕获后返回给用户。这样既能让 AI「写代码办事」,又不会越权操作宿主。

7.2 功能概述

  • 入口st sandbox <指令...>,例如 st sandbox 生成一个 index.htmlst sandbox 把当前目录下所有 .txt 里的空格改成下划线
  • 行为:根据用户指令,由调度模型决定是「执行代码/操作文件」还是「纯问答」;若需执行代码,则再调用一次模型,根据沙箱环境说明生成可在沙箱中运行的 JavaScript 代码,经语法校验后在 vm2 沙箱中执行,并将结果返回给用户。
  • 特殊处理:若生成的代码会启动 HTTP 服务(如 app.listen),进程会挂起并提示「按 Ctrl+C 停止」,避免服务立刻退出。

7.3 整体流程与 LangChain 概念对应

步骤实现LangChain 概念简述
1. 调度模型根据用户输入决定调用 sandbox 还是 direct_answerTool:把能力封装成工具,模型通过 tool_calls 选择调用;bindTools 将工具绑定到模型。
2. 生成代码沙箱工具内再调用一次模型,传入「沙箱环境说明」+ 用户指令,得到代码字符串SystemMessage / HumanMessage:构造对话;model.invoke(messages):同步调用模型。
3. 执行与回传在 vm2 中执行代码,将 stdout/返回值拼成字符串,作为ToolMessage 回传给模型ToolMessage:工具执行结果必须用 tool_call_id 与之前的 tool_calls 对应,模型据此继续推理或结束。

多轮逻辑:命令里用 messages 数组累积 HumanMessage → AIMessage(含 tool_calls)→ ToolMessage → …,循环 model.invoke(messages) 直到模型不再发起 tool_calls,即完成一轮「调度 → 执行 → 回复」。

7.4 命令入口:调度 Agent 与工具循环

命令定义在 src/bin/command/agentCommand/sandbox.ts。核心:绑定两个 Tool,用系统提示词约束「何时调沙箱、何时直接回答」。

// 调度提示:需要动文件/跑代码 → sandbox;纯问答 → direct_answer
const DISPATCHER_SYSTEM_PROMPT = `你是调度助手:根据用户输入决定「要不要执行代码」,并只调用一个工具。
规则:
1. **需要执行代码/操作文件时** → 调用 \`sandbox\`,把用户的整句指令原样传入。
2. **纯问答、不需要动文件或跑代码时** → 调用 \`direct_answer\`,用 \`answer\` 参数给出简短回答(1~3 句话)。
3. 只调用一个工具,不要同时调用两个。`;

const tools = [sandboxTool, answerTool];
const model = createModel().bindTools(tools);
const messages = [new SystemMessage(DISPATCHER_SYSTEM_PROMPT), new HumanMessage(instruction)];
const response = await model.invoke(messages);
// 若有 response.tool_calls,则执行对应工具,把结果 push 成 ToolMessage,再 invoke(messages),循环
  • bindTools(tools):LangChain 中把「可调用的工具列表」绑到模型上,模型输出中会包含 tool_calls(工具名 + 参数)。
  • ToolMessage:构造时需传入 tool_call_id(与 AIMessage 中某条 tool_call 的 id 一致),这样模型才能把「这条工具结果」与「哪一次调用」对应起来。

7.5 Tools 如何写、为什么这么写

工具定义在 src/bin/langchain/tools/sandbox.ts。我们只暴露两个 Tooldirect_answer(纯问答)和 sandbox(执行代码/操作文件)。模型通过 tool_calls 选择调用哪一个,并传入对应参数。下面用实际代码说明怎么写以及为什么这么写

7.5.1 为什么只有两个 Tool?

调度层只需要做二选一:「用户是在问问题」→ 用 direct_answer 直接回答;「用户要动文件或跑代码」→ 用 sandbox 生成代码并在沙箱里执行。若只给一个「万能工具」,模型容易在纯问答时也去调沙箱,增加延迟和误执行风险;若拆成很多小工具(如「创建文件」「读文件」「执行命令」),调度模型要做的选择太多,容易选错。因此两个工具、职责清晰,便于在系统提示词里写清「何时调哪个」。

7.5.2 answerTool:纯问答工具
import { tool } from "@langchain/core/tools";
import { z } from "zod";

export const answerTool = tool(
  (args: { answer: string }) => args.answer,
  {
    name: "direct_answer",
    description:
      "仅用于纯问答:用户只是提问、解释、闲聊,不需要创建/修改/删除文件或执行任何代码时使用。回答必须简短(一两句话到一小段),不要长篇大论。",
    schema: z.object({
      answer: z.string().describe("简短回答,控制在 1~3 句话内,不要过长"),
    }),
  }
);
  • name:模型在 tool_calls 里通过这个名字选中该工具;写成 direct_answer 与调度提示词里的「调用 direct_answer」一致。
  • description最关键。LangChain 会把 description 发给模型,模型据此判断「当前用户输入是否属于纯问答」。这里明确写了「仅用于纯问答」「不需要创建/修改/删除文件或执行任何代码」「回答必须简短」,模型才会在用户问「什么是 RAG」时调这个工具,而不是调 sandbox。
  • schema:用 zod 声明参数。模型不会「自己发明」参数名,而是按 schema 里的字段生成 JSON;这里只有 answer 一个字符串,模型就会把要回复给用户的话放进 answer,我们直接 args.answer 返回即可。不写 schema 的话,模型不知道要传什么参数,容易不传或传错。
7.5.3 sandboxTool:沙箱执行工具
export const sandboxTool = tool(
  async (args: { instruction: string }) => {
    const { instruction } = args;
    // 1. 构造沙箱专用对话,让模型生成代码
    const messages = [
      new SystemMessage(SANDBOX_SYSTEM_PROMPT),
      new HumanMessage(instruction),
    ];
    const res = await model.invoke(messages);
    const responseText = typeof res.content === "string" ? res.content : String(res.content ?? "");
    // 2. 解析代码 + 是否 HTTP 服务
    const { code, isHttpService } = parseCodeFromResponse(responseText);
    if (!code) return `未能从模型回复中解析出代码。...`;
    // 3. Acorn 语法校验
    const validation = validateSyntax(code);
    if (!validation.ok) return `语法校验失败:${validation.message}`;
    // 4. 在沙箱中执行
    try {
      const result = await runInSandbox(code);
      // 格式化结果,若为 HTTP 服务则加前缀供命令层挂起进程
      return isHttpService ? SANDBOX_HTTP_SERVICE_PREFIX + body : body;
    } catch (err) {
      return `沙箱执行错误:${msg}`;
    }
  },
  {
    name: "sandbox",
    description:
      "仅当用户需要「执行代码/操作文件」时使用:例如创建/修改/删除文件、生成 HTML、批量重命名、运行 shell 命令、读目录等。不需要动文件或跑代码时不要调用。",
    schema: z.object({
      instruction: z
        .string()
        .describe("用户的自然语言指令,例如:生成一个 index.html;或:把当前目录下所有 .txt 文件名里的空格改成下划线"),
    }),
  }
);
  • namesandbox,与调度提示词里「调用 sandbox」一致。
  • description:明确写「仅当用户需要执行代码/操作文件时使用」,并举例(创建/修改/删除文件、生成 HTML、批量重命名、运行命令、读目录),最后强调「不需要动文件或跑代码时不要调用」。这样模型才会在用户说「生成一个 index.html」时调 sandbox,在用户说「什么是 RAG」时不调。
  • schema:只有一个参数 instruction,类型为 string,describe 里给了示例。调度模型会把用户的整句指令原样放进 instruction,sandboxTool 内部再拿这句 instruction 去调第二次模型(生成代码的那次),这样「调度」和「生成代码」解耦:调度只负责选工具+传参,生成代码由沙箱专用的 system prompt(SANDBOX_SYSTEM_PROMPT)约束。
  • 为什么工具内部再调一次模型? 因为「生成可在沙箱中执行的 JavaScript」需要另一套提示词(沙箱环境说明、默认目录、HTTP 服务标记等),和「调度:选 sandbox 还是 direct_answer」的提示词不同。所以设计成:调度模型只做二选一并传 instruction;sandboxTool 内部用 SANDBOX_SYSTEM_PROMPT + instruction 再 invoke 一次模型,得到代码后再校验、执行、返回。这样职责清晰,也便于单独调优沙箱侧的提示词。
7.5.4 sandboxTool 内部四步(简要)
  1. 构造沙箱专用对话SystemMessage(SANDBOX_SYSTEM_PROMPT) + HumanMessage(instruction)。SANDBOX_SYSTEM_PROMPT 由 getSandboxPromptContext("markdown") 生成,限制模型只使用沙箱内列出的 API。
  2. 解析模型回复:从回复中提取 ```js ... ``` 或裸代码,并判断是否包含 __IS_HTTP_SERVICE__ 或代码中是否有 .listen(,用于后续是否挂起进程。
  3. Acorn 语法校验:在进入 vm2 前用 acorn 做一次 parse,避免明显语法错误在沙箱里报错不明确或卡死。
  4. runInSandbox(code):调用沙箱模块执行代码;若为 HTTP 服务,在返回内容前加上 SANDBOX_HTTP_SERVICE_PREFIX,命令层检测到后挂起进程。

7.6 沙箱相关提示词:为什么要这么写

沙箱功能里用到两套提示词:一套在命令层做调度(选 sandbox 还是 direct_answer),一套在沙箱工具内部做代码生成(只生成可在沙箱中执行的 JavaScript)。两套职责分离,便于单独调优。下面分别贴出关键内容,并说明为什么要这么写。对应代码位置:src/bin/command/agentCommand/sandbox.ts(调度)、src/bin/langchain/sandbox/prompt.ts(沙箱环境说明)、src/bin/langchain/tools/sandbox.ts(代码生成规则拼接)。


7.6.1 调度提示词(DISPATCHER_SYSTEM_PROMPT)

完整内容sandbox.ts 命令入口):

你是调度助手:根据用户输入决定「要不要执行代码」,并只调用一个工具。

规则:
1. **需要执行代码/操作文件时** → 调用 `sandbox`,把用户的整句指令原样传入。例如:创建/修改/删除文件、生成 HTML、批量重命名、列目录、运行命令等。
2. **纯问答、不需要动文件或跑代码时** → 调用 `direct_answer`,用 `answer` 参数给出简短回答(1~3 句话,不要长篇大论)。
3. 只调用一个工具,不要同时调用两个。不要输出过长文本。

为什么要这么写

部分作用不这么写的后果
角色「你是调度助手」让模型只做「二选一」决策,不越权去解释或生成代码模型可能既调工具又自己啰嗦一大段,或去「猜」用户意图时输出长文
任务「根据用户输入决定要不要执行代码,并只调用一个工具」明确输出形态:只产生一次 tool_calls,且只选一个工具可能同时调 sandbox 和 direct_answer,下游难以处理;或多次调用增加延迟
规则 1「需要执行代码/操作文件时 → 调用 sandbox,整句指令原样传入」与 Tool 的 name: "sandbox" 一致;举例(创建/修改/删除文件、生成 HTML、批量重命名等)帮助模型判断「何时算需要动文件」模型容易在纯问答时也调 sandbox,或把指令改写成自己的话导致语义漂移
规则 2「纯问答时 → 调用 direct_answer,answer 参数 1~3 句话」与 Tool 的 name: "direct_answer" 和 schema 里的 answer 一致;约束长度便于终端展示纯问答时模型可能调 sandbox 或输出过长,影响体验和 token
规则 3「只调用一个工具,不要输出过长文本」强化「只选一个」和「不附带长文」,避免模型在 tool_calls 之外再输出大段说明容易出现「调了工具又输出好几段话」或一次多个 tool_calls

总结:调度提示词的核心是角色单一(调度)、任务清晰(二选一)、规则与 Tool 的 name/schema 一一对应,这样模型才会稳定地「只选一个工具、传对参数」。


7.6.2 沙箱环境说明(prompt.ts:SANDBOX_SCHEMA / getSandboxPromptMarkdown)

作用:在沙箱工具内部,把「沙箱里有哪些全局对象/函数、怎么用」写成 Markdown(或 JSON),通过 getSandboxPromptContext("markdown") 拼进 SANDBOX_SYSTEM_PROMPT 的前半部分,让生成代码的那次模型只使用这些 API,不写 require('fs')require('path') 等(沙箱里没有原生 require)。

为什么要这么写

  • 按类别分块(Node 内置、异步、Web 框架、子进程、便捷 API):模型按「要找什么能力」快速定位,减少幻觉(例如去用未暴露的 API)。
  • 写清默认操作目录「默认使用当前命令行所在目录(即 __workspace);路径用相对路径」:避免模型生成绝对路径或假设别的 cwd,导致执行时报「文件不存在」。
  • 便捷 API 用表格列出(createFile、readFile、listDir、rename、remove 等):表格比大段文字更利于模型「按名选用」,且与 common.ts 里真实暴露的函数一致;对易错点(如「改文件名时用 rename,不要只 createFile 新路径」)单独写一句,减少同一内容两份文件。
  • 启动服务、修改文件名等单独强调:因为模型常犯「只生成文件不 listen」或「只 createFile 新路径不删旧文件」的错,所以在环境说明里就约束好,比只在后面「要求」里写更醒目。

对应代码:src/bin/langchain/sandbox/prompt.ts 中的 SANDBOX_SCHEMA(JSON 化配置)、getSandboxPromptMarkdown()(生成给模型看的 Markdown);工具里用 getSandboxPromptContext("markdown") 取这段,再拼上下面的「要求」部分。


7.6.3 沙箱代码生成规则(SANDBOX_SYSTEM_PROMPT 后半部分)

在「沙箱环境说明」之后,工具里拼接的要求src/bin/langchain/tools/sandbox.ts 中的 SANDBOX_SYSTEM_PROMPT)如下,并说明每条为什么要这么写

---
请根据用户的自然语言指令,生成一段可在上述沙箱中执行的 JavaScript 代码。
要求:
1. 只输出代码,不要解释或 markdown 标题。
2. 代码中只能使用上文列出的全局对象和函数。
3. 若需要返回结果给用户,请用 return 或 console.log。
4. 可以包在 ```js ... ``` 里,也可以直接输出裸代码。
5. 如果你认为执行后有重大错误请直接返回 "执行失败"。
6. **默认操作目录**:如果用户没有指定在哪个目录操作,默认使用当前命令行所在目录(即 __workspace);路径用相对路径如 '.' 或 '文件名' 即可。
7. **启动服务型项目时**:尽量在沙箱内完成,单段代码中完成应用创建、路由、app.listen 等,不要只生成文件让用户自己运行或依赖沙箱外的步骤;用 app.listen(port, () => console.log('http://localhost:' + port)) 打印地址,代码末尾不要 return。
8. **若本次生成的代码会启动 HTTP 服务**(如 Koa/Express 的 app.listen),请在代码块后单独一行写 __IS_HTTP_SERVICE__,以便宿主进程挂起(用户 Ctrl+C 停止)。
9. **修改文件名或格式时**:用 rename(oldPath, newPath) 重命名,或先 readFile 再 createFile 新路径后 remove 原文件;不要只 createFile 新路径而保留原文件,避免同一内容有两份。

为什么要这么写

目的不这么写的后果
1 只输出代码,不要解释或 markdown 标题便于从回复里稳定解析出「一段代码」;解析逻辑依赖「要么 ```js 块要么裸代码」模型输出大段说明 + 代码,解析容易取错或取到解释文本
2 只能使用上文列出的全局对象和函数与 prompt 前半部分「沙箱环境说明」一致,防止用 require('fs') 等沙箱内不存在的东西生成的代码在 vm2 里报 require is not defined 或访问未暴露 API 报错
3 返回结果用 return 或 console.log宿主通过 IIFE 的返回值或 stdout 拿结果;明确两种出口,模型不会只写中间变量不输出用户看不到执行结果,或解析不到返回值
4 可以包在 ```js 里也可以裸代码解析时两种都支持(parseCodeFromResponse),给模型容错空间若强制只接受一种,模型有时会选另一种导致解析失败
5 认为有重大错误时直接返回 "执行失败"避免模型硬生成明显会报错的代码,让工具层直接返回可读提示容易得到一段必然报错的代码,用户体验差
6 默认操作目录 __workspace,路径用相对路径与 prompt 前半部分一致;和 common.ts 里 createSandbox 的 root 对齐模型生成 /tmp/xxx 或其它绝对路径,在沙箱里路径不对
7 启动服务时在沙箱内完成 listen,不要只生成文件用户说「起一个 Koa 服务」时期望直接能访问,而不是再手动运行只生成 app.js 让用户自己 node app.js,不符合「一条指令完成」的预期
8 HTTP 服务时在代码块后写 IS_HTTP_SERVICE工具和命令层用该标记判断是否挂起进程(不退出),否则服务会立刻退出启动的服务一启动就退出,用户无法访问
9 改文件名用 rename 或 读→写新→删旧与环境说明里「不要只 createFile 新路径」一致,避免同一内容两份文件用户说「把 a.txt 改成 b.txt」时生成两个文件,语义错误

总结:前半部分(prompt.ts)负责能力边界与用法约定,后半部分(工具里拼接)负责输出格式、默认目录、HTTP 服务、重命名等易错约束;两段合在一起,模型才能稳定生成「可解析、可执行、行为符合预期」的沙箱代码。

7.7 沙箱环境与执行引擎

  • 环境定义src/bin/langchain/sandbox/common.ts):createSandbox(workspaceRoot) 返回一个对象,包含 vm2 所需的 sandbox 全局变量——如 __workspacefs/path/process/os/Buffer/util/console/URLPromise/setTimeoutKoa/koaRouterchild_process.execSync/spawnSync,以及便捷方法 createFile / readFile / listDir / rename / remove / copy / move / stat / listFilesRecursive / globFiles / requireFromWorkspace 等。路径未指定时默认为当前命令行所在目录(即 __workspace)。
  • 执行src/bin/langchain/sandbox/index.ts):使用 vm2VM,把上述 sandbox 对象传入;为支持「顶层 return」,将用户代码包成 IIFE 再执行:
const wrapped = `(function() {\n${code}\n})()`;
const result = vm.run(wrapped);
return result instanceof Promise ? await result : result;

这样生成的代码里可以直接 return ...,返回值会交给命令层展示;若 return 的是 Promise,会 await 后再返回。

  • 提示词与 API 说明src/bin/langchain/sandbox/prompt.ts):SANDBOX_SCHEMA 描述沙箱内所有全局对象和函数的类型、参数、示例;getSandboxPromptMarkdown() 将其转成 Markdown 表格和列表,注入到 SANDBOX_SYSTEM_PROMPT,使模型只使用这些 API 生成代码,避免使用未暴露的 Node 或浏览器 API。

7.8 小结

模块作用
sandbox 命令解析 st sandbox <指令>,用调度 Agent + bindTools 在 sandbox / direct_answer 间选择,并循环处理 tool_calls,直到模型不再调用工具;检测 HTTP 服务标记后挂起进程。
sandboxTool根据用户指令调用模型生成沙箱代码 → Acorn 校验 → runInSandbox 执行 → 将结果或错误以 ToolMessage 形式返回。
answerTool纯问答时由模型填入 answer,原样返回给用户。
createSandbox / runInSandbox提供 vm2 沙箱全局环境(含 Node 与便捷文件 API),IIFE 包裹执行并支持 return/Promise。
prompt 与 SANDBOX_SCHEMA把沙箱能力描述成 Markdown/JSON,约束模型只生成合规、可执行的代码。

整体上,这就是一个「自然语言 → 调度 Agent(Tool 二选一)→ 沙箱工具内再调模型生成代码 → 语法校验 → vm2 执行 → 结果回传」的闭环,用到的 LangChain 概念包括 Tool、bindTools、SystemMessage/HumanMessage/AIMessage/ToolMessage、model.invoke,对应官网 ToolsMessages 的用法。


八、提示词工程:如何写好提示词

前面提到的编排、RAG、沙箱等,最终都要通过「和模型说清楚要做什么」才能生效,这部分就是提示词工程(Prompt Engineering)。下面用通俗方式说明其重要性,并给出一套可落地的书写原则,便于在业务里统一规范、减少无效调用。

8.1 为什么提示词重要

模型本身不会「主动知道」业务规则、输出格式或边界条件,这些都需要通过**输入文本(提示词)**显式告诉它。提示词写得好,模型更容易:

  • 做对事:理解任务意图、约束和优先级,减少答非所问或越权行为。
  • 出对格式:便于下游解析(如 JSON、表格、代码块),减少二次清洗。
  • 控制成本与延迟:约束长度、禁止冗长解释,有利于 token 与响应时间可控。

因此,提示词是连接「业务需求」和「模型能力」的接口;写好提示词,是落地 AI 功能时性价比很高的投入。

8.2 如何写好提示词:几条可操作原则

归纳为角色、任务、约束、格式、示例五类要素,按需组合即可。

要素说明示例(一句话)
角色让模型进入「谁在说话」的设定,行为更一致「你是调度助手」「你是只生成代码的沙箱执行器」
任务用一句话说清「要干什么」,避免模糊「根据用户输入决定调用 sandbox 还是 direct_answer」「生成可在沙箱中执行的 JavaScript」
约束明确「不能做什么」「必须怎么做」,减少越界「只输出代码,不要解释」「只能使用上文列出的全局对象」「回答控制在 1~3 句话」
格式规定输出形态,方便解析与展示「返回 JSON」「用```js ... ``` 包住代码」「若启动 HTTP 服务请在代码块后写 IS_HTTP_SERVICE
示例给 1~2 个输入输出样例,大幅提升格式与风格一致性「输入:生成 index.html → 输出:仅一段可执行代码」

书写习惯建议

  • 先写「角色 + 任务」,再补约束和格式,最后需要时加示例。
  • 一条提示词只服务一个目标:调度就只做调度,生成代码就只生成代码,避免混在一起导致模型「不知道该优先听哪句」。
  • 关键规则用加粗或编号,便于模型注意(如「只调用一个工具」「3. 只输出代码」)。
  • 迭代优化:用真实用例跑几轮,看模型常犯的错误(漏约束、格式乱、话太多),再回头改提示词补一句、减一句。

8.3 本文中的提示词实践(对应关系)

  • 调度提示词(七、沙箱插件)角色:调度助手。任务:根据用户输入决定调用 sandbox 还是 direct_answer约束:只调用一个工具、不要长篇大论。这样模型就不会既调工具又自己啰嗦一大段。
  • 沙箱代码生成提示词****角色:沙箱内代码生成器。任务:根据用户指令生成可在给定沙箱中执行的 JavaScript。约束:只使用列出的 API、默认目录为 __workspace、启动服务时标注 __IS_HTTP_SERVICE__格式:可包在 ```js ... ``` 里或裸代码。示例:通过 SANDBOX_SCHEMA / Markdown 表格把「有哪些函数、怎么用」写清楚,等于给了结构化示例。
  • 温度(二、认识模型) 温度虽不是「一句话提示词」,但属于同一类控制:通过参数告诉模型「要更确定还是更发散」。代码/结构化输出用低温度,创意类用稍高温度,本质上也是在「写好」对模型的行为约束。

8.4 参照:业务中使用的提示词示例

下面摘录并整理业务里实际用过的提示词,作为「角色 + 任务 + 约束 + 格式 + 示例」的参照,便于对照前文原则做迭代。

示例一:生成管理后台页面的 Prompt(低代码 / 运营者模块)

角色/任务:让 AI 在「30% 框架内」生成管理后台页面代码,而非凭空创新;需求边界、数据格式、交互范式由人工先锁定。

约束与格式(节选):

  • 1.1 顶部导航栏:用 el-menu,背景色 #409EFF,文字白色,选中时背景加深 10%;左侧预留项目名称插槽(slot="brand");中间菜单项通过数组 NavItems 注入,结构 NavItem { name, route, icon? };暴露事件 @select、@menu-click。Store 的 module 划分、state 形状、mutation 名由人工先锁定,AI 只生成具体 CRUD 逻辑。
  • 1.2 左侧列表区块:点击高亮用 class 切换(.is-active);中间内容区 flex:1 自适应。
  • 1.3 左上角按钮组:添加按钮 el-button + Plus 图标、文字「新增」;搜索框 el-input + Search 图标,v-model 绑定 keyword,触发 @search。
  • 1.4 列表实现:字段校对由人工完成;AI 直接生成固定列数的 el-table,给出 <el-table-column> 骨架,prop 与后端字段保持一致。
  • 1.5 封装 ListTable 组件:外部传入 columns: { key, label, width?, slot? }[];内部维护 rendererMap,按 column.key 映射渲染函数;插槽命名规则 table-[key],如 <template #table-status>

要点:把「要生成什么、用什么组件、数据结构长什么样」写清楚,模型在给定框架内填代码,便于后续人工校对和联调。

示例二:AI 提升学习能力(设计模式 + 注释 + 单测)

角色/任务:用 AI 把「查文档 + 写样板」的时间省下来,在较短时间内给出「带设计模式 + 注释 + 单测模板」的高可维护代码。

约束:先指定设计模式(如 Strategy、Factory、Observer);要求 AI 生成 TypeScript 实现,并逐行补充 JSDoc 与单测用例;对存量代码,可让 AI 按相同模式做渐进式重构,人工只做 Code Review。

示例三:LangChain 调研结论(Function Calling / Multi-Agent / MCP)
  • Function Calling:本地预注册函数,LLM 仅返回 JSON 参数;本地框架负责反射调用。LLM 本身不拥有、也不执行函数——它只是「点名 + 传参」。
  • Multi-Agent 协作:同一进程内可启多个 Agent 实例,每个实例 system prompt 只聚焦单一职责(产品、开发、测试);通过消息队列顺序传递上下文,降低单 Agent 的上下文长度与幻觉概率。
  • MCP(Model Context Protocol):统一「工具描述 + 调用」协议,Agent 通过 MCP 把工具清单发给 LLM,LLM 按 MCP 格式返回调用指令,本地 SDK 再执行真正的 Function Calling。类比:Agent 是顾客,MCP 是菜单 + 点单协议,Function Calling 是后厨实际炒菜。
示例四:智能汇总 diff 生成 commit(工作流描述)

整体流程(一页讲解用):获取 diff 信息 → 使用 LangChain 的 TokenTextSplitter 将文本切分为约 1500 大小的块 → Agent 对片段并发处理、AI 总结 → 将每个片段的结果再喂给 AI,生成 JSON(generalize 描述文本、commitMsg 标准化 commit 信息)→ 命令行确认后提交。

分步要点

  1. 使用 git 获取 diff 信息。
  2. 使用 LangChain 的 TokenTextSplitter 将文本切分为约 1500 大小的模块。为什么要切分:一次数据量过大,直接丢给 Agent 生成速度慢;切分为 chunk 后通过 Promise.all 并发请求,减少等待时间。为什么不选 RAG/向量库:仅对 diff 做一次性汇总,先存向量库再检索过重,不适合。
  3. 用提示词让 AI 对非代码片段做文字性总结,对代码片段读取函数名并生成函数简述,收集成数组。
  4. 将多个片段汇总后的结果再作为提示词传入 AI,数据量小且能通过类型区分「代码」与「描述性文本」。
  5. 让 AI 用该数组生成一个 JSON:generalize 为描述整体的数组(展示为详细项),commitMsg 为标准化 commit 结果;后续用函数确认并调用 git 提交。

以上示例可作为撰写「角色、任务、约束、格式、示例」时的参照,按业务场景裁剪即可。

8.5 小结

提示词工程就是把「要模型做什么、不能做什么、输出长什么样」说清楚;用好角色、任务、约束、格式、示例五类要素,并在实际用例上小步迭代,就能在少改代码的前提下,明显提升模型输出的可用性和稳定性。我们在调度、沙箱、RAG 等环节都已经按这套思路在写提示词,后续新功能也可以沿用同一套规范。