++
This commit is contained in:
@@ -378,14 +378,15 @@ class CitizenGenerator:
|
||||
)
|
||||
user_text += f"\n\nTARGET SEGMENTS (distribute citizens across these):\n{seg_text}"
|
||||
|
||||
response = await self.llm.generate(
|
||||
system=system_prompt,
|
||||
user=user_text,
|
||||
json_mode=True,
|
||||
max_tokens=4000,
|
||||
)
|
||||
|
||||
data = parse_json(response)
|
||||
response = await self.llm.generate(
|
||||
system=system_prompt,
|
||||
user=user_text,
|
||||
json_mode=True,
|
||||
max_tokens=4000,
|
||||
purpose="cast_generate",
|
||||
)
|
||||
|
||||
data = parse_json(response, purpose="居民名单生成")
|
||||
if isinstance(data, dict) and "citizens" in data:
|
||||
cast = data["citizens"]
|
||||
elif isinstance(data, list):
|
||||
@@ -400,25 +401,26 @@ class CitizenGenerator:
|
||||
and cast
|
||||
and not any(self._has_cjk(str(c.get("name", ""))) for c in cast)
|
||||
):
|
||||
logger.warning("Cast generation returned non-CJK names despite zh locale, retrying. Names: %s", [c.get('name') for c in cast])
|
||||
logger.warning("中文模式下居民姓名仍非中文,将重试。当前姓名:%s", [c.get('name') for c in cast])
|
||||
retry_user = user_text + (
|
||||
"\n\n[STRICT REMINDER] All names, roles, personality hooks, and "
|
||||
"stances MUST be written in Chinese characters. Do NOT use English."
|
||||
)
|
||||
response = await self.llm.generate(
|
||||
system=system_prompt,
|
||||
user=retry_user,
|
||||
json_mode=True,
|
||||
max_tokens=3000,
|
||||
)
|
||||
data = parse_json(response)
|
||||
response = await self.llm.generate(
|
||||
system=system_prompt,
|
||||
user=retry_user,
|
||||
json_mode=True,
|
||||
max_tokens=3000,
|
||||
purpose="cast_generate_retry",
|
||||
)
|
||||
data = parse_json(response, purpose="居民名单生成重试")
|
||||
if isinstance(data, dict) and "citizens" in data:
|
||||
cast = data["citizens"]
|
||||
elif isinstance(data, list):
|
||||
cast = data
|
||||
|
||||
if len(cast) < count:
|
||||
logger.warning("Cast generation returned %d/%d citizens, padding", len(cast), count)
|
||||
logger.warning("居民生成仅返回 %d/%d 人,将使用默认居民补齐", len(cast), count)
|
||||
while len(cast) < count:
|
||||
idx = len(cast)
|
||||
if self._locale == "zh":
|
||||
@@ -468,12 +470,31 @@ class CitizenGenerator:
|
||||
)
|
||||
prompts.append((self._directive(PERSONA_SYSTEM_PROMPT), f"{world_ctx}\n\n{citizen_ctx}"))
|
||||
|
||||
responses = await self.llm.generate_batch(prompts, json_mode=True, max_tokens=800)
|
||||
# A full profile contains a backstory, goals, beliefs, and
|
||||
# resources. 800 tokens is too small for Chinese output and can
|
||||
# truncate the JSON before the closing braces, causing avoidable
|
||||
# parse failures.
|
||||
responses = await self.llm.generate_batch(
|
||||
prompts,
|
||||
json_mode=True,
|
||||
max_tokens=1400,
|
||||
purpose="persona_fast",
|
||||
)
|
||||
# Sub-purpose differentiates persona_fast vs persona_enrich so
|
||||
# timing stats aren't mixed together.
|
||||
_persona_purpose = "persona_fast"
|
||||
# Sub-purpose: differentiate "persona_fast" from "persona_enrich"
|
||||
# so timing stats don't get bucketed together with the slow
|
||||
# variants.
|
||||
# (this is the persona_fast path — the enrich path is below)
|
||||
# Sub-purpose: differentiate "persona fast" from "persona enrich" so
|
||||
# timing stats don't get bucketed together with the slow variants.
|
||||
# Callers above set this; default to persona_fast if unset.
|
||||
|
||||
for i, response in enumerate(responses):
|
||||
idx = batch_start + i
|
||||
member = cast[idx]
|
||||
data = parse_json(response)
|
||||
data = parse_json(response, purpose=f"居民画像生成(批次索引={batch_start + i})")
|
||||
|
||||
personality_data = data.get("personality", {})
|
||||
personality = Personality(
|
||||
@@ -536,7 +557,7 @@ class CitizenGenerator:
|
||||
max_tokens=3000,
|
||||
)
|
||||
|
||||
data = parse_json(response)
|
||||
data = parse_json(response, purpose="居民关系生成")
|
||||
if isinstance(data, dict) and "relationships" in data:
|
||||
rel_list = data["relationships"]
|
||||
elif isinstance(data, list):
|
||||
@@ -624,7 +645,7 @@ class CitizenGenerator:
|
||||
|
||||
for i, response in enumerate(responses):
|
||||
agent = batch[i]
|
||||
data = parse_json(response)
|
||||
data = parse_json(response, purpose=f"居民人生经历生成(居民={agent.name},ID={agent.id})")
|
||||
agent.life_state = self._parse_life_history(data, agent)
|
||||
|
||||
def _parse_life_history(self, data: dict, agent: AgentPersona) -> LifeState:
|
||||
|
||||
Reference in New Issue
Block a user