让 LLM 学会审视自己:LangGraph 中 Reflection 与 Reflexion 模式源码剖析

AI Agent框架深度对比:LangChain、AutoGen等19类主流方案选型指南 AI Agent作为人工智能领域的关键技术,其核心在于模拟智能体的感知、规划与执行能力,通过大语言模型(LLM)驱动自主任务分解与决策。这一技术原理使其在自动化工作流、智能助手、数据分析等场景展现出巨大价值。在实际工程实践中,开发者需根据项目需求在灵活性与易用性间权衡,例如LangChain以其强大的工具生态和流程编排能力,成为构建复杂多步骤自动化流程的基石;而AutoGen则通过多Agent对话式协作,特别适合需要反复讨论验证的研究分析场景。本文基于对19类主流框架的深度横评,从核心架构、工具生态、记忆管 阅读详情

一、前言

本篇约1.2万字,阅读时长约30分钟。

随着LLM应用越来越复杂,单轮对话已经很难满足高质量输出的需求。一个常见的痛点是:LLM第一次生成的答案往往不够好——可能遗漏关键信息,可能逻辑不够严密,可能缺乏引用支撑。

那么问题来了:怎么让LLM"回头看看自己写的答案,想想哪里不对,然后改一改"?这就是Reflection模式要解决的事。而Reflexion模式更进一步——不光自己想,还去外面查。本文就来拆解这两种模式在LangGraph上的完整实现。

一、前言二、Reflection与Reflexion:两种反思范式三、Reflection模式源码剖析四、Reflexion模式源码剖析五、两种模式的工程对比六、要点总结

二、Reflection与Reflexion:两种反思范式

Reflection的核心思想很简单:让LLM自己批评自己。

具体来说,它引入了两个角色:

  1. 生成器(Generator):负责写内容
  2. 反思器(Reflector):负责挑毛病

生成器写完,反思器来批,批完生成器再改,如此循环。说白了就是让LLM瞎折腾自己的输出——但折腾完确实变好了。

Reflexion在Reflection的基础上,多了一层外部工具调用。它不光靠LLM自己"想",还会真正去搜索外部信息来验证和补充。

那么Reflexion相比Reflection多了什么:

  1. 结构化输出:通过bind_tools强制LLM输出结构化的AnswerQuestion对象
  2. 工具调用:引入搜索工具,执行search_queries拿回真实信息
  3. 情景记忆(Episodic Memory):每一轮的反思和搜索结果都累积到消息列表中,后续轮次能看到前面的"教训"
  4. 引用机制:修订后的答案必须带数字引用([1] https://...)

简单说,Reflection是"闭卷自我修改",Reflexion是"开卷查证修改"。

两者最核心的差异有三个:

  1. 输出方式:Reflection是纯文本,Reflexion是结构化(bind_tools + Pydantic)
  2. 外部信息:Reflection纯靠LLM脑子里的知识,Reflexion会调TavilySearchResults去外面查
  3. 终止条件:Reflection靠哨兵标记,Reflexion用双闸门

更详细的对比放在第五章。先把两个模式的源码逐行拆开。

三、Reflection模式源码剖析

先看整体拓扑,再逐层拆解。

Reflection拓扑:自我精炼的闭环

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

整条链路只有三个节点:generate、reflect、加一个条件路由should_continue。简单到不能再简单。

1、State设计:一条消息链承载全部记忆

State只维护一个字段——messages列表:

class State(TypedDict):    messages: Annotated[list, add_messages]

add_messages是LangGraph内置的reducer,作用是:每轮generate和reflect产出的新消息会追加到列表尾部,而不是覆盖。

这意味着整个对话历史——请求、初稿、批评、修订稿、再批评——全部累积在一条messages链里。这就是"情景记忆"的载体。

2、Prompt设计:生成器与反思器各司其职

生成器和反思器的Prompt分别长这样:

generate_prompt = ChatPromptTemplate.from_messages([    ("system",     "You are an essay assistant tasked with writing excellent 5-paragraph essays."     " Generate the best essay possible for the user's request."     " If the user provides critique, respond with a revised version."),    MessagesPlaceholder(variable_name="messages"),])reflection_prompt = ChatPromptTemplate.from_messages([    ("system",     "You are a teacher grading an essay submission."     " Generate critique and recommendations for the user's submission."     " If the submission needs NO further revision,"     " append the exact token <<NO_REVISIONS_NEEDED>>"     " at the very end of your critique."),    MessagesPlaceholder(variable_name="messages"),])

注意一个关键设计:反思器的Prompt里埋了一个哨兵标记<<NO_REVISIONS_NEEDED>>。当反思器认为"不用再改了",它会在批评末尾附带这个标记。这是一种确定性的终止信号——不靠关键词猜测,靠精确匹配。

3、generate节点:朴实无华的链调用

generate节点就是一个prompt | model的链调用,包了一层工厂函数:

def make_generation_node(generate) -> Callable[[State], dict]:    def generation_node(state: State) -> dict:        return {"messages": [generate.invoke(state["messages"])]}    return generation_node

工厂函数的目的是让generate这个Runnable可注入——测试时可以传一个假的Runnable进来,不需要真正调用LLM。这是有必要的,否则单测没法跑。

4、reflect节点:角色翻转是精髓

reflect节点干了一件看起来很"诡异"的事——翻转消息角色:

def make_reflection_node(reflect) -> Callable[[State], dict]:    def reflection_node(state: State) -> dict:        cls_map = {"ai": HumanMessage, "human": AIMessage}        # 保留原始请求,翻转之后的所有消息角色        translated = [state["messages"][0]] + [            cls_map[m.type](content=m.content) for m in state["messages"][1:]        ]        res = reflect.invoke(translated)        return {"messages": [HumanMessage(content=res.content)]}    return reflection_node

为什么要翻转?因为反思器的Prompt设定是"你是老师,在批改学生提交的作文"。而实际上之前的作文是AI写的(AIMessage)。

所以需要把AI写的作文伪装成HumanMessage(学生提交),让反思器以为自己在批改学生的作业。反过来,反思器输出的批评,又被包装成HumanMessage返回给生成器。生成器看到的是"用户给了反馈,让我改"。

角色翻转:一场精心编排的双簧  生成器(AI)写作文 → 翻转为 HumanMessage  反思器(AI)批改   → 输出包装为 HumanMessage  生成器收到反馈     → 以为用户要求修改

5、should_continue:什么时候停

终止逻辑只有两条规则,干净利落:

_SATISFIED_MARKER = "<<NO_REVISIONS_NEEDED>>"def should_continue(state: State) -> str:    messages = state["messages"]    if len(messages) > 6:          # 兜底:消息数超限        return END    last = messages[-1]    if isinstance(last, HumanMessage) and _SATISFIED_MARKER in last.content:        return END                  # 满意了,停    return "generate"              # 不满意,回去继续改

个人认为,把检查放在reflect之后而不是generate之后,是一个很务实的改进。因为这样可以直接读到最新的批评,不需要去messages[-2]偷看前一条消息。

6、build_app:把零件拼起来

最后把所有节点和边组装成一张完整的图:

def build_app(*, model=None, generate=None, reflect=None, checkpointer=None):    if generate is None or reflect is None:        if model is None:            model = make_default_model()    if generate is None:        generate = generate_prompt | model    if reflect is None:        reflect = reflection_prompt | model    workflow = StateGraph(State)    workflow.add_node("generate", make_generation_node(generate))    workflow.add_node("reflect", make_reflection_node(reflect))    workflow.add_edge(START, "generate")    workflow.add_edge("generate", "reflect")    workflow.add_conditional_edges("reflect", should_continue, ["generate", END])    return workflow.compile(checkpointer=checkpointer or InMemorySaver())

generate和reflect都是可选注入的。传了就用你传的,没传就从model推导。这种设计让整个图的每个角色都可替换——这是工程上靠谱的做法。

四、Reflexion模式源码剖析

Reflexion的拓扑明显更复杂,多了execute_tools节点:

Reflexion拓扑:带工具调用的反思闭环

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

关键区别在于:draft和revise是两个不同的角色(绑定不同的tool schema),中间还插了一个execute_tools来执行搜索。

1、Schema设计:用Pydantic锁死输出格式

Reflexion用Pydantic模型定义了三种结构化输出,强制LLM按schema吐数据:

class Reflection(BaseModel):    """The actor's self-critique."""    missing: str = Field(description="Critique of what is missing.")    superfluous: str = Field(description="Critique of what is superfluous.")class AnswerQuestion(BaseModel):    """Answer the question: an answer, a reflection, and follow-up queries."""    answer: str = Field(description="~250 word detailed answer to the question.")    reflection: Reflection = Field(description="Your reflection on the initial answer.")    search_queries: list[str] = Field(        description="1-3 search queries for researching improvements."    )class ReviseAnswer(AnswerQuestion):    """Revise the original answer, with citations motivating the changes."""    references: list[str] = Field(description="Citations motivating your updated answer.")

关键点在于:ReviseAnswer继承了AnswerQuestion并多加一个references字段。这意味着修订版必须带引用,而初始版不需要。

这些schema通过bind_tools绑定到LLM上,强制LLM以function call的形式输出结构化数据,而不是自由文本。

2、Prompt设计:一个模板复用两个角色

Reflexion的Prompt同时服务于初始回答和修订回答:

actor_prompt_template = ChatPromptTemplate.from_messages([    ("system",     "You are expert researcher.\n"     "Current time: {time}\n\n"     "1. {first_instruction}\n"     "2. Reflect and critique your answer. Be severe to maximize improvement.\n"     "3. Recommend search queries to research information and improve your answer."),    MessagesPlaceholder(variable_name="messages"),    ("user",     "\n\n<system>Reflect on the user's original question and the actions taken thus far."     " Respond using the {function_name} function.</reminder>"),]).partial(time=lambda: datetime.datetime.now().isoformat())

first_instruction和function_name是可变参数:

  1. 初始回答时:first_instruction="Provide a detailed ~250 word answer.",function_name=AnswerQuestion
  2. 修订回答时:first_instruction=revise_instructions(要求加引用),function_name=ReviseAnswer

一个模板复用两个角色,靠参数区分,这是务实的做法。

3、ResponderWithRetries:带着质检员的流水线

未经审视的人生不值得过。——苏格拉底

这是Reflexion模式里最值得品的设计。它不是简单地调用LLM,而是"调用-验证-失败重试"三步走,就像流水线末端站了一个质检员,不合格就打回去返工:

class ResponderWithRetries:    def __init__(self, runnable, validator):        self.runnable = runnable        self.validator = validator    def respond(self, state: State) -> dict:        messages = state["messages"]        response = None        for attempt in range(3):  # 最多重试3次            response = self.runnable.invoke(                {"messages": messages}, {"tags": [f"attempt:{attempt}"]}            )            try:                self.validator.invoke(response)  # PydanticToolsParser 验证                return {"messages": [response]}            except ValidationError as e:                # 把错误信息塞回去当ToolMessage,让LLM看着错误改                tool_call_id = (                    response.tool_calls[0]["id"]                    if response.tool_calls                    else str(attempt)                )                messages = messages + [                    response,                    ToolMessage(                        content=(                            f"{repr(e)}\n\nPay close attention to the function"                            " schema.\n\nRespond by fixing all validation errors."                        ),                        tool_call_id=tool_call_id,                    ),                ]        return {"messages": [response]}

执行流程拆解:

  1. 调用runnable拿到LLM响应
  2. 用PydanticToolsParser验证输出是否符合schema
  3. 验证通过,直接返回
  4. 验证失败,把错误信息塞回去当ToolMessage,让LLM"看着错误自己改"
  5. 最多重试3次,3次都不行就返回最后一次的结果

个人认为,这种"把验证错误反馈给模型"的设计比直接抛异常要靠谱得多。LLM看到ValidationError的具体描述后,往往能在下一轮修正格式问题。

注意一个原版notebook的Bug修复:原代码写的是state + [response, ToolMessage(...)],这是dict + list操作,直接抛TypeError。正确写法是messages + [response, ToolMessage(...)]——追加到列表,而不是用state做加法。

4、execute_tools:跑腿小弟

execute_tools:负责把LLM给出的搜索词拿去跑

工具节点负责执行LLM给出的search_queries:

def run_queries(search_queries: list[str], **kwargs):    if os.getenv("TAVILY_API_KEY"):        try:            from langchain_community.tools.tavily_search import TavilySearchResults            tavily = TavilySearchResults(max_results=5)            return tavily.batch([{"query": q} for q in search_queries])        except ImportError:            pass  # 可选依赖缺失,走离线    return [_offline_lookup(q) for q in search_queries]def build_tool_node() -> ToolNode:    return ToolNode([        StructuredTool.from_function(run_queries, name=AnswerQuestion.__name__),        StructuredTool.from_function(run_queries, name=ReviseAnswer.__name__),    ])

设计上有两个细节值得注意:

  1. run_queries同时注册了两个名字——AnswerQuestion和ReviseAnswer。因为draft和revise两个节点的LLM输出的tool call名称不同,但实际执行的是同一个搜索函数
  2. 没有配置TAVILY_API_KEY时,返回离线占位文本。这让整个loop不需要网络也能跑起来,方便演示和调试

5、event_loop:两道水坝,谁先满谁开闸

流水不腐,户枢不蠹。但流太多了也得拦住。

Reflexion的终止条件是最复杂也最精妙的部分。它用了两道独立的闸门,就像两道水坝——哪道先溢出就触发泄洪(终止):

MAX_QUERIES = 12    # 所有轮次search_queries总和上限MAX_REVISIONS = 5   # 修订次数上限(不含初始draft)def event_loop(state: State) -> str:    if (        _get_total_search_queries(state) > MAX_QUERIES        or _get_revision_count(state) > MAX_REVISIONS    ):        return END    return "execute_tools"

两道闸门是OR关系,谁先超就谁触发。

为什么需要两道?因为LLM的行为不可预测:

  1. 如果LLM每轮都吐出很长的search_queries列表,查询总数会先爆——MAX_QUERIES闸门触发
  2. 如果LLM每轮只吐一两个查询,修订次数会先爆——MAX_REVISIONS闸门触发
  3. 无论哪种情况,循环都不会无限跑下去

以下是一个假设场景(假设LLM每轮吐3条查询),展示闸门触发过程:

双闸门终止示意(假设LLM每轮吐3条查询)轮次  累计查询数  累计修订数  触发闸门  1       3          0          -  2       6          1          -  3       9          2          -  4      12          3          -  5      15          4      MAX_QUERIES > 12 → END

如果只有一道闸门,要么拦不住查得多的,要么拦不住改得多的。两道齐上,整得挺靠谱。

_get_revision_count的计算逻辑也需要留意:它统计的是带tool_calls的AIMessage数量减1。因为第一条AIMessage是初始draft,不计入修订次数。

6、build_app:组装带工具的反思图

def build_app(*, model=None, first_responder=None, revisor=None,              tool_node=None, checkpointer=None):    if first_responder is None or revisor is None:        if model is None:            model = make_default_model()    if first_responder is None:        initial_chain = actor_prompt_template.partial(            first_instruction="Provide a detailed ~250 word answer.",            function_name=AnswerQuestion.__name__,        ) | model.bind_tools(tools=[AnswerQuestion])        first_responder = ResponderWithRetries(            runnable=initial_chain,            validator=PydanticToolsParser(tools=[AnswerQuestion]),        )    if revisor is None:        revision_chain = actor_prompt_template.partial(            first_instruction=revise_instructions,            function_name=ReviseAnswer.__name__,        ) | model.bind_tools(tools=[ReviseAnswer])        revisor = ResponderWithRetries(            runnable=revision_chain,            validator=PydanticToolsParser(tools=[ReviseAnswer]),        )    tool_node = tool_node or build_tool_node()    workflow = StateGraph(State)    workflow.add_node("draft", first_responder.respond)    workflow.add_node("execute_tools", tool_node)    workflow.add_node("revise", revisor.respond)    workflow.add_edge(START, "draft")    workflow.add_edge("draft", "execute_tools")    workflow.add_edge("execute_tools", "revise")    workflow.add_conditional_edges("revise", event_loop, ["execute_tools", END])    return workflow.compile(checkpointer=checkpointer or InMemorySaver())

和Reflection的build_app对比,区别一目了然:

  1. 多了execute_tools节点
  2. draft和revise绑定了不同的tool schema
  3. 两者都包在ResponderWithRetries里(带验证重试)
  4. 条件路由从should_continue换成了event_loop(双闸门)

五、两种模式的工程对比

把两种模式放在一起,从工程视角做一次全面对比:

对比维度ReflectionReflexion
核心思路自我批评循环自我批评 + 外部搜索验证
LLM输出纯文本(str)结构化(bind_tools + Pydantic)
外部依赖仅需LLMLLM + 搜索工具(Tavily)
消息角色翻转(AI→Human)保持原始角色
终止策略哨兵标记 + 硬上限双闸门(MAX_QUERIES OR MAX_REVISIONS)
容错无重试ValidationError 重试(3轮)
输出质量依赖LLM自身能力有引用、有搜索验证
Provider兼容性高(纯文本即可)中(需支持function calling)
适用场景创意写作、文本润色知识问答、研究分析

选型建议很简单:如果你的场景不需要查外部资料,Reflection就够了,还省token;如果需要事实核查和引用支撑,上Reflexion。

六、要点总结

  1. Reflection的核心是"生成-批评-修订"的纯文本循环,通过角色翻转让LLM扮演师生关系,用哨兵标记<<NO_REVISIONS_NEEDED>>控制终止。
  2. Reflexion在Reflection基础上增加了结构化输出(bind_tools)、工具调用(Tavily搜索)和情景记忆,实现"开卷反思"。
  3. ResponderWithRetries的验证重试机制通过把ValidationError反馈给LLM来修复格式问题,最多重试3次。

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

在这里插入图片描述

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费】

在这里插入图片描述

图谱后端选型:Memgraph vs Neo4j vs 嵌入式 SQLite,什么时候该切换? 本文通过脚本自动探测代码图谱规模,对比SQLite、Memgraph与Neo4j在不同节点量级下的性能表现。实测表明:10万节点内嵌入式SQLite凭借低延迟和轻量部署仍具竞争力;超15万节点后,Memgraph适合低延迟、高并发场景;而Neo4j仅在百万级图谱且需复杂查询时才具备优势。配套提供一键测试延迟与平滑迁移后端的Python工具链,实现按需选型与无缝切换。 阅读详情

相关推荐

SpringBoot+Vue+MySQL 高校学科竞赛平台 完整可运行版(源码+文档)

本项目基于SpringBoot+Vue+MySQL构建高校学科竞赛管理平台,覆盖学生、教师、领队教师、管理员四大角色,实现竞赛发布、报名、刷题、评分、公示等全流程闭环管理。系统架构清晰,技术主流,配套完整源码、数据库脚本、万字论文、开题报告、答辩PPT及部署文档,支持一键运行,适用于毕业设计、课程设计及院系二次开发,真正实现“开箱即用”。

招风的黑耳优快云 295

Docker Compose:搭建本地多服务开发环境

从一个 Java API、PostgreSQL 和 Redis 开始,配置服务名、端口、环境变量、健康检查、数据卷和依赖关系。理解 Compose 文件如何被解析、项目如何隔离,以及哪些数据不能依赖“重建容器”保留,能够把个人开发环境整理成团队可复用的启动入口。

m0_62221377的博客 477

别再用MounRiver了!在VSCode里用PlatformIO搞定CH32V208开发(附完整配置流程)

本文详细介绍了如何在VSCode中使用PlatformIO进行CH32V208开发,替代传统的MounRiver Studio。通过完整的配置流程和优化技巧,开发者可以构建高效、现代化的RISC-V开发环境,显著提升编译速度和开发效率。

weixin_28711397的博客 539

AI全栈实战 | 3.9-01 爬虫入门:requests 加 BeautifulSoup 三分钟跑通,但 90% 的人栽在这 4 个“礼貌“问题上

⚠️:本文内容仅用于。请遵守目标站点的服务条款与相关法律法规,不得对目标服务造成负担,不得采集、传播个人隐私数据。技术是中性的,边界在你手里。爬虫的入门技术(requests 发请求 + BeautifulSoup 解析)三分钟就能学会。真正区分"会用爬虫"和"会做爬虫的人"的,是这篇我们跑通"请求→解析→存储"的最小闭环,然后重点把"合规与礼貌"这根弦给你绷上。

源码获取 | 运行部署 | 定制二开修改,如果回复不及时请耐心等待,请见谅。 436

生成式引擎优化(GEO)全景指南:技术架构、实施策略与未来趋势

生成式引擎优化(GEO)全景指南摘要 GEO(生成式引擎优化)是针对AI生成内容(如ChatGPT、文心一言等)的优化策略,通过结构化数据、权威建设与语义优化提升企业内容在AI答案中的引用优先级,实现“无点击曝光”。其核心价值在于从流量竞争转向信任构建,突破传统SEO局限。技术架构依托RAG(检索增强生成)、向量数据库及反馈学习机制,动态优化内容生成与引用逻辑。实施策略包括:部署结构化数据(如JSON-LD)、维护动态知识图谱、适配多模态内容(3D/VR)、联合权威机构发布白皮书。行业案例显示,美妆、智能家

解锁AI流量新红利!🚀 GEO优化(生成引擎优化)助您掌控AI搜索,让AI成为您的品牌最佳代言人! 1454

深入解析Android SoundTrigger架构:从HIDL到AIDL的演进与实践

本文深入解析Android SoundTrigger架构,从HIDL到AIDL的演进与实践。SoundTrigger是Android系统中低功耗语音唤醒的关键技术,通过分层设计和硬件协同实现高效语音识别。文章详细介绍了核心组件、HIDL与AIDL的对比及优化技巧,帮助开发者掌握语音模型优化和功耗管理。

brown的博客 231

【基于 WebSocket 的多用户网页五子棋】—— 数据管理模块

但行好事,莫问前程

qq_42996461的博客 251

【七】Hadoop3.3.4基于ubuntu24的分布式集群安装

本次安装实验基于苹果m2芯片的mac系统,使用vmware fusion搭建三台ubuntu24分布式虚拟机,确保在三台机器上安装了Java jdk8,并配置了免密码登录,网络互通,防火墙关闭,授时服务器已经同步。访问apche官网源,下载3.3.4版本,我们用二进制通用版即可,因为hadoop运行在java环境,跨平台性使得无需编译arm架构版本。至此,Hadoop的安装完成,包括hdfs文件存储系统,mapreduce计算框架,yarn资源管理系统均能正常、稳定使用。

qq_31412425的博客 2161

C++算法(七)

C++ stack算法题和一些客观题

2503_94479566的博客 378

FCL碰撞检测库在Windows下的编译与配置(MinGW+CMake)

本文详细介绍了在Windows系统下使用MinGW和CMake编译配置FCL碰撞检测库的完整流程。内容涵盖MinGW-w64、CMake的安装与环境配置,关键依赖库Eigen和libccd的安装,以及FCL源码的编译、安装与实战测试。重点解析了CMake配置命令中的关键参数与常见错误解决方案,旨在帮助开发者高效完成FCL在Windows平台的部署,适用于机器人、游戏物理引擎等需要精确碰撞检测的开发场景。

sunny的博客 484

什么是 SAP S/4HANA 的 VDM Layering Architecture 的 CDS Hierarchy View

当涉及SAP S/4HANA的CDS Hierarchy View时,我们正在谈论一种高级数据建模技术,用于构建层次结构化的数据视图,以支持树状和分层数据的处理和分析。CDS(Core Data Services)是SAP的一种数据建模和定义语言,而CDS Hierarchy View则是CDS的一个重要组成部分,用于处理层次数据,如组织结构、产品分类、地理区域等。首先,您可以使用CDS语言创建一个新的CDS Hierarchy View,定义产品分类的层次结构。您还可以定义其他与库存相关的属性。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 392

OpenClaw 深度调查:把 AI 助手做成你自己的控制平面

对 openclaw/openclaw 的完整技术尽调:Gateway 架构、Agent 运行时、工具与沙箱、30 个消息通道、181 个插件、安全信任边界、工程代价与采用建议。17 章 / 10 张图,全部数字标注口径,数据截至 2026-10-31。

厚积薄发 296

课题申报书成功率提升85%!借助大模型AI精准选题、搭综述框架及提炼创新点(附实操AI提示词)

写一份高质量的课题申报书往往面临许多困难,对很多同仁来说,难就难在:选题既要新又要能落地,文献综述要结构清晰还得有观点,研究目标要写得有逻辑还不能夸大,创新点必须得新。而且就算你有思路,也卡在怎么组织语言,怎么压缩字数上。现在我们用ChatGPT等AI工具,可以帮我们从“选题策划 → 综述撰写 → 目标拆解 → 创新提炼 → 团队结构”实现申报工作的全流程,我们要做的就是设计好提示词和收集相关资料。这篇文章将会从申报工作的六个核心模块出发,并给出参考AI提示词,帮你快速提升课题申报效率。

智能AI让学术科研更容易 909

IDEA 简介:从零认识 IntelliJ IDEA

IDEA 全称,是由 JetBrains 公司开发的一款主流 Java 集成开发环境(IDE)。它集代码编辑、编译、调试、测试、版本控制、构建管理等功能于一体,被大量 Java 开发者视为日常开发的首选工具。所谓 IDE(Integrated Development Environment,集成开发环境),就是把写代码所需的各类工具整合到同一个界面中。相比只用文本编辑器加命令行编译,IDE 能显著减少重复操作,让开发者把精力集中在业务逻辑上。

ztI10的博客 178

RAGFlow升级指南(纯小白都看得懂)

升级背景:RAGFlow项目原来的版本是0.17.0版本,在使用过程中,发现当知识库检索为空的时候并且使用到rerank模型的时候,就会输出错误的信息;为了解决这个版本问题,特意升级到最新的版本0.17.2(截止2025-3-14时最新版本就是0.17.2了)官方升级文档https://ragflow.io/docs/dev/upgrade_ragflow官方文档对小白还是不太友好,作者也是捣鼓了十多分钟,特出下面的升级指南前提:旧版本的RAGFlow项目是启动好了的1.在ragflow目录下执行(拉取最新

Ven%的博客 3596

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

TransactionInactiveError:await 之后事务已经不活跃了

TransactionInactiveError 出现于 IndexedDB 事务已结束(非 active 状态)时调用 put、get 等操作。常见于 await 后或 setTimeout 中执行请求,因任务已完成,事务已提交或进入 finished 状态。请求必须在创建事务的同一任务中挂起,否则无效。解决方法:在 onsuccess 回调内同步发起后续操作,或提前将所有请求挂入事务。避免在异步上下文中使用事务操作,确保请求在事务活跃期内完成。

qq_40822000的博客 159

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

云计算课程小组PPT汇报任务书

36人分为6组,每组6人;形式:生活案例调研 + 理论解读;汇报时长7‑9min;PPT建议10‑14页。

Michelle8023的博客 208

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

大表 ALTER TABLE 怎么做?NineData OnlineDDL 配置与执行实践

介绍NineData OnlineDDL大表变更实践,涵盖执行策略、切表控制、拷贝批次与可视化进度追踪。

dbasenewbie的博客 295

软件项目交付时,源代码之外还应该交付哪些技术资料?

软件项目交付时,除可运行程序外,还应核对源代码、数据库结构、接口文档、部署运维、测试验收和账号资产。本文从实际交付环节拆解完整资料清单,并说明合同如何约定交付范围、知识产权与维护边界。

chengduyoushu的博客 306

Axum 初步入门学习笔记

)自定义错误实现后,可以直接作为Result的ErrAxum 是一个构建在 Tokio、Tower、Hyper 之上的 Rust Web 框架,核心能力是:Router 路由、Extractor 提取器、Tower 中间件、IntoResponse 响应机制、State 共享状态。那张分层架构图是“地图”不是“说明书”:它帮你建立全局观,但 Service、Repository、数据库、Redis、MQ 都是你自己在 Handler 内部调用的业务/基础设施层,不是 Axum 自带的。

weixin_43219667的博客 192

MySQL报Too many open files?句柄耗尽的排查与参数配置

文章讲清 max_connections 与 open_files_limit 两个额度、句柄被谁占走、分区表为什么最容易踩,给出从 error log 到 /proc/pid/limits 的定位顺序与句柄预算算法。

「一个在数据库赛道上边学边分享的学妹」——聚焦国产数据库/信创方向、分享学习笔记、踩坑经验和行业观察。 336

SQL Server 数据库双备份:简化配置,兼顾本地留存与异机归档

本文针对中小企业SQLServer数据库备份难题,提出简化配置与本地+异机双副本方案。传统原生备份依赖手动脚本,存在配置复杂、传输易中断、日志分散、静默失败等问题。推荐使用图形化工具实现备份、本地留存与异机同步一体化管理,支持断点续传、加密传输、自动清理与版本控制,降低运维负担。双副本策略提升数据安全性,本地快速恢复,异地防硬件故障。建议定期验证恢复流程,确保备份可用性。

2501_93776716的博客 291

Redis 入门详解:核心特性、重要文件与全局命令实战

本文系统介绍了Redis的核心特性、重要文件及全局命令。Redis凭借内存存储、C语言实现和单线程设计,具备极高的读写性能;支持持久化(RDB/AOF)、主从复制与集群架构,适用于缓存、排行榜、计数器等场景,但不适合存储海量冷数据。文中还解析了常见面试题,如为何快速、单线程原理、持久化机制、KEYS *禁用原因及过期键处理策略,强调其在高并发场景下的优势与局限。

2303_77004089的博客 206

Agent 安全实战:间接提示注入的四个攻击面与防御体系

当 Agent 从 "生成内容" 走向 "执行动作",安全边界就从内容合规变成了权限越界。本文拆解间接提示注入在网页抓取、工具返回值、MCP 连接器、长期记忆四个位置的真实攻击路径,对照 Claude、GPT、Gemini 在工具调用权限模型上的设计差异,给出可直接落地的五层防御体系。

阡陌数智,专注大模型网关与 LLM 工程落地 281

【FDE前沿部署工程师实战教程】第62章:Enterprise AI Developer Platform——企业级 AI 开发者平台与低代码 AI 应用工厂

企业从AI能力平台迈向AI应用生产平台,需构建统一的企业级AI开发者平台,将模型、RAG、Agent、Workflow等能力封装为可视化、可复用的开发工具。通过PromptIDE、AgentBuilder、WorkflowBuilder等模块,实现低代码与专业代码协同,降低开发门槛。平台覆盖应用全生命周期管理,集成测试评估、安全治理与CI/CD发布体系,推动AI应用规模化、标准化交付。最终形成“需求→设计→开发→测试→发布→运营”的企业AI应用工厂模式,助力制造等行业的智能化转型。

IT古董 314

5个陷阱和解决方案:MongoDB源码中自动化测试平台的数

在现代软件工程实践中,自动化测试平台扮演着至关重要的角色,它确保了系统的稳定性和迭代的可靠性。然而,随着业务数据量的快速增长以及并发写入需求的不断上升,基于MongoDB构建的自动化测试平台常常面临性能瓶颈和数据一致性问题。本文将围绕MongoDB源码中一个关键模块——,通过一行一行代码的解读,揭示其设计原理、性能调优点及常见陷阱,适合希望深入理解数据库实现机制的高级工程师。

wuchangjian的专栏 174
上一篇: Agent三层架构 Harness-Loop-Graph
下一篇: Harness 工程:AI 自我改进先从运行系统开始
Python_金钱豹
博客等级 码龄5年 1万+粉丝 2840原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值