ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

上下文工程与LLM Harness实战:构建可复用的LLM应用运行框架

上下文工程与LLM Harness实战:构建可复用的LLM应用运行框架 最近在项目里做 LLM 应用落地时我最大的体会是模型能力本身已经不是唯一瓶颈真正影响效果的反而是“喂给模型的上下文怎么组织”。同样一个模型上下文拼得好输出稳定且贴近业务上下文一塌糊涂模型再强也会给出错误答案。这篇文章围绕Context Engineering上下文工程和LLM Harness模型运行框架展开从概念到实战完整拆解如何在一个可复用的 Harness 中设计上下文管理、工具调用、检索与对话流程。适合做 LLM 应用开发的新手也适合已经在做 RAG、Agent 项目的开发者参考。1. 背景与核心概念1.1 为什么要关注 Context Engineering早期做 LLM 应用大家关心的是“选哪个模型”后来发现模型差异只是基础真正拉开应用效果差距的是以下几个问题同一套业务知识怎么塞进上下文才能让模型准确理解多轮对话历史越长模型越容易“忘记”关键信息怎么取舍需要调用外部工具时工具结果怎么拼回上下文才能让模型正确使用检索出来的文档很多全部放入上下文会导致 token 超限如何压缩和排序这些问题本质上都指向同一个能力上下文工程。它并不是某个具体的算法而是一套围绕“上下文窗口”进行数据组织、调度、压缩、注入的设计方法。上下文工程的最终目标是让模型在有限的上下文窗口内获取到足够且不乱的信息从而稳定输出预期结果。1.2 什么是 LLM HarnessHarness 的原意是“绳索”或“控制装置”在大模型领域它通常指一个承载模型调用、上下文构建、工具执行、输出解析等能力的运行框架。打个比方模型像一个经验丰富但是“一次只能看一张纸条”的专家你每次问他问题都要把相关材料递到他手里。Harness 就是那个负责整理材料、传递纸条、记录对话、调用外部工具的助手。开发者在 Harness 中设计一套流程模型负责“思考与表达”Harness 负责“信息进出与调度”。社区里讨论的很多概念比如 Agent、RAG 应用、工具调用其实都建立在 Harness 之上。没有 HarnessAgent 就缺乏稳定的会话上下文和工具执行环境没有策略化上下文管理RAG 检索量再大也只是浪费 token。我们平时看到的各种 LLM 编排框架本质上都是围绕 Harness 思路做的封装区别只在抽象程度和生态完整性上。1.3 上下文工程与提示词工程的区别很多同学会把上下文工程和提示词工程混在一起这里做一下区分概念关注层典型问题主要手段提示词工程指令与示例本身如何让模型理解角色、输出格式、任务边界指令优化、Few-shot 示例、格式约束上下文工程上下文数据组织与流动如何选择、裁剪、排序、注入信息检索、过滤、重排、摘要、记忆管理、工具结果回填提示词工程解决的是“把话说明白”上下文工程解决的是“把信息备充分、备干净”。在实际应用中两者经常配合使用Harness 负责把检索到的内容加工成合适的上下文片段提示词工程负责告诉模型怎么使用这些片段。2. 环境准备与总体架构2.1 技术栈与版本说明本文章的示例代码使用 Python 编写核心依赖尽量简化方便读者复制运行。示例环境如下操作系统Windows 10 / macOS 13 / Ubuntu 22.04 均可 Python3.10 LLM API以 OpenAI 兼容接口为例 项目依赖requests、pydantic版本需要根据你的项目实际情况调整本文示例以常见环境为例重点演示设计思路。不同模型的 API 参数虽然有差异但上下文管理和 Harness 调度的抽象方式可以通用。安全提醒调用模型 API 时请使用自己的合法 API Key并注意不要在公开仓库中提交密钥。生产环境建议使用密钥管理服务或环境变量注入。2.2 一个最小 Harness 的组成一个可用的 LLM Harness 至少要包含四层用户输入 ↓ Harness 入口层会话管理、输入清洗 ↓ 上下文构建层检索、历史裁剪、工具结果整理 ↓ 模型调用层请求组装、参数控制、重试 ↓ 输出处理层结构化解析、工具请求分发、错误处理 ↓ 用户结果在开始写代码之前先明确各层职责入口层接收用户消息记录会话 ID统一格式。上下文构建层决定哪些内容进入上下文哪些内容丢弃。模型调用层把上下文和指令拼成请求体调用模型 API。输出处理层判断模型返回的是正常回答还是工具调用意图再决定下一步动作。2.3 项目结构建议按下面的结构组织代码llm-harness-demo/ ├── main.py # 入口文件启动交互演示 ├── requirements.txt # 项目依赖 ├── harness/ │ ├── __init__.py │ ├── model.py # 模型调用封装 │ ├── context.py # 上下文构建与管理 │ ├── tools.py # 工具注册与执行 │ └── session.py # 会话与记忆管理 └── config.py # 配置读取这种分层的写法在工程上有两个好处每次只改一层不影响其他模块不同层可以独立测试比如不调用模型也能验证上下文拼接是否正确。3. 核心配置与原理拆解3.1 上下文窗口的预算管理上下文窗口是 Token 数量有限的“舞台”Harness 必须把宝贵的窗口空间分配给当前任务最需要的信息。一般可以按以下优先级分配系统指令固定占用建议保持在 1000 Token 以内。用户当前输入不可丢失允许长文本输入时需要截断策略。工具定义与工具结果按需注入工具调用场景中占用会明显增大。检索文档内容通过 Top-K 和重排控制。历史对话使用滑动窗口保留最近几轮并可以压缩老会话。在代码中我们可以先定义一个上下文预算类# 文件路径harness/context.py from dataclasses import dataclass, field from typing import List, Dict dataclass class ContextBudget: max_tokens: int 8000 system_tokens: int 800 history_tokens: int 2000 doc_tokens: int 2500 reserved_tokens: int 500 property def available_tokens(self) - int: return ( self.max_tokens - self.system_tokens - self.history_tokens - self.doc_tokens - self.reserved_tokens )这里的核心思想是先留出固定开销再计算当前请求的可变开销。如果用户输入特别长Harness 可以在进入模型前先做截断或摘要避免请求超过模型上下文限制。3.2 上下文消息结构大多数模型的 Chat 接口都支持系统消息、历史消息和当前用户消息。Harness 的上下文构建层本质上就是把这些来源统一加工成模型可接受的 messages 列表。# 文件路径harness/context.py from typing import List, Dict def build_messages( system_prompt: str, history: List[Dict[str, str]], user_input: str, retrieved_docs: List[str] None, ) - List[Dict[str, str]]: 构建发送给模型的 messages 列表。 messages [{role: system, content: system_prompt}] # 注入检索文档 if retrieved_docs: doc_text \n\n.join( f[文档 {i1}] {doc} for i, doc in enumerate(retrieved_docs) ) messages.append({ role: system, content: f以下是检索到的参考资料请结合这些资料回答用户问题\n{doc_text}, }) # 注入历史消息 messages.extend(history) # 注入当前用户输入 messages.append({role: user, content: user_input}) return messages这里需要注意的一个细节是检索文档注入时尽量使用 system 角色或者独立的 context 标记不要让用户输入混杂在文档中否则用户可以通过构造特殊输入干扰模型对文档内容的判断。3.3 工具调用的上下文注入在 Agent 场景下模型需要在对话过程中决定“要不要调用工具”“调用哪个工具”。为了让模型做出准确判断Harness 要在上下文中提供工具描述。常见的方式是在请求体中携带tools参数# 文件路径harness/tools.py from typing import Callable, List, Dict, Any class ToolRegistry: 工具注册器维护工具名称、描述、参数 Schema 和可执行函数。 def __init__(self): self._tools: Dict[str, Dict[str, Any]] {} def register( self, name: str, description: str, parameters: Dict[str, Any], func: Callable, ) - None: self._tools[name] { type: function, function: { name: name, description: description, parameters: parameters, }, executor: func, } def list_specs(self) - List[Dict[str, Any]]: 返回给模型的工具定义列表。 return [ { type: item[type], function: item[function], } for item in self._tools.values() ] def execute(self, name: str, arguments: Dict[str, Any]) - str: 执行工具并返回字符串结果。 if name not in self._tools: return f错误工具 {name} 不存在 func self._tools[name][executor] try: result func(**arguments) except Exception as exc: return f工具执行异常: {exc} return str(result)工具定义其实就是一段 JSON Schema模型通过这个 Schema 理解工具参数。工具执行结果再作为一条tool消息拼接回上下文形成完整闭环。这里有一个容易被忽视的点工具结果返回给模型时内容越精简越好。如果工具返回超长日志直接把全部文本塞回上下文不仅浪费 token还会干扰模型的回答。建议在工具执行结果返回前做一层截断或摘要。4. 完整实战构建一个可扩展的 LLM Harness下面我们完成一个实际可运行的最小 Harness。这个 Harness 支持系统提示词管理多轮对话历史简单检索文档注入工具调用以天气查询为示例Token 预算控制4.1 创建项目结构先创建项目目录和文件mkdir llm-harness-demo cd llm-harness-demo mkdir harness touch config.py main.py requirements.txt touch harness/__init__.py4.2 添加依赖编辑requirements.txtrequests2.31.0 pydantic2.5.0安装依赖pip install -r requirements.txt4.3 编写配置模块编辑config.py# 文件路径config.py import os API_KEY os.getenv(LLM_API_KEY, ) BASE_URL os.getenv(LLM_BASE_URL, https://api.openai.com/v1) MODEL os.getenv(LLM_MODEL, gpt-4o-mini)使用环境变量的方式配置密钥避免把密钥硬编码在代码中。如果你使用的是兼容 OpenAI 协议的其他模型服务只需要修改BASE_URL和MODEL。4.4 编写模型调用封装编辑harness/model.py# 文件路径harness/model.py from typing import List, Dict, Optional import requests import config class LLMClient: 封装 OpenAPI 兼容的 Chat Completion 调用。 def __init__(self, api_key: str, base_url: str, model: str): self.api_key api_key self.base_url base_url.rstrip(/) self.model model def chat( self, messages: List[Dict[str, str]], tools: Optional[List[Dict]] None, temperature: float 0.7, ) - Dict: url f{self.base_url}/chat/completions headers { Authorization: fBearer {self.api_key}, Content-Type: application/json, } payload { model: self.model, messages: messages, temperature: temperature, } if tools: payload[tools] tools response requests.post(url, headersheaders, jsonpayload, timeout60) response.raise_for_status() return response.json()这段代码的核心工作是组装请求并解析响应。不同模型可能在tools参数格式上略有差异在生产环境中建议封装一个适配层避免业务代码直接依赖某一个 SDK。4.5 编写会话记忆管理编辑harness/session.py# 文件路径harness/session.py from typing import Dict, List from collections import deque import json import time class Session: 保存多轮对话历史并使用滑动窗口控制长度。 def __init__(self, max_history_rounds: int 5): self.max_history_rounds max_history_rounds self.history: deque deque(maxlenmax_history_rounds * 2) self.created_at time.time() def append(self, role: str, content: str) - None: self.history.append({role: role, content: content}) def get_messages(self) - List[Dict[str, str]]: return list(self.history) def clear(self) - None: self.history.clear() class SessionManager: 管理多个会话适用于同时服务多用户的场景。 def __init__(self): self._sessions: Dict[str, Session] {} def get_or_create(self, session_id: str) - Session: if session_id not in self._sessions: self._sessions[session_id] Session() return self._sessions[session_id] def remove(self, session_id: str) - None: self._sessions.pop(session_id, None)滑动窗口的意义在于历史对话不可能无限累积超过窗口后最老的对话会被自动丢弃。这样既能减少 token 消耗也避免老旧信息干扰当前决策。4.6 编写工具注册与执行编辑harness/tools.py在之前的基础上增加一个天气查询工具# 文件路径harness/tools.py import random from typing import Dict, List class ToolRegistry: def __init__(self): self._tools: Dict[str, Dict] {} def register(self, name: str, description: str, parameters: Dict, func): self._tools[name] { type: function, function: { name: name, description: description, parameters: parameters, }, executor: func, } def list_specs(self) - List[Dict]: return [ { type: item[type], function: item[function], } for item in self._tools.values() ] def execute(self, name: str, arguments: Dict) - str: if name not in self._tools: return f错误工具 {name} 不存在 func self._tools[name][executor] try: result func(**arguments) except Exception as exc: return f工具执行异常: {exc} return str(result) def build_default_registry() - ToolRegistry: 创建包含示例工具的注册器。 def get_weather(city: str) - str: # 演示用伪数据实际项目应接入真实天气 API weather_data { 上海: 小雨22℃, 北京: 晴26℃, 广州: 雷阵雨29℃, 成都: 阴21℃, } value weather_data.get(city) if value is None: return f暂无 {city} 的天气数据 return f{city} 当前天气{value} registry ToolRegistry() registry.register( nameget_weather, description查询指定城市的当前天气情况, parameters{ type: object, properties: { city: { type: string, description: 城市名称例如 上海, } }, required: [city], }, funcget_weather, ) return registry这里使用伪数据是为了演示完整流程实际项目中你需要替换成真实 API 调用并增加超时、缓存、限流处理。工具注册表的好处是业务方只需要调用register不需要修改 Harness 核心代码扩展性很强。4.7 编写上下文构建模块编辑harness/context.py加入预算控制# 文件路径harness/context.py from dataclasses import dataclass from typing import List, Dict dataclass class ContextBudget: max_tokens: int 8000 system_tokens: int 800 history_tokens: int 2000 doc_tokens: int 2500 reserved_tokens: int 500 property def available_tokens(self) - int: return ( self.max_tokens - self.system_tokens - self.history_tokens - self.doc_tokens - self.reserved_tokens ) def build_messages( system_prompt: str, history: List[Dict[str, str]], user_input: str, retrieved_docs: List[str] None, ) - List[Dict[str, str]]: 构建发送给模型的 messages 列表。 messages [{role: system, content: system_prompt}] if retrieved_docs: doc_text \n\n.join( f[文档 {i1}] {doc} for i, doc in enumerate(retrieved_docs) ) messages.append({ role: system, content: f以下是检索到的参考资料请结合这些资料回答用户问题\n{doc_text}, }) messages.extend(history) messages.append({role: user, content: user_input}) return messages注意这里的 Token 预算只是做了一个数学规划。真正计算 Token 需要模型自带的 Tokenizer或者第三方 Token 计算库。建议在生产环境中接入精确 Token 计数避免上下文超限。4.8 编写 Harness 主流程编辑harness/chat.py# 文件路径harness/chat.py from typing import Optional import json from sessions import SessionManager from context import build_messages, ContextBudget from tools import ToolRegistry, build_default_registry from model import LLMClient class LLMHarness: 整合上下文构建、工具调用、会话管理、模型调用的运行框架。 def __init__( self, client: LLMClient, system_prompt: str, registry: ToolRegistry None, session_manager: SessionManager None, budget: ContextBudget None, ): self.client client self.system_prompt system_prompt self.registry registry or build_default_registry() self.sessions session_manager or SessionManager() self.budget budget or ContextBudget() def run(self, user_input: str, session_id: str default) - str: session self.sessions.get_or_create(session_id) # 1. 上下文检索演示固定文档实际接入向量检索或搜索 API retrieved_docs [ LLM Harness 是一个连接模型调用、上下文管理和外部工具的运行时框架。, 上下文工程的核心是在有限上下文窗口内组织高质量信息。, ] # 2. 构建 messages messages build_messages( system_promptself.system_prompt, historysession.get_messages(), user_inputuser_input, retrieved_docsretrieved_docs, ) # 3. 第一轮模型调用判断是否需要工具 response self.client.chat( messagesmessages, toolsself.registry.list_specs(), ) message response[choices][0][message] # 4. 如果模型请求调用工具 if message.get(tool_calls): tool_calls message[tool_calls] # 记录助手消息 assistant_message { role: assistant, content: message.get(content) or , tool_calls: tool_calls, } session.append(assistant_message[role], assistant_message.get(content) or ) # 执行工具调用 for tool_call in tool_calls: fn_name tool_call[function][name] fn_args json.loads(tool_call[function][arguments] or {}) result self.registry.execute(fn_name, fn_args) tool_message { role: tool, tool_call_id: tool_call[id], content: result, } messages.append(assistant_message) messages.append(tool_message) # 5. 第二轮模型调用拿到工具结果后生成最终回答 second_response self.client.chat( messagesmessages, toolsself.registry.list_specs(), ) final_message second_response[choices][0][message] final_text final_message.get(content) or else: final_text message.get(content) or # 6. 保存会话 session.append(user, user_input) session.append(assistant, final_text) return final_text这个主流程是 Harness 的核心。第一步先组装上下文第二步让模型判断是否需要调用工具第三步如果模型选了工具Harness 负责执行并回填结果第四步让模型基于工具结果做最终回答。整个过程看起来简单但解决了 Agent 应用中最常见的“模型乱调工具”和“工具结果无法回填”问题。4.9 编写入口文件编辑main.py# 文件路径main.py from config import API_KEY, BASE_URL, MODEL from harness.chat import LLMHarness from harness.model import LLMClient SYSTEM_PROMPT 你是一个智能助手。请根据用户的问题和检索到的参考资料给出准确、简洁的回答。 如果用户询问天气你必须调用 get_weather 工具获取最新数据。 不要编造信息信息不足时请直接说明。 def main(): if not API_KEY: print(请先设置环境变量 LLM_API_KEY) print(示例) print( export LLM_API_KEYyour_key # macOS / Linux) print( set LLM_API_KEYyour_key # Windows CMD) return client LLMClient(api_keyAPI_KEY, base_urlBASE_URL, modelMODEL) harness LLMHarness(clientclient, system_promptSYSTEM_PROMPT) print(LLM Harness 演示已启动输入 quit 退出) session_id demo-session while True: user_input input(\n你).strip() if user_input.lower() in (quit, exit): break try: answer harness.run(user_input, session_idsession_id) print(f\n助手{answer}) except Exception as exc: print(f\n出错了{exc}) if __name__ __main__: main()4.10 运行与验证在终端执行export LLM_API_KEY你的密钥 python main.py如果配置正确会出现交互式对话界面。输入“上海天气怎么样”模型会返回工具调用请求Harness 捕获到tool_calls后执行get_weather最终把天气结果拼进上下文并生成回答。执行流程如图所示用户输入上海天气怎么样 ↓ Harness 拼接系统指令 历史 检索文档 ↓ 模型返回 tool_calls: get_weather(city上海) ↓ Harness 执行工具得到 上海 当前天气小雨22℃ ↓ 工具结果拼接回上下文再次调用模型 ↓ 模型生成最终回答上海今天有小雨气温22℃建议带伞。4.11 结果说明这个示例虽然简单但已经具备一个基础 Harness 的核心能力多轮对话不会丢失状态工具调用能够闭环执行检索文档以 system 消息注入隔离用户输入污染代码按模块拆分后续扩展数据库查询、向量检索、搜索 API 时不需要重写主流程5. 常见问题与排查思路在实际开发中Harness 的坑往往不在“写不出来”而是在“跑起来之后不稳定”。下面整理我遇到的高频问题。问题现象常见原因解决思路请求报上下文长度超限检索文档 历史 工具结果超过模型窗口在 Harness 中增加 Token 预算按重要性截断文档和历史模型不调用工具工具描述不清晰或上下文里没有明确的工具调用指令优化工具 name 和 description在系统提示词中写清调用条件模型调用不存在的工具工具参数 Schema 与执行函数不一致增加工具注册校验执行前校验参数合法性工具结果太长导致模型回答混乱直接拼接原始日志工具返回前做截断、摘要只保留关键字段多轮对话后效果越来越差历史消息无限增长旧信息干扰当前判断使用滑动窗口只保留最近 N 轮必要时对旧对话做摘要用户输入注入不相关内容污染检索文档用户输入与文档放在同一条消息分离消息角色文档相关内容放 system 或独立 context 区域模型反复调用同一个工具没有告诉模型工具已经执行过检查工具结果是否成功回填为 tool 消息API 请求偶发超时外部依赖接口响应慢增加超时、重试、熔断机制排查这类问题建议按下面的顺序先看 Harness 拼接后的 messages 结构是否包含预期的 system、user、tool 消息。再看上下文里是否有重复内容、缺失内容。最后才怀疑模型本身。很多时候模型输出异常是因为前面的上下文组装已经出了问题。6. 最佳实践与工程建议6.1 配置与代码分离LLM 应用涉及很多运行时配置模型名称、API 地址、温度参数、检索 Top-K、历史轮数、Token 预算。这些配置不建议散落在业务代码中而是统一放到配置中心或者 YAML 文件里并支持环境变量覆盖。# 示例配置片段config.yaml model: name: gpt-4o-mini temperature: 0.7 max_retries: 3 context: max_tokens: 8000 history_rounds: 5 doc_top_k: 5 tools: enabled: - get_weather - get_stock_price这样做的好处是调整上下文章节参数不需要改代码部署多个环境时只需要切换配置。6.2 上下文数据要打标签在复杂业务中上下文可能来自多个数据源用户资料、订单信息、商品库、历史工单、FAQ 文档。建议在注入上下文时给每段内容打上来源标签例如[来源: 用户资料] 用户当前等级VIP [来源: 订单系统] 最近订单2024-06-01 购买 iPhone 15标签不仅帮助模型定位信息也方便开发者排查“模型答错的依据来自哪里”。6.3 日志要完整记录上下文快照在生产环境排查 LLM 应用问题时最大的困难是“复现”。大模型输出具有随机性如果没有完整的日志很难判断问题出在上下文还是模型。建议在 Harness 中记录请求 ID会话 ID当前 messages 的完整快照调用模型时的时间戳Token 消耗工具调用结果模型返回内容日志可以输出为 JSON 格式方便后续接入日志平台。# 日志示例 log_data { request_id: req_123, session_id: demo-session, messages: messages, tool_calls: tool_calls, final_answer: final_text, tokens: response[usage], latency_ms: 820, }6.4 评估集比提示词调优更重要很多人花大量时间调提示词却忽略建立评估集。建议在项目早期就整理 50 到 100 条典型问题覆盖正常问题、边界问题、工具调用问题、超长上下文问题。每次改动 Harness 结构或上下文策略都跑一遍评估集对比输出质量。评估维度可以包括回答正确率工具调用准确率上下文超限次数平均 Token 消耗端到端延迟6.5 安全边界与最小权限当 Harness 支持工具调用时安全问题会变得突出。一个常见风险是模型被用户输入诱导调用了不应该调用的工具或者把敏感信息作为参数传给外部接口。这就是社区里常说的“过度授权”问题。缓解思路包括工具最小化当前对话只需要三个工具就不要给模型注册十个工具。参数白名单执行工具前校验参数禁止传入危险命令或任意文件路径。权限分级读取类工具可以自动执行写入、删除、转账等高风险工具必须二次确认。用户输入隔离用户消息不能直接拼接进 system prompt 或工具描述防止提示词注入。敏感信息过滤工具返回值下发模型前用脱敏规则过滤手机号、身份证、密钥等信息。6.6 版本化与灰度发布LLM 应用更新频率很高尤其是上下文策略、系统提示词、工具描述这些内容。建议将 Harness 的配置和提示词纳入版本管理发布时先使用小流量灰度对比新旧版本的评估结果后再全量切换。7. 总结与后续学习路线这篇文章从 Context Engineering 的概念出发介绍了 LLM Harness 的核心组成并完成了一个支持多轮对话、检索文档注入、工具调用闭环的最小 Harness 示例。重点不是某一个模型 API而是 Harness 如何组织上下文、如何调度工具、如何管理系统状态。如果你正在从“调 API”进入“做 LLM 应用”下面几条学习路径值得继续深入检索增强把示例中的固定文档替换为向量数据库检索加入重排策略这是 RAG 应用的基础。Agent 编排在工具注册表的基础上增加多步推理循环让模型可以连续调用多个工具解决复杂任务。评估体系建立自动化测试集把 Harness 的每次改动都变成可回归验证的工程行为。记忆机制从简单的滑动窗口升级为短期记忆、长期记忆、摘要记忆的分层方案。上下文工程不是一个静态的知识点而是随着模型能力迭代不断演进的设计方法论。尤其当模型上下文窗口越来越大很多人觉得不需要再做上下文管理了但实际恰恰相反上下文窗口越大信息的优先级、相关性、去重、压缩问题就越突出。如果把模型比作一个能力极强的员工Harness 就是他的工作台Context Engineering 则是整理工作台的方法论。工作台越整洁员工才能越稳定地发挥实力。在动手实践时建议从一个最小的 Harness 开始先跑通“用户输入 → 上下文构建 → 模型调用 → 输出返回”这条主线再逐步加入检索、工具、评估和安全机制。每一步都单独验证不要一上来就搭一个庞大的框架否则出了问题很难定位。希望这篇文章能帮你理清 Context Engineering 和 LLM Harness 的关系也欢迎在实际落地中根据自己项目的业务特点做调整。
返回列表