跳到主内容
快讯直播
AI智模界
教程

用快速模型加个性化记忆搭低延迟写作助理

这篇教程能做出什么

读完你能搭出一个这样的写作助理:你把两三行粗糙要点丢进去,它在几秒内吐出符合你语气、你行业规范、你常用结构的成稿雏形;下次换一个新会话,它仍然记得"别用感叹号""术语保留英文原文""段落不超过四行"这些事,不需要你再复述一遍。

三个可验收的成果:

1. 延迟可控:首字在很短时间内开始往外蹦(流式输出),你边读边判断方向,不用等整段生成完。

2. 语气稳定:同一个需求连问五次,输出风格基本一致,不需要每次都贴一遍参考范文。

3. 偏好可管:你能随时列出它"记住了什么",改掉记错的那条,删掉过期的要求。

这里的关键认知是:个性化记忆不是微调模型,它是在每次请求发出前,把"与本次任务相关的偏好"挑选出来塞进上下文。所以延迟高低、效果好坏,取决于你注入了多少、命中了多少,而不是取决于模型本身有多懂你。这个认知会决定后面所有工程取舍。

下面按"先把风格定死 → 再接记忆 → 再压延迟"的顺序走。

前置条件清单

  • 一个可用的快速模型接入:支持流式输出的对话接口。命名里带 Instant / Flash / Turbo 这类词的一般是低延迟档位,具体可用模型标识、上下文长度、速率限制以官方文档为准
  • 一个带自定义指令和记忆功能的客户端:自定义指令是你手写的、长期生效的规则;记忆是系统从对话中抽取或你显式要求写入的条目,通常支持查看、编辑、删除和整体开关。两者的具体入口名称以官方页面为准
  • 五到十段你写过的真实文本:邮件、周报、公众号、需求文档都行,用来提炼风格卡。
  • 一个存偏好的地方:本地一个 Markdown 文件或 JSONL 就够,不要一上来就上向量数据库。
  • Python 3.9+ 环境(走接口路线时需要),以及 requests 之类的 HTTP 库。
  • 一个计时方式time.perf_counter() 或者任何能测"发出请求到收到第一个字"的工具。没有基线就没法判断优化有没有用。

如果你只打算用现成客户端、不写代码,第 5 节之前的内容全部适用,代码部分可以跳过。

步骤 1:先定验收标准,再动手

很多人跳过这步,最后变成"感觉快了一点"。先写死两条:

  • 延迟基线:从点发送到看见第一个字,记录五次的平均值。这是"首字延迟"。再记录整段写完的时间。
  • 修改成本:同一份要点,让助理写三版,统计你平均要改几处才算能用。

这两个数字就是后面每一步的评分卡。风格卡加一条规则、记忆多注入两百字,都要回头看这两个数字有没有变差。

步骤 2:写出你的风格卡

风格卡是后面所有配置的源头。它不用长,但要具体到可执行。反面例子是"专业、简洁、有温度"——这种话模型没法执行。

```text

我的风格卡 v1

语气

  • 短句为主,一句话不超过 30 字
  • 不用感叹号,不用"首先/其次/最后"
  • 不写"在当今这个时代"这类开场白,第一句直接给结论

用词

  • 行业术语保留英文原文:prompt、token、latency,不翻译
  • 中文用"你",不用"您"(对外正式邮件除外)
  • 数据必须带口径,没口径就写"约"

结构

  • 段落不超过 4 行
  • 需要分点时用短横线,不用 1./2./3.
  • 结尾不加"希望对你有所帮助"

禁止

  • 不编造数字和引用
  • 不确定的信息标"待确认",不要圆过去

```

写完之后做一次自检:把每一行念出来,问"如果我给一个新同事看这条,他能不能照做?"不能就改具体。

步骤 3:把风格卡拆成两半,分别放到该放的地方

这是最容易做错的一步。风格卡里的内容要拆成两部分:

放进自定义指令的(长期不变、每次都生效):语气、用词、结构禁令。这部分是你的"宪法",稳定、量小、永远注入。

放进记忆条目的(场景化、会变、按需调用):某客户的称呼习惯、某个平台的标题字数限制、某段时间的禁用词。

拆分的判断标准很简单:这条规则三个月后还成立吗? 成立就写进自定义指令,不成立就做成一条记忆,用的时候再调出来。

自定义指令模板,直接抄:

```text

你是一位中文写作助理,服务对象是一位 AI 相关从业者。

输出规则:

1. 第一句直接给结论,不要铺垫。

2. 一句话不超过 30 字,段落不超过 4 行。

3. 不使用感叹号,不使用"首先/其次/最后"作为段落开头。

4. 行业术语保留英文原文。

5. 不编造数据、引用、链接。信息不确定时标注"待确认"。

流程规则:

  • 收到要点后,先输出一个 3 行以内的提纲,等我确认再展开。
  • 我发"改"字,你就重写上一段,不要解释你改了什么。

```

最后一条"等我确认再展开"值得保留:它把一次大生成拆成两次小生成,你更早拿到方向反馈,整体体感延迟反而更低。

步骤 4:搞清记忆的开关和边界

记忆功能一般有两层开关,含义不同:

  • 总开关:关掉之后,新对话不再读取也不再写入记忆。注意它通常只对新会话生效,已经开的那个会话里,上下文里已经有的内容不会凭空消失。
  • 单条记忆:可以查看、编辑、删除。删除是永久的,编辑是覆盖,不会保留历史版本。

还有几个常见边界,先知道能省很多排查时间:

  • 记忆跨会话生效,但不跨账号。换设备登录同一账号通常还在,退出登录就没了。
  • 自定义指令与记忆冲突时,多数产品把自定义指令视为更高优先级的硬约束,但具体行为以官方文档为准。稳妥做法是不要让两者说反话——发现冲突就去改自定义指令。
  • 自动抽取的记忆质量参差。系统可能把你的玩笑话记成偏好,也可能漏掉你认真强调过的规则。所以自动抽取只能当草稿,重要的偏好要手动写。

步骤 5:三种写入偏好的方式,按场景选

方式一:对话式显式写入。 在你希望它记住的那一刻,直说:

```text

请记住:我写周报时,"OKR"要写成"目标","对齐"要写成"拉通",因为我的读者不熟悉互联网黑话。

```

这种写法信息最全,因为有上下文。

方式二:指令式批量导入。 手上已经有一份风格卡时,粘贴进去并说明归类:

```text

下面这些是我的写作规则,请把它们存为长期偏好。如果和我已有的记忆冲突,以这份为准。

  • 对外邮件用"您",内部沟通用"你"
  • 标题不超过 20 字
  • 数据没口径就写"约",并注明来源待补

```

方式三:程序化写入(走接口时用)。 如果记忆是通过接口管理的,形态通常是增删查三个操作。下面的骨架是示意,字段名和路径以官方文档为准

```python

memory_admin.py —— 示意结构,具体接口以官方文档为准

import requests

BASE = "https://<你的接口地址>"

HEADERS = {"Authorization": "Bearer <你的密钥>"}

def add_memory(text: str, scope: str = "writing"):

"""写入一条偏好。scope 用来自建命名空间,方便后续按场景筛选。"""

payload = {

"content": text,

"metadata": {"scope": scope, "source": "manual"},

}

r = requests.post(f"{BASE}/memories", json=payload, headers=HEADERS, timeout=10)

r.raise_for_status()

return r.json()

def list_memories(scope: str | None = None):

params = {"scope": scope} if scope else {}

r = requests.get(f"{BASE}/memories", params=params, headers=HEADERS, timeout=10)

r.raise_for_status()

return r.json().get("items", [])

def delete_memory(memory_id: str):

r = requests.delete(f"{BASE}/memories/{memory_id}", headers=HEADERS, timeout=10)

r.raise_for_status()

```

如果产品没有开放记忆接口,就用本地文件兜底——效果一样,只是注入要自己拼。

步骤 6:本地偏好库,别一上来就上向量库

写在本地文件里的好处是:你能用编辑器搜索、能 git diff、能一眼看出哪条过期了。JSONL 格式最省事:

```jsonl

{"id": "m001", "scope": "writing", "tags": ["邮件", "称呼"], "text": "对外邮件用「您」,内部沟通用「你」", "updated": "2026-01-01"}

{"id": "m002", "scope": "writing", "tags": ["标题", "公众号"], "text": "公众号标题不超过 20 字,不加书名号", "updated": "2026-01-01"}

{"id": "m003", "scope": "writing", "tags": ["术语"], "text": "保留英文原文:prompt、token、latency、recall", "updated": "2026-01-01"}

{"id": "m004", "scope": "writing", "tags": ["禁用"], "text": "结尾不写「希望对你有所帮助」,不写「让我们一起」", "updated": "2026-01-01"}

```

检索用最土的关键词打分就够了:

```python

retrieve.py —— 无依赖的关键词检索,先跑通再谈优化

import json, re

def load(path: str):

with open(path, encoding="utf-8") as f:

return [json.loads(line) for line in f if line.strip()]

def score(memory: dict, task: str) -> int:

s = 0

for tag in memory.get("tags", []):

if tag in task:

s += 3

for word in re.findall(r"[\w\u4e00-\u9fff]+", memory["text"]):

if len(word) >= 2 and word in task:

s += 1

同一 scope 的基础分,保证场景内的通用规则永远进得来

if memory.get("scope") == "writing":

s += 1

return s

def pick(memories: list, task: str, top_k: int = 6, max_chars: int = 600):

"""选出最相关的几条,并卡死字符预算。"""

ranked = sorted(memories, key=lambda m: score(m, task), reverse=True)

chosen, total = [], 0

for m in ranked:

if total + len(m["text"]) > max_chars:

continue

chosen.append(m)

total += len(m["text"])

if len(chosen) >= top_k:

break

return chosen

if __name__ == "__main__":

mems = load("memories.jsonl")

task = "帮我写一封给客户的邮件,说明这周延期两天"

for m in pick(mems, task):

print("-", m["text"])

```

top_kmax_chars 这两个参数就是你的延迟旋钮。把注入的记忆压到几百字以内,是低延迟最直接的来源——注入五千字的"完整偏好档案",首字延迟一定会明显变长,而且模型更容易被无关规则干扰。

步骤 7:拼 prompt 并调用快速模型

顺序很重要:稳定性从上到下递减。固定的系统指令放最前,动态记忆放中间,本次任务放最后。这样利于服务端缓存前缀(如果供应商支持),也能让模型分清哪些是硬约束、哪些是本次的临时要求。

```python

assistant.py —— 端到端骨架,接口细节以官方文档为准

import time, json, requests

from retrieve import load, pick

BASE = "https://<你的接口地址>"

HEADERS = {

"Authorization": "Bearer <你的密钥>",

"Content-Type": "application/json",

}

CUSTOM_INSTRUCTIONS = """你是一位中文写作助理。

规则:第一句给结论;一句话不超过30字;段落不超过4行;

不用感叹号;行业术语保留英文原文;不编造数据与引用,不确定就标「待确认」。

流程:先给3行以内提纲,等我确认再展开。"""

def build_prompt(task: str, memories: list) -> list:

memory_block = "\n".join(f"- {m['text']}" for m in memories) or "- (本次无额外偏好)"

return [

{"role": "system", "content": CUSTOM_INSTRUCTIONS},

{"role": "user", "content": f"以下是我的长期偏好,请在本次写作中遵守:\n{memory_block}"},

{"role": "user", "content": f"本次任务:\n{task}"},

]

def write(task: str, model: str = "<快速档模型标识>"):

mems = pick(load("memories.jsonl"), task)

messages = build_prompt(task, mems)

payload = {

"model": model,

"messages": messages,

"stream": True, # 流式:先拿首字,边读边判断

"temperature": 0.6, # 写作场景别太低,太低会僵

其他参数以官方文档为准

}

t0 = time.perf_counter()

first = None

buf = []

with requests.post(f"{BASE}/chat/completions", json=payload,

headers=HEADERS, stream=True, timeout=60) as r:

r.raise_for_status()

for line in r.iter_lines():

if not line:

continue

text = line.decode("utf-8").removeprefix("data: ").strip()

if text == "[DONE]":

break

try:

delta = json.loads(text)["choices"][0]["delta"].get("content", "")

except (json.JSONDecodeError, KeyError, IndexError):

continue # 心跳行或结构差异,跳过

if delta and first is None:

first = time.perf_counter() - t0

buf.append(delta)

print(delta, end="", flush=True)

total = time.perf_counter() - t0

print(f"\n\n[首字 {first:.2f}s / 全文 {total:.2f}s / 注入记忆 {len(mems)} 条]")

return "".join(buf)

if __name__ == "__main__":

write("帮我写周报开头,说明这周主要在调延迟,顺带修了两个线上问题")

```

两个细节值得注意:

  • flush=Trueiter_lines()。很多人以为延迟没降,其实是终端或中间层在缓冲,字早就生成了,只是没显示出来。
  • 首字和全文分开计时。首字反映的是网络加排队,全文反映的是输出长度。两者要优化的手段完全不同。

步骤 8:让 assistant 自己校验,再把新偏好回写

生成完之后加一步自检,成本很低但能显著减少返工:

```text

对照上面的偏好清单,检查你刚写的内容。

只列出违反的条目编号和违反处的原文,不要重写,不要解释。

```

你根据它的自检结果决定改不改。如果发现某条偏好它反复违反,说明这条写得不够可执行——回到步骤 2 改风格卡,别指望靠重复强调解决。

回写指的是把这次对话里新出现的稳定偏好存下来。做法是:会话结束时问自己一句"这次我纠正了它什么?"如果是会重复出现的,就手动写成一条记忆;如果只是这一次的特殊要求,不要存。记忆库最大的敌人不是太少,是太多。

常见坑与排错

记忆不生效。 按这个顺序查:总开关是否打开 → 是否新开了会话(老会话不会重新读取)→ 这条记忆是否和自定义指令冲突 → 它是否被检索逻辑选中了(打印一下 pick() 的结果)。四步能覆盖绝大多数情况。

记忆污染。 典型症状是它突然开始用一个你早就不用的说法。原因是半年的一条旧记忆和新的冲突,检索时两条都被选了。解决办法:每条记忆带 updated 字段,同 tags 命中时新版本优先;定期跑一次 list_memories() 做人工清理。

延迟没降反升。 检查注入字符数。max_chars 从 600 调到 300 试试,通常立刻见效。另外确认没有把整份风格卡和历史对话一起塞进去。

输出格式漂移。 比如开始用"首先/其次"。这几乎总是因为记忆注入太多、稀释了系统指令。削减记忆条目,或者把这条禁令从记忆搬到自定义指令里。

它记住了不该记的东西。 敏感信息、临时的情绪化表述、别人的隐私,都不该进记忆。写入前过一遍脑:这条出现在三个月后的对外文档里,会不会有问题?会就别存。

流式看起来还是卡。 确认客户端没有开缓冲,确认中间没有代理层聚合响应。用 curl 直接打一次对比,能快速定位是模型慢还是链路慢。

下一步建议

1. 建一个小评测集:准备 10 个真实任务和对应的"及格线",每次改配置后跑一遍,别靠感觉调。修改成本这个指标比延迟更值得盯。

2. 做多风格档位:给记忆加 scope 字段,分出 writing / email / report,按任务类型切换注入哪一组。同一个助手,三种人格。

3. 上 diff 式改写:让它在原文基础上只输出改动处,而不是整段重写。这对长文档的体感延迟改善最明显,因为输出量直接降下来了。

4. 加术语表:把部门黑话和对应的大白话存成记忆,让它在写作时自动替换。这是最容易见效、也最容易维护的一类记忆。

5. 考虑共享:如果你要给团队用,把风格卡做成仓库里的一个文件,走 code review。个人偏好放本地,团队规范放共享——两层的边界要划清楚。

最后提醒一句:模型档位、记忆入口、接口字段这些会变,动手前先扫一眼官方页面,比照着一篇半年前的教程猜要省事得多。

AI 生成本文由 AI 基于公开信息自动生成,仅供参考。